返回文章列表

自動擴充套件服務最佳化與成本管理實踐

本文探討如何最佳化自動擴充套件服務,以提升大資料工作負載的可靠性和效率,並深入分析雲端儲存成本管理的最佳實踐,包含生命週期管理、版本控制以及檔案結構設計等關鍵策略,有效控制成本並提升資料處理效能。

雲端運算 系統設計

在雲端環境下處理大資料工作負載時,自動擴充套件服務的最佳化和成本管理至關重要。本文將探討如何調整自動擴充套件規則和架構,並結合基準測試,以確保作業的成功率並降低成本。同時,我們也將深入研究雲端儲存的成本結構,並提供資料管線設計的最佳實踐,涵蓋生命週期管理、版本控制和檔案結構設計等方面,以協助您有效控制成本並提升資料處理效能。透過這些策略,您可以更有效地利用雲端資源,並在成本和效能之間取得最佳平衡。

自動擴充套件服務最佳化與實踐

在處理大資料工作負載時,自動擴充套件(Autoscaling)服務的最佳化對於確保作業成功率及成本控制至關重要。本文將探討如何透過改善自動擴充套件規則、調整架構設計以及進行基準測試來提升系統的可靠性和效率。

改善自動擴充套件規則與架構設計

首先,針對之前遇到的作業失敗問題,我們對自動擴充套件規則進行了改進,並修改了架構以確保作業在複製階段擁有足夠的資源。具體做法包括:

  • 在叢集組態中新增任務節點(Task Nodes),並修改擴充套件策略以僅調整任務節點的數量,而核心節點(Core Nodes)的數量保持固定。
  • 將擴充套件指標從 HDFS 使用率轉換為根據 YARN 記憶體和容器指標的擴充套件。

這些改變消除了因 HDFS 擴充套件引起的問題,但仍需解決不同作業對磁碟空間需求不同的挑戰。

基準測試與動態叢集組態

為瞭解決磁碟空間需求不一的問題,我們進行了基準測試,繪製了不同資料大小與叢集組態對成功匯入作業的影響圖表。根據這些指標,我們將作業分為高、中、低資料量三類別,並在叢集啟動過程中加入檢查輸入資料大小的步驟。

根據資料量的不同,初始叢集組態會使用相應的核心節點數量,並設定工作節點的最小和最大擴充套件限制。這樣一來,成本得以根據資料工作負載進行最佳化,同時單執行緒複製階段也能因核心節點數量固定在所需容量而成功。

EBS 磁碟區大小設定

由於上述過程會取得資料大小,我們還能據此設定 EBS 磁碟區大小,以確保有足夠的容量執行作業,從而消除對磁碟空間擴充套件的需求。我們根據資料大小、複製因子和資料轉換所需的磁碟空間提出了一個保守的近似值。

最佳化效果

經過這些變更後,自動擴充套件事件僅在資料轉換過程中因需要更多資源處理資料而發生。這種方法消除了長時間執行的自動擴充套件事件,並顯著降低了作業失敗率。此外,根據工作負載的叢集和自動擴充套件組態透過從一開始就保證足夠的 HDFS 容量來提高可靠性。

自動擴充套件服務綜覽

雲端服務提供商(CSPs)提供了多種自動擴充套件功能,其複雜程度各不相同。在某些情況下,大部分組態由使用者自行決定;而在其他情況下,CSP 會為使用者管理大部分組態,只需指定允許的最小和最大容量。

Kubernetes HPA

Kubernetes 的水平 Pod 自動擴充套件(HPA)相對基礎,但具備很大的靈活性。使用者可以使用根據 Pod 利用率的指標或建立自定義指標。HPA 根據所需指標值與當前指標值的比率計算要新增或刪除的副本數量。

程式碼範例:Kubernetes HPA 設定

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: example-hpa
spec:
  selector:
    matchLabels:
      app: example-app
  minReplicas: 1
  maxReplicas: 10
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: example-deployment
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

內容解密:

此 YAML 組態檔案定義了一個 Kubernetes HPA 物件,用於根據 CPU 利用率自動調整 example-app 的副本數量。minReplicasmaxReplicas 分別設定了副本數量的最小值和最大值。scaleTargetRef 指定了要擴充套件的 Deployment 物件,而 metrics 部分則定義了觸發擴充套件的 CPU 利用率指標。

Google Dataproc 自動擴充套件

Google Dataproc 的自動擴充套件功能更針對叢集資料工作負載,使用根據 YARN 的指標來決定新增或刪除的工作節點數量,並允許自定義閾值。

EMR 和 Databricks 自動擴充套件

EMR 的託管自動擴充套件和 Databricks 的叢集自動擴充套件承擔了更多的組態工作,透過識別重要的指標並在後台設定擴充套件閾值。使用者只需指定最小和最大邊界,剩下的由自動化處理。

Snowflake 多叢集倉函式庫

Snowflake 的多叢集倉函式庫支援具有預定擴充套件組態的自動擴充套件,使用者可從中選擇。

AWS 預測性擴充套件

AWS 的預測性擴充套件嘗試根據過去的作業預測資源需求。透過預先分配預期的資源需求,可以避免因動態叢集指標而延遲自動擴充套件。預測性擴充套件最適合具有重複操作和穩定工作負載的Pipeline。

自動擴充套件服務比較

圖表翻譯: 此圖表比較了不同的自動擴充套件服務。它們各有特點,例如 Kubernetes HPA 提供基礎但靈活的自動擴充套件,而 Google Dataproc 則針對資料工作負載進行最佳化。EMR 和 Databricks 提供託管自動擴充套件服務,簡化了使用者的組態工作。Snowflake 的多叢集倉函式庫提供了預定的擴充套件組態,易於使用。最後,AWS 的預測性擴充套件透過預測資源需求來最佳化資源分配,特別適合具有穩定工作負載的應用場景。

資料處理管線中的可變性與擴充套件性最佳化

在現代雲端運算環境中,資料處理管線(Data Pipelines)的可變性是實作成本最佳化和效能提升的關鍵。所謂的可變性是指資料處理需求和工作負載隨時間的變化,這種變化為利用雲端的彈性擴充套件提供了機會。

瞭解資料處理管線的可變性來源

要充分利用雲端的彈性擴充套件優勢,首先需要深入瞭解資料處理管線的可變性來源。以下幾個問題有助於識別這些來源:

  1. 資料處理管線的操作如何隨時間變化?
  2. 資料工作負載如何變化?
  3. 資料工作負載或操作的變化如何影響資源需求?
  4. 如何得知資源需求正在變化?

可變性的好處與擴充套件策略

具備可變性的資料處理管線能夠在工作負載較低時減少成本,同時在需求增加時擴充套件以滿足需求。這種彈性可以在多個層面實作:

  1. 系統層級:對於具有周期性操作的管線,可以利用排程自動擴充套件,在已知的工作負載低谷期減少成本。
  2. 資料處理層級:根據工作負載的變化調整資源分配,例如使用 Spark 的動態資源分配功能。
  3. 資料處理作業內部:在資料處理的不同階段根據需要調整資源使用。

有效擴充套件的關鍵因素

要實作有效的擴充套件,需要識別有意義的指標來判斷是否需要增加或減少資源。對不同工作負載進行基準測試,有助於確定這些指標的起始點,以及做出擴充套件決策所需的閾值和觀察視窗。

設計可擴充套件的資料處理管線

設計能夠利用分散式資料處理的管線對於水平擴充套件至關重要。仔細的程式碼設計、資料分割槽以及對洗牌(Shuffle)操作的意識,將有助於充分利用這一策略。

程式碼範例:Spark 中的動態資源分配

// 使用 Spark 的動態資源分配功能
val spark = SparkSession.builder()
  .appName("DynamicResourceAllocation")
  .config("spark.dynamicAllocation.enabled", "true")
  .config("spark.dynamicAllocation.initialExecutors", "1")
  .config("spark.dynamicAllocation.minExecutors", "1")
  .config("spark.dynamicAllocation.maxExecutors", "10")
  .getOrCreate()

內容解密:

上述程式碼啟用了 Spark 的動態資源分配功能。這意味著 Spark 將根據工作負載的需要自動調整 Executor 的數量。初始 Executor 數量設為 1,最少保持 1 個 Executor,最大不超過 10 個 Executor。這種組態允許在工作負載增加時動態擴充套件資源,而在工作負載減少時縮減資源,從而最佳化成本和效能。

雲端儲存的最佳實踐

偏好使用雲端儲存可以提高管線的可擴充套件性並降低成本。由於 HDFS 的解除委任(decommissioning)時間較長,且資料函式庫將儲存和計算耦合在一起,因此不建議擴充套件 HDFS。將儲存和計算分離,可以利用雲端儲存更快的頻寬並消除與資料函式庫相關的計算成本。

自動調整資源分配的挑戰

自動調整資源分配需要謹慎的平衡。在開發擴充套件計劃時,需要留出足夠的時間讓擴充套件事件完成、讓工作負載在變更後的資源環境中重新平衡,並讓指標更新,以確保下一次擴充套件決策是根據前一次擴充套件事件的影響。

常見問題與建議

常見的問題包括設定閾值過高或過於接近,以及冷卻(cooldown)和觀察視窗持續時間不足。為了避免效能和可靠性下降,建議:

  1. 設定足夠低的擴充套件閾值,以便在達到關鍵效能或可靠性限制之前有時間新增資源並完成負載重新平衡。
  2. 在擴充套件事件之間提供足夠的時間,以便資源重新平衡。
  3. 設定足夠寬的觀察視窗,以避免過早的擴充套件事件。

雲端儲存成本管理:資料管線的最佳實踐

在雲端運算的時代,資料儲存和管理是企業的重要課題。雲端儲存的成本不僅取決於資料的儲存量,還與資料傳輸和操作頻率息息相關。本篇文章將探討雲端儲存的成本結構,並提供資料管線設計的最佳實踐,以降低成本並提高效能。

雲端儲存成本的三個主要來源

  1. 資料儲存量:儲存的資料量越大,成本越高。
  2. 資料傳輸(Egress):將資料從雲端儲存傳輸到其他區域或外部環境的費用。
  3. 操作次數:對雲端儲存物件的操作(如讀取、寫入、刪除)都會產生費用。

靜態資料儲存的成本考量

在資料管線中,雲端儲存扮演著多重角色,包括:

  • 儲存原始資料和處理後的資料
  • 存放中間資料
  • 長期儲存歷史資料
  • 用於開發和測試的資料
  • 記錄管線操作的日誌

程式碼範例:使用雲端儲存客戶端函式庫

from google.cloud import storage

# 初始化客戶端
client = storage.Client()

# 建立新的儲存桶
bucket = client.create_bucket("my_data_bucket")

# 上傳檔案到儲存桶
def upload_blob(bucket_name, source_file_name, destination_blob_name):
    """上傳檔案到指定的儲存桶"""
    bucket = client.bucket(bucket_name)
    blob = bucket.blob(destination_blob_name)
    blob.upload_from_filename(source_file_name)
    print(f"檔案 {source_file_name} 已上傳到 {destination_blob_name}")

# 使用範例
upload_blob("my_data_bucket", "local_data.csv", "remote_data.csv")

內容解密:

  1. 這段程式碼初始化了一個Google Cloud Storage客戶端。
  2. create_bucket 方法用於建立新的儲存桶。
  3. upload_blob 函式負責將本地檔案上傳到指定的儲存桶。
  4. 上傳檔案時,需要指定來源檔案路徑和目標 Blob 名稱。
  5. 上傳成功後,會列印確認訊息。

資料傳輸(Egress)成本的影響

將資料從雲端儲存傳輸到其他區域或外部環境會產生額外的費用。例如,將10 TB的資料從一個AWS區域傳輸到另一個區域,根據AWS S3的定價,可能會花費相當於四個月儲存費用的金額。因此,盡量在同一個區域內處理資料,以減少傳輸成本。

資料傳輸流程

圖表翻譯: 此圖示展示了資料從原始狀態到最終分析結果的流程。首先,原始資料被上傳到雲端儲存,接著透過傳輸到其他區域或外部環境進行處理,最終產生分析結果。

資料存取成本的管理

每次與雲端儲存物件互動(例如讀取、寫入、刪除)都會產生費用。頻繁的操作會增加成本,尤其是在處理大量小檔案時。

最佳實踐:

  1. 合併小檔案:將多個小檔案合併成較大的檔案,以減少操作次數。
  2. 壓縮資料:使用壓縮技術減少資料量,從而降低儲存和傳輸成本。

程式碼範例:合併小檔案

import os
import pandas as pd

# 定義資料夾路徑
folder_path = "path/to/small/files"

# 合併小檔案
def merge_small_files(folder_path, output_file):
    """合併指定資料夾中的所有CSV檔案"""
    files = [f for f in os.listdir(folder_path) if f.endswith('.csv')]
    dfs = [pd.read_csv(os.path.join(folder_path, f)) for f in files]
    combined_df = pd.concat(dfs, ignore_index=True)
    combined_df.to_csv(output_file, index=False)
    print(f"已合併 {len(files)} 個檔案到 {output_file}")

# 使用範例
merge_small_files(folder_path, "combined_data.csv")

內容解密:

  1. 這段程式碼用於合併指定資料夾中的所有CSV檔案。
  2. merge_small_files 函式列出所有CSV檔案,並使用Pandas讀取它們。
  3. 將所有DataFrame合併成一個,並儲存到新的CSV檔案中。
  4. 合併後會列印處理結果。

雲端儲存組織與成本最佳化

在前面的章節中,我們討論了小檔案問題對雲端儲存成本的影響。現在,我們將探討如何透過有效的雲端儲存組織來降低成本並提升資料管理效率。

為何需要雲端儲存組織

正如 Marie Kondo 在《怦然心動的人生整理魔法》一書中所說,整理和組織是一個需要策略的過程。對於雲端儲存來說,這一點同樣重要。理想情況下,我們應該從一開始就考慮如何組織雲端儲存。當然,我們也可以對現有的雲端儲存進行改造,只是過程可能會更加複雜。

雲端儲存桶策略

組織雲端儲存的第一步是定義儲存桶(bucket)。一種常見的方法是根據功能和環境建立儲存桶。例如,假設我們需要儲存三種型別的資料:日誌、原始資料和處理後的資料,並且我們有兩個環境:測試和生產。那麼,我們最終會得到六個不同的儲存桶:logs-testlogs-prodraw-data-testraw-data-prodprocessed-data-testprocessed-data-prod

使用標籤和標記進行資源管理

在建立儲存桶時,考慮新增標籤(tags)和標記(labels)以幫助追蹤資源和成本,就像我們在第一章中對計算資源所做的那樣。需要注意的是,某些雲端服務提供商可能會對這些服務收取額外費用,例如 Google Cloud Storage 的儲存桶標籤。

標籤和標記的粒度與我們可以對報告和許可權進行分層的程度相關。如果我們想檢視原始資料的成本,可以為每個原始資料儲存桶新增一個標籤。如果我們想按環境檢視原始資料成本,則需要為每個儲存桶新增另一個表示環境的標籤。在較大的組織中,按部門檢視成本是可取的,這可以是另一個標籤。

版本控制:資料保護與還原

另一個需要考慮的重要功能是版本控制(versioning)。啟用版本控制後,每次寫入儲存位置時,都會建立一個新的物件。一個指標會跟蹤最新版本,因此從資料使用者的角度來看,舊版本的物件似乎已被替換。

版本控制可以在事情出錯時真正挽救局面。例如,如果我們正在處理根據時間戳儲存的時間序列資料,例如按字首 YYYY-MM-DD 儲存,那麼在作業重新執行或回填的情況下,將使用相同的字首儲存新資料。

版本控制的實際應用

在之前的工作中,我們使用版本控制建立了一個失敗資料攝取的還原機制。如果最新的攝取建立了錯誤的資料,我們的團隊可以快速回復到最後一個已知的好狀態,因為版本控制使我們能夠存取先前的資料。Azure Blob Storage 檔案中有對物件版本控制和回復機制的詳細描述。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 自動擴充套件服務最佳化與成本管理實踐

package "Git 版本控制" {
    package "工作區域" {
        component [工作目錄
Working Directory] as work
        component [暫存區
Staging Area] as stage
        component [本地倉庫
Local Repository] as local
        component [遠端倉庫
Remote Repository] as remote
    }

    package "基本操作" {
        component [git add] as add
        component [git commit] as commit
        component [git push] as push
        component [git pull] as pull
    }

    package "分支管理" {
        component [git branch] as branch
        component [git merge] as merge
        component [git rebase] as rebase
    }
}

work --> add : 加入暫存
add --> stage : 暫存變更
stage --> commit : 提交變更
commit --> local : 版本記錄
local --> push : 推送遠端
remote --> pull : 拉取更新
branch --> merge : 合併分支

note right of stage
  git status 查看狀態
  git diff 比較差異
end note

@enduml

圖表翻譯: 此圖示展示了啟用版本控制後,寫入新物件和回復到先前版本的流程。

版本控制的成本考量

版本控制是一個強大的工具,但它可能會帶來成本。根據 FinOps 基金會的例子,一家公司在開發人員意識到陳舊的物件版本未被刪除後,將其儲存成本降低了 60%。

管理版本控制成本

為了避免不必要的成本,我們需要定期清理陳舊的物件版本。這可以透過設定生命週期策略來實作,自動刪除舊版本或將其轉移到更便宜的儲存類別中。

雲端儲存組織與生命週期管理

在雲端儲存的資料管理中,生命週期管理(Lifecycle Management)扮演著至關重要的角色。透過在儲存桶(Bucket)或字首(Prefix)層級應用生命週期組態(Lifecycle Configurations),可以有效控制物件的過期、儲存類別轉換等屬性,從而最佳化儲存成本並提升資料管理的效率。

生命週期組態

生命週期組態能夠自動刪除物件或將其轉移到成本較低的儲存類別,幫助控制成本。以不同功能和環境的資料儲存桶為例,可以根據需求應用不同的生命週期策略。下表展示了一個可能的生命週期組態和版本控制策略,用於這些儲存桶。

表:範例儲存桶的版本控制與過期生命週期

| 儲存桶名稱 | 版本控制 | 過期時間 | |





|



|



| | logs-test | 否 | 7天 | | logs-prod | 否 | 30天 | | raw-data-test | 否 | 7天 | | raw-data-prod | 否 | 30天 | | processed-data-test | 否 | 7天 | | processed-data-prod | 是 | 365天 |

從表中可以看出,僅 processed-data-prod 啟用了版本控制。這是因為該儲存桶中的資料可能需要保留多個版本,以便進行除錯和分析。測試環境中的儲存桶由於不需要長期保留資料,因此未啟用版本控制。

生命週期組態的效益

  • 成本文省:透過設定合理的過期時間,可以自動刪除不再需要的資料,從而降低儲存成本。
  • 資料管理:根據資料的重要性和使用頻率,將其轉移到合適的儲存類別,既能滿足效能需求,又能最佳化成本。

儲存類別與生命週期轉換

儲存類別(Storage Class)是另一項可以透過生命週期策略進行管理的屬性。不同的儲存類別提供了不同的效能和成本組合,例如高效能的「熱儲存」(Hot Storage)適合頻繁存取的資料,而「冷儲存」(Cold Storage)則適合長期備份或歸檔資料。

表:從熱儲存到過期的生命週期組態範例

| 資料年齡(天) | 儲存類別 | |




-|



| | 0 | 熱儲存 | | 90 | 暖儲存 | | 180 | 冷儲存 | | 365 | 過期 |

在這個範例中,processed-data-prod 中的資料最初儲存在高效能的熱儲存中,隨著時間的推移,分別轉移到暖儲存和冷儲存,最終在一年後過期被刪除。這種策略可以在保證資料可用的同時,有效降低長期儲存的成本。

清理失敗的多部分上傳

另一個重要的生命週期策略是清理失敗的多部分上傳(Multipart Upload)。當上傳大檔案時,如果上傳過程中斷,相關的部分上傳資料可能會殘留在雲端儲存中,佔用空間並增加成本。自動清理這些失敗的上傳可以保持儲存空間的整潔,避免不必要的費用。

檔案結構設計

除了生命週期管理外,檔案結構設計對於最佳化資料儲存和檢索效率同樣重要。合理的檔案格式選擇和分割槽策略可以顯著提升資料處理的效能和成本效益。

檔案格式

欄位式檔案格式(如 Parquet 和 ORC)相比傳統的平面檔案格式(如 JSON 或 CSV),在儲存和計算成本上具有明顯優勢。它們提供了更好的壓縮率,並且支援欄位修剪(Column Pruning),減少了資料處理的開銷。

分割槽策略

分割槽(Partitioning)是將資料按照某個共同屬性進行分組的技術,可以有效提高查詢效能。透過將資料分割槽,可以快速篩選出相關資料,避免掃描整個資料集,從而降低計算資源的消耗。