

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

# 提升 Hive 效能
<a name="emr-hive-s3-performance"></a>

Amazon EMR 提供的功能，可在使用 Hive 查詢、讀取和寫入儲存在 Amazon S3 中的資料時協助優化效能。

S3 Select 可藉由將處理「下推」至 Amazon S3 改善某些應用程式中 CSV 和 JSON 檔案的查詢效能。

EMRFS S3 優化的遞交程式是 [OutputCommitter](https://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/OutputCommitter.html) 類別的替代方案，它消除了清單和重新命名操作，可提高使用 EMRFS 寫入 Amazon S3 檔案時的效能。

**Topics**
+ [啟用 Hive EMRFS S3 優化的遞交程式](hive-optimized-committer.md)
+ [將 S3 Select 與 Hive 搭配使用以提升效能](emr-hive-s3select.md)
+ [MSCC 優化](emr-msck-optimization.md)

# 啟用 Hive EMRFS S3 優化的遞交程式
<a name="hive-optimized-committer"></a>

Hive EMRFS S3 優化的遞交程式是使用 EMRFS 時 EMR Hive 為插入查詢寫入檔案的替代方法。遞交程式消除了在 Amazon S3 上執行的清單和重新命名操作，並提高了應用程式的效能。從 EMR 5.34 和 EMR 6.5 開始，此功能可用。

## 啟用遞交程式
<a name="enabling-hive-committer"></a>

如果您希望讓 EMR Hive 使用 `HiveEMRFSOptimizedCommitter` 作為所有 Hive 受管和外部資料表的預設值遞交資料，則請在 EMR 6.5.0 或 EMR 5.34.0 叢集中使用下列 `hive-site` 組態。

```
[
   {
      "classification": "hive-site",
      "properties": {
         "hive.blobstore.use.output-committer": "true"
      }
   }
]
```

**注意**  
在 `hive.exec.parallel` 設定為 `true` 時，請勿開啟此功能。

## 限制
<a name="hive-committer-limitations"></a>

以下基本限制適用於 標籤：
+ 不支援 Hive 自動合併小型檔案。即使啟用了優化的遞交程式，也會使用預設 Hive 遞交邏輯。
+ 不支援 Hive ACID 資料表。即使啟用了優化的遞交程式，也會使用預設 Hive 遞交邏輯。
+ 寫入檔案的檔案命名術語從 Hive 的 `<task_id>_<attempt_id>_<copy_n>` 變更為 `<task_id>_<attempt_id>_<copy_n>_<query_id>`。例如，名為 

  `s3://warehouse/table/partition=1/000000_0` 的檔案將變更為 `s3://warehouse/table/partition=1/000000_0-hadoop_20210714130459_ba7c23ec-5695-4947-9d98-8a40ef759222-1`。此處 `query_id` 是使用者名稱、時間戳記和 UUID 的組合。
+ 自訂分割區在不同的檔案系統 (HDFS、S3) 上時，將自動停用此功能。啟用後將使用預設 Hive 遞交邏輯。

# 將 S3 Select 與 Hive 搭配使用以提升效能
<a name="emr-hive-s3select"></a>

**重要**  
Amazon S3 Select 不再提供給新客戶。Amazon S3 Select 的現有客戶可以繼續照常使用此功能。[進一步了解](https://aws.amazon.com/blogs/storage/how-to-optimize-querying-your-data-in-amazon-s3/) 

在 Amazon EMR 發行版本 5.18.0 及更新版本中，您可以將 [S3 Select](https://aws.amazon.com/blogs/aws/s3-glacier-select/) 與 Amazon EMR 上的 Hive 搭配使用。S3 Select 可讓應用程式從物件只擷取資料子集。針對 Amazon EMR，篩選大型資料集以進行處理的運算工作，會從叢集「下推」到 Amazon S3 處理，因而在某些應用程式中可提升效能，並減少 Amazon EMR 和 Amazon S3 之間傳輸的資料量。

以 CSV 和 JSON 檔案為基礎的 Hive 資料表，以及在 Hive 工作階段將 `s3select.filter` 組態變數設定為 `true`，可支援 S3 Select。如需詳細資訊和範例，請參閱 [在您的程式碼中指定 S3 Select](#emr-hive-s3select-specify)。

## S3 Select 是否適合我的應用程式？
<a name="emr-hive-s3select-apps"></a>

建議您在使用和不使用 S3 Select 的狀態下，對應用程式進行基準分析，以確認其是否適合您的應用程式。

利用下列的準則，來判斷您的應用程式是否可能使用 S3 Select：
+ 您的查詢會篩選掉原始資料集一半以上的資料。
+ 您的查詢篩選條件述詞所使用的資料欄，具有 Amazon S3 Select 所支援的資料類型。如需詳細資訊，請參閱《Amazon Simple Storage Service 使用者指南》**中的[資料類型](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-data-types.html)。
+ Amazon S3 與 Amazon EMR 叢集之間的網路連線具有良好的傳輸速度和可用頻寬。Amazon S3 不會壓縮 HTTP 回應，因此所壓縮輸入檔案的回應大小可能會增加。

## 考量和限制
<a name="emr-hive-s3select-considerations"></a>
+ 不支援使用客戶所提供加密金鑰 (SSE-C) 的 Amazon S3 伺服器端加密，也不支援用戶端加密。
+ 不支援 `AllowQuotedRecordDelimiters` 屬性。如果指定此屬性，查詢會失敗。
+ 僅支援採用 UTF-8 格式的 CSV 和 JSON 檔案。不支援多行 CSV 和 JSON。
+ 僅支援未壓縮的檔案，或 gzip 或 bzip2 檔案。
+ 不支援在最後一行的註解字元。
+ 不會處理檔案尾端的空白行。
+ Amazon EMR 上的 Hive 支援 S3 Select 所支援的基本資料類型。如需詳細資訊，請參閱《Amazon Simple Storage Service 使用者指南》**中的[資料類型](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-data-types.html)。

## 在您的程式碼中指定 S3 Select
<a name="emr-hive-s3select-specify"></a>

若要在 Hive 資料表中使用 S3 Select，請將 `com.amazonaws.emr.s3select.hive.S3SelectableTextInputFormat` 指定為 `INPUTFORMAT` 類別名稱，並使用 `TBLPROPERTIES` 子句，來指定 `s3select.format` 屬性的值，以建立資料表。

根據預設，在您執行查詢時會停用 S3 Select。在 Hive 工作階段期間，將 `s3select.filter` 設定為 `true`，以啟用 S3 Select，如下所示。下列的範例，示範如何在使用基礎的 CSV 和 JSON 檔案建立資料表時指定 S3 Select，然後利用簡單的選擇陳述式來查詢資料表。

**Example 適用於 CSV 型資料表的 CREATE TABLE 陳述式**  

```
CREATE TABLE mys3selecttable (
col1 string,
col2 int,
col3 boolean
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS
INPUTFORMAT
  'com.amazonaws.emr.s3select.hive.S3SelectableTextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://path/to/mycsvfile/'
TBLPROPERTIES (
  "s3select.format" = "csv",
  "s3select.headerInfo" = "ignore"
);
```

**Example 適用於 JSON 型資料表的 CREATE TABLE 陳述式**  

```
CREATE TABLE mys3selecttable (
col1 string,
col2 int,
col3 boolean
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS
INPUTFORMAT
  'com.amazonaws.emr.s3select.hive.S3SelectableTextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://path/to/json/'
TBLPROPERTIES (
  "s3select.format" = "json"
);
```

**Example SELECT TABLE 陳述式**  

```
SET s3select.filter=true;
SELECT * FROM mys3selecttable WHERE col2 > 10;
```

# MSCC 優化
<a name="emr-msck-optimization"></a>

Hive 可將每個資料表的分割區清單儲存在中繼存放區中。但是，在直接將分割區新增至檔案系統或從檔案系統中移除分割區時，Hive 中繼存放區無法得知這些變更。[MSCK 命令](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-RecoverPartitions(MSCKREPAIRTABLE))會為直接新增至檔案系統或從檔案系統移除的分割區，更新 Hive 中繼存放區中的分割區中繼資料。命令的語法是：

```
MSCK [REPAIR] TABLE table_name [ADD/DROP/SYNC PARTITIONS];
```

Hive 如下所示實作此命令：

1. Hive 從中繼存放區擷取資料表的所有分割區。然後，從檔案系統中不存在的分割區路徑清單中，建立要從中繼存放區捨棄的分割區清單。

1. Hive 收集檔案系統中存在的分割區路徑，將它們與中繼存放區中的分割區清單進行比較，並產生需要新增至中繼存放區的分割區清單。

1. Hive 使用 `ADD`、`DROP` 或 `SYNC` 模式更新中繼存放區。

**注意**  
當中繼存放區中具有許多分割區時，檢查檔案系統中是否不存在分割區的步驟需要很長時間才能執行，因為必須對每個分割區進行檔案系統的 `exists` API 呼叫。

在 Amazon EMR 6.5.0 中，Hive 引進了一個稱為 `hive.emr.optimize.msck.fs.check` 的旗標。啟用後，此旗標會導致 Hive 檢查上面步驟 2 中產生的檔案系統的分割區路徑清單中是否存在分割區，而不是進行檔案系統 API 呼叫。在 Amazon EMR 6.8.0 中，Hive 預設啟用此優化，無需設定旗標 `hive.emr.optimize.msck.fs.check`。