最佳化讀取效能 - AWS 規範指南

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

最佳化讀取效能

本節討論您可以調整以最佳化讀取效能的表格屬性,而不受引擎影響。

分割

與 Hive 表一樣,Iceberg 使用分區作為索引的主要層,以避免讀取不必要的元數據文件和數據文件。資料行統計資料也會被視為索引的次要層,以進一步改善查詢規劃,進而提高整體執行時間。

分割您的資料

若要減少查詢 Iceberg 資料表時掃描的資料量,請選擇符合預期讀取模式的平衡分割區策略:

  • 識別查詢中經常使用的資料行。這些都是理想的分區候選人。例如,如果您通常查詢特定日期的資料,則分區資料行的自然範例就是日期資料行。

  • 請選擇低基數分割區資料欄,以避免建立過多的分割區。分割區過多可能會增加資料表中的檔案數量,這可能會對查詢效能產生負面影響。根據經驗法則,可以將「太多分區」定義為大多數分區中的數據大小小於設置值的 2-5 倍的情況target-file-size-bytes

注意

如果您通常在高基數資料行上使用篩選器 (例如,可以有數千個值的id資料欄) 進行查詢,請使用 Iceberg 的隱藏分割功能搭配儲存貯體轉換,如下一節所述。

使用隱藏的分區

如果您的查詢通常會篩選資料表資料行的衍生項目,請使用隱藏的分割區,而不是明確建立新的資料行來當做資料分割使用。如需有關此功能的詳細資訊,請參閱 Iceberg 文件

例如,在具有時間戳記資料行的資料集中 (例如,2023-01-01 09:00:00),而不是使用剖析日期建立新資料欄 (例如,2023-01-01),而是使用 partition transform 從時間戳記擷取日期部分,然後即時建立這些分區。

隱藏分區的最常見用例是:

  • 當數據具有時間戳列時,按日期或時間進行分區。Iceberg 提供了多個轉換來提取時間戳的日期或時間部分。

  • 分割資料行具有高基數且會產生太多分割區時,在資料行的雜湊函數上進行分割。Iceberg 的儲存貯體轉換會使用分割資料行上的雜湊函數,將多個分割區值組合在一起,成為較少的隱藏 (儲存貯體) 分割區。

有關所有可用分區轉換的概述,請參閱 Iceberg 文檔中的分區轉換。

用於隱藏分割的資料行可以透過使用一般 SQL 函數 (例如year()month()),成為查詢述詞的一部分。謂詞也可以與運算符(如BETWEENAND)結合使用。

注意

Iceberg 無法針對產生不同資料類型的函數執行分割區修剪,substring(event_time, 1, 10) = '2022-01-01'例如。

使用分割區演進

當現有的分區策略不是最佳化時,請使用 Iceberg 的分區演進。例如,如果您選擇的每小時分割區太小 (每個分割區只有幾 MB),請考慮轉換為每日或每月分割區。

當資料表的最佳分割區策略最初不清楚時,您可以使用這個方法,而且您想要在獲得更多深入見解時調整您的磁碟分割策略。分割區演進的另一個有效用途是資料磁碟區發生變化,而且目前的分割策略隨著時間的推移而變得較不

如需有關如何進化分割區的指示,請參閱冰山文件中的 ALTER TABLE SQL 延伸模組。 

調整檔案大小

最佳化查詢效能需要將資料表中的小型檔案數量降到最低。為了獲得良好的查詢性能,我們通常建議將實木複合地板和 ORC 文件保持在 100 MB 以上。

檔案大小也會影響冰山資料表的查詢規劃。隨著表格中的檔案數量增加,中繼資料檔案的大小也會增加。較大的中繼資料檔案會導致較慢的查詢規劃。因此,當資料表大小增加時請增加檔案大小以減輕中繼資料的指數擴充。

使用以下最佳實踐在 Iceberg 表中創建適當大小的文件。

設定目標檔案和資料列群組大小

Iceberg 提供了以下關鍵配置參數,用於調整數據文件佈局。建議您使用這些參數來設定目標檔案大小以及資料列群組或刪除大小。

Parameter (參數)

預設值

註解

write.target-file-size-bytes

512 MB

此參數指定 Iceberg 將建立的最大檔案大小。但是,某些文件的寫入大小可能小於此限制。

write.parquet.row-group-size-bytes

128 MB

Parquet 和 ORC 都以塊形式存儲數據,以便引擎可以避免讀取整個文件進行某些操作。

write.orc.stripe-size-bytes

64 MB

write.distribution-mode

無,對於冰山版本 1.1 及更低版本

哈希,從冰山 1.2 版開始

Iceberg 請求 Spark 在寫入存儲之前對其任務之間的數據進行排序。

  • 根據您預期的資料表大小,請遵循下列一般準則:

    • 小型表格 (最多幾 GB) — 將目標檔案大小縮減為 128 MB。同時將資料列群組或資料分割大小 (例如,減少到 8 或 16 MB)。

    • 中型到大型表格 (從幾 GB 到數百 GB) — 預設值是這些表格的良好起點。如果您的查詢非常有選擇性,請調整資料列群組或資料條大小 (例如,調整為 16 MB)。

    • 非常大的資料表 (數百 GB 或 TB) — 將目標檔案大小增加到 1024 MB 以上,如果查詢通常會提取大量資料集,請考慮增加資料列群組或資料帶大小。

  • 若要確保寫入 Iceberg 資料表的 Spark 應用程式會建立適當大小的檔案,請將write.distribution-mode內容設定為hashrange。有關這些模式之間差異的詳細說明,請參閱 Iceberg 文檔中的編寫分發模式

這些是一般指引。我們建議您執行測試,以找出最適合您特定資料表和工作負載的值。

運行定期壓實

上表中的配置設置了寫入任務可以創建的最大文件大小,但不保證文件具有該大小。為了確保正確的檔案大小,請定期執行壓縮,將小型檔案合併成較大的檔案。有關運行壓實的詳細指導,請參閱本指南後面的冰山壓實

優化列統計

Iceberg 使用資料行統計資料來執行檔案修剪,藉由減少查詢掃描的資料量來改善查詢效能。若要受益於資料行統計資料,請確定 Iceberg 收集查詢篩選器中常用之所有資料行的統計資料。

根據預設,Iceberg 僅針對每個資料表中的前 100 個資料行收集統計資料,如 table 屬性write.metadata.metrics.max-inferred-column-defaults所定義。如果您的資料表有超過 100 個資料行,而您的查詢經常參考前 100 個資料行以外的資料行 (例如,您可能有篩選資料行 132) 的查詢,請確定 Iceberg 收集這些資料行的統計資料。有兩個選項可以實現這一目標:

  • 建立 Iceberg 資料表時,請重新排序欄,讓查詢所需的欄落在設定的欄範圍內 write.metadata.metrics.max-inferred-column-defaults (預設值為 100)。

    注意:如果您不需要 100 個資料欄的統計資料,您可以將write.metadata.metrics.max-inferred-column-defaults設定調整為想要的值 (例如 20),然後重新排序資料欄,讓您需要讀取和寫入查詢的資料欄落在資料集左側的前 20 個資料欄內。

  • 如果您在查詢篩選中只使用幾個資料欄,您可以停用測量結果收集的整體特性,並選擇性地選擇要收集統計資料的個別資料欄,如下列範例所示:

    .tableProperty("write.metadata.metrics.default", "none") .tableProperty("write.metadata.metrics.column.my_col_a", "full") .tableProperty("write.metadata.metrics.column.my_col_b", "full")

注意:在這些資料欄上排序資料時,資料欄統計資料最有效。如需詳細資訊,請參閱本指南稍後的 < 設定排序順序 > 一節。

選擇正確的更新策略

當您的使用案例可接受較慢的寫入作業時,請使用 copy-on-write 策略來最佳化讀取效能。這是冰山使用的默認策略。

C opy-on-write 導致更好的讀取效能,因為檔案會以讀取最佳化的方式直接寫入儲存空間。但是,與之相比 merge-on-read,每個寫入作業需要更長的時間,而且耗用更多的運算資源 這提出了讀取和寫入延遲之間的經典折衷。通常,對 copy-on-write 於大多數更新都在同一個表分區中並置(例如,每日批次載入)中的使用案例非常理想。

C opy-on-write 配置(write.update.modewrite.delete.mode、和write.merge.mode)可以在表格層級設置,也可以在應用程序端獨立設置。

使用 ZSTD 壓縮

您可以使用 table 屬性write.<file_type>.compression-codec修改冰山使用的壓縮編解碼器。我們建議您使用 ZSTD 壓縮轉碼器來改善表格的整體效能。

默認情況下,冰山 1.3 及更早版本使用 GZIP 壓縮,與 ZSTD 相比,它提供了較慢的讀/寫性能。

附註:某些引擎可能會使用不同的預設值。這是與 Athena 或 Amazon EMR 版本 7.x 創建的冰山表的情況。

設定排序順序

若要改善 Iceberg 資料表的讀取效能,建議您根據查詢篩選器中常用的一或多個資料行來排序資料表。排序與 Iceberg 的列統計信息相結合,可以使文件修剪更有效率,從而導致更快的讀取操作。對於在查詢篩選器中使用排序欄的查詢,排序也可減少 Amazon S3 請求的數量。

您可以使用 Spark 執行資料定義語言 (DDL) 陳述式,在資料表層級設定階層排序順序。有關可用選項,請參閱 I ceberg 文檔。設定排序順序後,編寫者會將此排序套用至 Iceberg 資料表中的後續資料寫入作業。

例如,在以 date (yyyy-mm-dd) 分區的資料表中,大部分查詢會篩選依據uuid,您可以使用 DDL 選項Write Distributed By Partition Locally Ordered來確定 Spark 會寫入具有非重疊範圍的檔案。

下圖說明排序表格時,資料行統計資料的效率如何提升。在示例中,排序表只需打開一個文件,並且從 Iceberg 的分區和文件中獲益最大。在未排序的表中,任何uuid可能存在於任何數據文件中,因此查詢必須打開所有數據文件。

在冰山表中設置排序順序

變更排序順序不會影響現有的資料檔案。您可以使用冰山壓實在那些應用排序順序。

使用 Iceberg 排序表格可能會降低工作負載的成本,如下圖所示。

冰山和鑲木地板桌比較成本

這些圖表總結了運行 Hive(鑲木地板)表的 TPC-H 基準結果與冰山排序表格進行比較。不過,其他資料集或工作負載的結果可能會有所不同。

實木複合地板與冰山桌的 TPC-H 基準結果