

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

# Amazon EMR 上的 Trino 最佳實務
<a name="emr-trino-advanced"></a>

Trino 的架構專為跨多個資料來源的大型資料集上的快速分散式 SQL 查詢而設計，遵循協調器工作者模型，其中每個元件在查詢執行中都具有特殊角色。您可以專注於幾個領域或類別，以便為執行 Trino 的 Amazon EMR 叢集設定其最佳效能。這些索引標籤包括以下項目：
+ 調整叢集組態設定以進行記憶體最佳化。
+ 最佳化資料分割和資料分佈的設定。
+ 使用動態篩選來減少查詢結果計數。

當您搭配 Amazon EMR 使用 Trino 時，其中一些設定會自動調校。其他可以透過主控台或 CLI 命令手動設定。本節中的主題可協助您以最佳方式設定資料和叢集。

**Topics**
+ [提升效能的關鍵重點領域](emr-trino-performance-areas.md)
+ [收集和使用資料表統計資料](emr-trino-performance-areas-collect-stats.md)
+ [擴展 Trino 工作負載時的常見挑戰](emr-trino-common-issues.md)

# 提升效能的關鍵重點領域
<a name="emr-trino-performance-areas"></a>

Trino 可將查詢平行處理和記憶體最佳化最大化。此架構可讓您查詢多個不同資料來源，同時有效率地擴展，藉此提供彈性。Trino 中效能改善的關鍵領域包括下列各項。

## 記憶體最佳化
<a name="emr-trino-performance-areas-optimization"></a>

Trino 中的記憶體管理對於實現高效能和穩定性至關重要，尤其是當您執行大型、複雜的查詢時。Trino 使用分散式記憶體模型。在此模型中，記憶體會配置到工作者節點，以處理任務、彙總、聯結和其他操作。下列清單介紹這些設定的集合：
+ **query.max-memory** – 設定整個叢集中單一查詢可用的記憶體上限。這是硬性限制；如果查詢超過此記憶體，則會失敗。
+ **query.max-memory-per-node** – 定義查詢在每個工作者節點上可以使用的最大記憶體。設定此設定可確保任何工作者上的單一查詢不會獨佔資源。
+ **JVM 堆積大小** – 在 JVM 層級設定，它會為每個節點上的 Trino 伺服器程序設定堆積大小上限。此值通常應該大於 Trino 中的記憶體相關組態 （這是 **query.max-memory-per-node** 和 **memory.heap-headroom-per-node** 的總和），以避免系統在 JVM 層級的記憶體不足。
+ **memory.heap-headroom-per-node** – 指定緩衝記憶體數量，讓非查詢操作的 JVM 堆積大小不多。這對於確保內部操作和垃圾收集有足夠的額外負荷至關重要。

## 動態篩選
<a name="emr-trino-performance-areas-dynamic"></a>

Trino 中的動態篩選是一種最佳化技術，可透過減少處理的資料量來改善查詢效能，尤其是在聯結期間。它會動態套用篩選條件，根據在另一側看到的資料來限制聯結的一側掃描的資料，這在聯結的一側具有高度選擇性 （表示其中包含一小部分的資料） 的查詢中特別有用。預設會在 Amazon EMR 上啟用。以下是範例查詢：

```
SELECT orders.order_id, orders.total_amount
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id
WHERE customers.country = 'France';
```

如果沒有動態篩選，Trino 會在聯結中掃描整個訂單資料表，即使只有一小部分的客戶 （來自法國的客戶） 是相關的。此方法會讀取**訂單**資料表中的所有資料列，進而產生高 I/O 和處理成本。透過動態篩選，Trino 一開始會掃描較小的**客戶**資料表、擷取僅來自法國客戶的 customer\$1id 值，然後套用此子集做為訂單的篩選條件。這表示只會掃描**訂單**中與篩選子集相符的 customer\$1id 相關的資料列，大幅減少處理的記錄。

## 溢出到磁碟
<a name="emr-trino-performance-areas-spill"></a>

 在 Trino 中，磁碟溢出可讓中繼查詢結果卸載至磁碟，讓記憶體密集型查詢能夠完成，即使超過 `query_max_memory`或 設定的記憶體限制`query_max_memory_per_node`。根據預設，Trino 會強制執行這些限制，以確保公平的記憶體配置，並防止叢集死結。不過，當大型查詢超過這些限制時，就會有終止的風險。磁碟溢出會透過使用 來解決此問題`revocable memory`，允許查詢借用可在其他位置需要資源時撤銷的額外記憶體。撤銷記憶體時，中繼資料會溢出到磁碟，讓查詢能夠繼續處理，而不會超過記憶體限制。請注意，被強制溢出到磁碟的查詢可能會有較長的執行時間，因此預設為停用。若要在 Amazon EMR 上啟用溢出，請使用下列組態：
+ `spill-enabled=true` – 當記憶體用量超過可用閾值時，啟用磁碟溢出。
+ `spill-paths` – 定義存放溢出資料的目錄，`spill-paths=/mnt/spill`。

# 收集和使用資料表統計資料
<a name="emr-trino-performance-areas-collect-stats"></a>

 收集資料表統計資料可讓 Trino 的成本型最佳化工具對聯結訂單、篩選下推和分割區剔除做出明智的決策，進而獲得更好的效能。

您可以使用 `ANALYZE`命令來收集 Hive 或 Iceberg 資料表的統計資料：

```
ANALYZE sales;
```

收集寬資料表的統計資料可能會對資源課稅。我們建議指定用於聯結、篩選條件或分組操作的欄子集。

這是另一個有用的命令。它會顯示資料表的目前統計資料，以驗證統計資料是否為最新狀態。

```
show stats for table_name;
```

# 擴展 Trino 工作負載時的常見挑戰
<a name="emr-trino-common-issues"></a>

搭配 Trino 使用 Amazon S3 的主要優點是 S3 能夠擴展大型資料磁碟區和 S3 的成本效益。但是，當您查詢大型資料磁碟區時，可能會發生一系列相關的效能問題。這些原因可能是資料的儲存方式、限制良好效能的組態設定，或其他原因。當這些問題發生時，您可以採取有效步驟來避免或緩解這些問題。

本節從您可以實作的一般最佳化清單開始，以提高大型資料磁碟區的查詢效能。接下來，會詳細說明常見問題，並針對每個問題提供緩解措施。

本主題來自下列會議簡報：[大規模加速效能：搭配 Amazon S3 的 Trino 最佳實務](https://www.youtube.com/watch?v=cjUUcHlUKxQ)。

## 最佳化大型資料集的資料配置
<a name="emr-trino-common-issues-practices"></a>

當您查詢大型資料集時，效能瓶頸並不常發生。但是，您可以實作一些最佳實務，以便在使用 Trino 查詢 Amazon S3 中的資料時開始著手。這些索引標籤包括以下項目：
+ **分割** – 根據相關屬性，分割表示在階層中組織資料，並將相關資料一起存放。分割可讓查詢不必掃描太多不相關的資料，進而獲得更佳的查詢效能。您可以使用各種分割策略，例如使用字首排列來源資料，特別是依日期範圍區域或其他屬性。如需在 Amazon S3 中分割資料以提高效能的詳細資訊，請參閱部落格文章 [開始管理 Glue Data Catalog 支援的 Amazon S3 AWS 資料表分割區](https://aws.amazon.com/blogs/big-data/get-started-managing-partitions-for-amazon-s3-tables-backed-by-the-aws-glue-data-catalog/)，或文章[的前 10 個效能調校秘訣 Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)。
+ **儲存貯體** – 儲存貯體會將相關資料分組在常見檔案中。例如，如果您根據地理區域查詢資料，例如狀態，您可以透過將特定狀態的所有資料分組在相同的檔案或檔案群組中，來提高查詢效能。為了獲得最佳效果，請將儲存貯體以高基數的資料屬性為基礎，例如狀態或省。此外，您可以將查詢模式納入考量。如果您的查詢通常從這些狀態一起讀取資料，則此範例可能意味著將加州和奧勒岡州的資料分組在一起。
+ **管理 S3 字首** – 您可以使用 Amazon S3 字首來實作分割策略。如果您只對 Amazon S3 儲存貯體使用單一字首，例如特定日期，這可能會導致大量請求，並可能導致 HTTP 503 錯誤。我們建議您使用字首來新增其他條件，並更有效地組織您的來源資料。如需詳細資訊，請參閱《Amazon S3 文件》中的[使用字首組織物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-prefixes.html)。下列簡短範例顯示的字首可提供更好的請求輸送量：`s3://bucket/country=US/dt=2024-06-13`。在此範例中，國家/地區和日期都包含在字首中，這會導致比字首僅包含日期的案例讀取更少。

  緩解 HTTP 503 錯誤在本主題後面的 *HTTP 慢速*區段中進行了更詳細的討論。
+ **最佳化資料大小** – 您可以執行 OPTIMIZE 命令，以設定有利於執行更佳查詢的組態。若要針對 Hive 外部資料表執行它，請依照下列步驟執行：
  + 使用 `OPTIMIZE`搭配下列參數：`hive.non-managed-table-writes-enabled=true`。如需此屬性的詳細資訊，請參閱 [Hive 一般組態屬性](https://trino.io/docs/current/connector/hive.html#hive-general-configuration-properties)。
  + 設定下列工作階段參數： `SET SESSION` `catalog.non_transactional_optimize_enabled=true`
  + 執行 `OPTIMIZE`命令：`ALTER TABLE catalog.schema.table EXECUTE optimize(file_size_threshold => '128MB')`。在此情況下， 預設為 `file_size_threshold` 100MB。如範例所示，提高此閾值會導致合併低於 128MB 的檔案。
+ **設定重試** – 您可以設定下列項目，以增加重試限制，進而降低 HTTP 503 錯誤的機率：`s3.max-error-retries`。這適用於使用 TrinoFileSystem API 和 Trino 449 版本或更新版本時。另一方面，如果您使用 Amazon EMR 搭配 Trino，您可以使用 EMRFS 存取 Amazon S3。使用 EMRFS，您可以透過變更 `fs.s3.maxRetries` 參數來增加淘汰次數。
+ **選擇 Amazon S3 儲存類別** – 根據特定資料收集的需求，為生命週期中不同時間點的資料選擇適當的儲存類別，有助於同時提升效能和成本。如需詳細資訊，請參閱 [Amazon S3 文件中的了解和管理 Amazon S3 儲存類別](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.htm)。 Amazon S3 
+ **遷移至 Iceberg** – 緩解效能問題的另一個解決方案是遷移至 Iceberg 資料表，特別是在小型檔案上執行查詢。Iceberg 具有可妥善處理小型檔案的功能。
+ **使用自動資料壓縮** – 如果您使用 Iceberg 資料表，搭配 Glue Data Catalog AWS 的自動資料壓縮可以最佳化資料大小，並產生更好的查詢效能。

## 查詢大型資料集時的常見挑戰
<a name="emr-trino-common-issues-challenges"></a>

本節列出當您在 Amazon S3 中累積大型資料集並使用 Trino 查詢時可能發生的常見問題集。每個區段都會向您展示解決問題或降低其對查詢影響的方法。以下各節所述的每個問題都已使用 Hive 連接器進行重現和測試。

### 大型資料掃描
<a name="emr-trino-common-issues-large-scan"></a>

當您的查詢必須掃描大型資料集時，可能會導致查詢效能緩慢和儲存成本提高等問題。大型資料磁碟區可能是因為資料快速成長或規劃，不會導致在適當的時間範圍內移動舊版資料。這可能會導致查詢速度變慢。

若要降低掃描大型資料集的效能命中，建議您使用分割和儲存貯體：
+ 根據群組的屬性，將相關資料分割在一起。有效使用分割可以大幅改善查詢效能。
+ 儲存貯體是指根據特定、相關的資料欄，將檔案或儲存貯體中的資料分組。儲存貯體通常表示實際將相關的來源資料檔案保留在一起。

為了說明緩解措施如何適用於大型資料掃描，假設您存放和查詢具有狀態屬性記錄的資料，這些記錄可以指派給加州或阿拉斯加，而此狀態屬性是您的其中一個查詢條件。您可以將每個狀態的資料儲存在個別的 S3 儲存貯體中，或使用 S3 字首根據狀態分割資料，以改善查詢效能。如果您以其他資料欄為基礎，例如日期屬性，則此分割和儲存貯體也會導致效能改善。

**注意**  
如果資料欄具有高基數，而且您想要使用它來將資料分組，在這種情況下，建議您使用儲存貯體。另一方面，通常，分割區索引鍵應具有較低的基數。

**使用各種 S3 儲存類型**

一般而言，您可以根據工作負載的效能、資料存取、彈性和成本需求來選擇儲存類型。成本和效能之間可能會有權衡。請務必選擇符合您資料存取模式的適當 Amazon S3 儲存類別。主要存取模式有兩種：
+ 以已知或可預測的方式存取的資料。一般而言，如果您有不常存取的資料，S3 標準 IA 可能是不錯的選擇，因為它有助於降低成本。如果您經常存取資料，S3 Standard 最適合使用 Amazon EMR 和 Trino 進行存取。
+ 以未知或無法預測的方式存取的資料。這可以呼叫 以使用其他 Amazon S3 儲存類別，S3 儲存類別之間存在權衡。這些包括延遲、儲存成本和可用性。您可以根據您的工作負載和存取模式，選擇適當的 S3 儲存類型。如需每個類別優點的說明，請參閱 [Amazon S3 Storage Classs]()。

**使用壓縮**

您也可以使用 Iceberg 自動壓縮，如果您使用 Iceberg 資料表，這會產生更理想的檔案大小，以提高查詢效率。如需詳細資訊，請參閱 [AWS Glue Data Catalog 現在支援自動壓縮 Apache Iceberg 資料表](https://aws.amazon.com/blogs/aws/aws-glue-data-catalog-now-supports-automatic-compaction-of-apache-iceberg-tables/)。

### HTTP 減速錯誤
<a name="emr-trino-common-issues-slow-network"></a>

當請求率超過 Amazon S3 字首上預先設定的閾值時，就會發生這種情況。達到此狀態時最常發生的 HTTP 錯誤如下：**錯誤 503：請降低請求率**。此問題的來源可以根源於大量小型檔案，因為必須建立*的分割*數量才能讀取資料。有兩種方法可以緩解問題：
+ 提高 Trino 中 Amazon S3 請求的重試限制。這是針對在 Trino 449 `fs.s3.maxretries`中使用 的 EMRFS 設定。
+ 最佳化檔案大小，這也會導致較低的請求率。

如需有關 Trino 如何決定要查詢之資料集中分割數量的詳細資訊，請參閱 Hive 連接器文件中[的效能調校組態屬性](https://trino.io/docs/current/connector/hive.html#performance-tuning-configuration-properties)。

### 難以查詢小型檔案
<a name="emr-trino-common-issues-small-files"></a>

由於大量的 GET 和 LIST 請求，查詢許多小型檔案可能會導致大量的 I/O 額外負荷，並隨後對查詢效能造成負面影響。最佳化檔案大小可以改善查詢效能。有幾種方法可以執行此操作：
+ 將資料合併為較少較大的檔案。（通常，我們建議將檔案大小保持在 128 MB 左右。) 您可以在擷取資料時使用工具執行此操作，例如在 ETL 管道中，也可以手動合併資料。如果您無法使用這些解決方案，剩餘的選項可能更適合您。
+ 執行 `OPTIMIZE` 命令。
+ 設定 `SESSION` 參數。

請注意，Iceberg 具有一項功能，可將小型檔案合併為自動壓縮的較大檔案。它適用於使用 Glue Data Catalog AWS 管理的檔案。如需詳細資訊，請參閱 [AWS Glue Data Catalog 現在支援自動壓縮 Apache Iceberg 資料表](https://aws.amazon.com/blogs/aws/aws-glue-data-catalog-now-supports-automatic-compaction-of-apache-iceberg-tables/)。

### 包含不需要之資料的查詢
<a name="emr-trino-common-issues-uneeded-data"></a>

資料成長很常見，這使得追蹤資料存取模式以及隨著資料老化或變得不相關而適當移動資料變得至關重要。這是因為隨著資料增長，查詢效能可能會隨著時間降低，主要是因為查詢執行時要掃描的資料量龐大。Amazon S3 和其他 服務提供資料生命週期遷移的指引，顯示資料在變冷時移動到不同儲存位置的策略。這樣做也具有儲存成本優勢。

除了資料遷移之外，您還可以使用其他策略，例如移除與您執行的查詢無關的來源資料。這可能需要一些工作，因為這可能意味著變更您的來源資料結構描述。但其正面結果是減少資料量並加快查詢速度。如需詳細資訊，請參閱[管理物件的生命週期](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)。