

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

# S3DistCp (s3-dist-cp)
<a name="UsingEMR_s3distcp"></a>

Apache DistCp 是一款開源工具，可用來複製大量資料。*S3DistCp* 與 DistCp 類似，但經優化可與 AWS(尤其是 Amazon S3) 搭配使用。Amazon EMR 4.0 版及更新版本內的 S3DistCp 命令為 `s3-dist-cp`，您可以在叢集或命令列中將其新增為步驟之一。透過 S3DistCp，即可有效地將大量 Amazon S3 資料複製到 HDFS，並交由 Amazon EMR 叢集處理後續步驟。您也能利用 S3DistCp 在多個 Amazon S3 儲存貯體間複製資料，或將資料從 HDFS 複製到 Amazon S3。S3DistCp 更具可擴展性和效率。 AWS 

如需在真實世界案例中示範 S3DistCP 彈性的特定命令，請參閱 AWS 大數據部落格上的[使用 S3DistCp 的七個秘訣](https://aws.amazon.com/blogs/big-data/seven-tips-for-using-s3distcp-on-amazon-emr-to-move-data-efficiently-between-hdfs-and-amazon-s3/)。

如同 DistCp，S3DistCp 會使用 MapReduce 以分散式的方式進行複製。它會跨多個伺服器分享複本、處理錯誤、進行復原，以及回報任務。如需有關 Apache DistCp 開放原始碼專案的詳細資訊，請參閱 Apache Hadoop 文件中的 [DistCp 指南](http://hadoop.apache.org/docs/stable/hadoop-distcp/DistCp.html)。

若 S3DistCp 無法複製部分或全部的指定檔案，叢集步驟會失敗，並傳回非零的錯誤代碼。若發生此種狀況，S3DistCp 不會清除掉部分複製的檔案。

**重要**  
S3DistCp 不支援含有底線字元的 Amazon S3 儲存貯體名稱。  
S3DistCp 不支援 Parquet 檔案的連接。改用 PySpark。如需詳細資訊，請參閱 [在 Amazon EMR 中串連 parquet 檔案](https://aws.amazon.com/premiumsupport/knowledge-center/emr-concatenate-parquet-files/)。  
為了避免使用 S3DistCP 將單一檔案 (而非目錄) 從 S3 複製到 HDFS 時出現複製錯誤，請使用 Amazon EMR 5.33.0 版或更新版本，或者 Amazon EMR 6.3.0 版或更高版本。

## S3DistCp 選項
<a name="UsingEMR_s3distcp.options"></a>

雖然與 DistCp 類似，但 S3DistCp 支援一組不同的選項來變更其複製和壓縮資料的方式。

呼叫 S3DistCp 時，您可以指定下表所述的選項。這些選項會透過引數清單加入步驟中。下表會列出 S3DistCp 引數的範例。


| 選項  | Description  | 必要  | 
| --- | --- | --- | 
| ‑‑src=LOCATION  |  複製資料的位置。可能為 HDFS 或 Amazon S3 的位置。 範例：`‑‑src=s3://amzn-s3-demo-bucket/logs/j-3GYXXXXXX9IOJ/node`  S3DistCp 不支援含有底線字元的 Amazon S3 儲存貯體名稱。   | 是  | 
| ‑‑dest=LOCATION  |  資料的目的地。可能為 HDFS 或 Amazon S3 的位置。 範例：`‑‑dest=hdfs:///output`  S3DistCp 不支援含有底線字元的 Amazon S3 儲存貯體名稱。   | 是  | 
| ‑‑srcPattern=PATTERN  |  [規則運算式](http://en.wikipedia.org/wiki/Regular_expression)，能夠篩選以 `‑‑src` 資料子集為目標的複製操作。若並未指定 `‑‑srcPattern` 或 `‑‑groupBy`，`‑‑src` 的所有資料均會複製到 `‑‑dest`。 若規則表達式引數含有星號 (\$1) 等特殊字元，則需將規則表達式或整個 `‑‑args` 字串以單引號 (') 括起來。 範例：`‑‑srcPattern=.*daemons.*-hadoop-.*`  | 否  | 
| ‑‑groupBy=PATTERN  |  [規則運算式](http://en.wikipedia.org/wiki/Regular_expression)，S3DistCp 能藉此串連符合該運算式的檔案。舉例而言，您可以使用此選項將所有在一小時內寫入的記錄檔結合成單個檔案。串連的檔案名稱是與分組用的規則表達式相符的該值。 括號代表檔案的分組方式，所有與括號中的陳述相符的項目均會結合成同一個輸出檔案。若規則表達式並無括號內的陳述式，則叢集會在 S3DistCp 步驟失敗，並傳回錯誤。 若規則表達式引數含有星號 (\$1) 等特殊字元，則需將規則表達式或整個 `‑‑args` 字串以單引號 (') 括起來。 指定 `‑‑groupBy` 時，僅會複製符合指定模式的檔案。不需要同時指定 `‑‑groupBy` 和 `‑‑srcPattern`。 範例：`‑‑groupBy=.*subnetid.*([0-9]+-[0-9]+-[0-9]+-[0-9]+).*`  | 否  | 
| ‑‑targetSize=SIZE  |  根據 `‑‑groupBy` 選項建立檔案大小，單位為 mebibytes (MiB)。該值必須為整數。若有設定 `‑‑targetSize`，S3DistCp 會常識符合該大小，而實際複製檔案的大小可能會大於或小於該值。根據資料檔案大小彙總的作業，因此目標檔案大小可能會與來源資料檔案大小相符。 若由 `‑‑groupBy` 串連的檔案大於 `‑‑targetSize` 的值，會將檔案分解為多個分割檔，並按順序在名稱結尾加上數字編號。舉例而言，串連為 `myfile.gz` 的檔案會分割為：`myfile0.gz`、`myfile1.gz` 等。 範例：`‑‑targetSize=2`  | 否  | 
| ‑‑appendToLastFile |  在將檔案從 Amazon S3 複製到已存在的 HDFS 時，指定 S3DistCp 的行為。會將新的檔案資料附加到既有檔案中。如果使用 `‑‑appendToLastFile` 搭配 `‑‑groupBy`，新資料會附加到符合相同群組的檔案上。搭配 `‑‑targetSize` 使用時，此操作也會遵守 `‑‑groupBy.` 的行為  | 否  | 
| ‑‑outputCodec=CODEC  |  指定要用複製檔案的壓縮代碼。可能會使用到這些值：`gzip`、`gz`、`lzo`、`snappy` 或 `none`。舉例而言，您可以使用此選項將輸入檔案透過 Gzip 轉換為 LZO 壓縮格式的輸出檔，或在複製操作的過程終將檔案解壓縮。若選擇了輸出代碼，檔案名稱會附加上合適的副檔名 (例如 `gz` 和 `gzip` 的副檔名為 `.gz`)。若不指定 `‑‑outputCodec` 的值，將檔案複製過去時就不會變更壓縮方式。 範例：`‑‑outputCodec=lzo`  | 否  | 
| ‑‑s3ServerSideEncryption  |  確保使用 SSL 傳輸目標資料，並使用 AWS 服務端金鑰在 Amazon S3 中自動加密。當使用 S3DistCp 擷取資料時，物件會自動處於未加密的狀態。如果嘗試將未加密的物件複製到需要加密的 Amazon S3 儲存貯體，複製操作會失敗。如需詳細資訊，請參閱[使用資料加密](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingEncryption.html)。 範例：`‑‑s3ServerSideEncryption`  | 否  | 
| ‑‑deleteOnSuccess  |  如果複製操作成功，此選項會導致 S3DistCp 將複製檔案從來源位置刪除。若是要將記錄檔這類輸出檔案當做排程任務處理，從一個位置複製到另個位置，且您不想重複複製相同的檔案，此功能便相當實用。 範例：`‑‑deleteOnSuccess`  | 否  | 
| ‑‑disableMultipartUpload  |  停用分段上傳。 範例：`‑‑disableMultipartUpload`  | 否  | 
| ‑‑multipartUploadChunkSize=SIZE  |  Amazon S3 分段上傳中每個部分的大小 (MiB)。S3DistCp 在複製大於 `multipartUploadChunkSize` 的資料時使用分段上傳。若要提高作業效能，您可以增加每個部分的大小。預設大小為 128 MiB。 範例：`‑‑multipartUploadChunkSize=1000`  | 否  | 
| ‑‑numberFiles  |  會在輸出檔案的開頭加上順序編號。數字會從 0 開始，除非由 `‑‑startingIndex` 指定不同的值。 範例：`‑‑numberFiles`  | 否  | 
| ‑‑startingIndex=INDEX  |  搭配 `‑‑numberFiles` 使用，以指令序列中的第一個編號。 範例：`‑‑startingIndex=1`  | 否  | 
| ‑‑outputManifest=FILENAME  |  建立一個以 Gzip 壓縮的文字檔，內有 S3DistCp 複製的所有檔案的清單。 範例：`‑‑outputManifest=manifest-1.gz`  | 否  | 
| ‑‑previousManifest=PATH  |  讀取先前使用 `‑‑outputManifest` 旗標呼叫 S3DistCp 時建立的資訊清單檔案。設定 `‑‑previousManifest` 旗標後，S3DistCp 會將列於資訊清單內的檔案從複製操作中排除出去。若與 `‑‑outputManifest` 一起指定 `‑‑previousManifest`，列在之前的資料清單中的檔案也匯出現在新的資訊清單檔案中，但不會複製檔案。 範例：`‑‑previousManifest=/usr/bin/manifest-1.gz`  | 否  | 
| ‑‑requirePreviousManifest |  需要先前呼叫 S3DistCp 期間所建立的資訊清單。若設定為 false，未指定先前的資訊清單，也不會產生任何錯誤。預設值為 true。  | 否  | 
| ‑‑copyFromManifest  |  將 `‑‑previousManifest` 的行為反轉，讓 S3DistCp 使用指定的資訊清單檔案做為複製檔案的清單，而非當做不予複製的檔案清單。 範例：`‑‑copyFromManifest ‑‑previousManifest=/usr/bin/manifest-1.gz`  | 否  | 
| ‑‑s3Endpoint=ENDPOINT |  指定上傳檔案時要使用的 Amazon S3 端點。此選項會設定來源和目的地兩邊的端點。若未設定，預設端點則為 `s3.amazonaws.com`。如需 Amazon S3 端點的清單，請參閱[區域與端點](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region)。 範例：`‑‑s3Endpoint=s3.eu-west-1.amazonaws.com`  | 否  | 
| ‑‑storageClass=CLASS |  目的地是 Amazon S3 時所用的儲存類別。有效值為 STANDARD 和 REDUCED\$1REDUNDANCY。如果未指定此選項，S3DistCp 會嘗試保留儲存類別。 範例：`‑‑storageClass=STANDARD`  | 否  | 
| ‑‑srcPrefixesFile=PATH |  Amazon S3 (s3://)、HDFS (hdfs:///) 或本機檔案系統 (file:/) 中的文字檔，其中包含一系列 `src` 字首，每行一個字首。 若有提供 `srcPrefixesFile`，S3DistCp 不會列出 src 路徑。反之會產生一份來源清單做為合併的結果，其中列出此檔案中指定的所有字首。會使用相對於 src 路徑的相對路徑來產生目的地路徑，而非這些字首。若也有指定 `srcPattern`，會將之套用到來源字首的合併清單結果，以進一步篩選輸入結果。若有使用 `copyFromManifest`，則會複製資訊清單中的物件，並略過 `srcPrefixesFile`。 範例：`‑‑srcPrefixesFile=PATH`  | 否  | 

除了上述選項之外，S3DistCp 也採用了 [Tool interface](https://hadoop.apache.org/docs/current/api/org/apache/hadoop/util/Tool.html)，表示其可支援通用選項。

## 將 S3DistCp 新增為叢集中的步驟
<a name="UsingEMR_s3distcp.step"></a>

您可以將 S3DistCp 新增為叢集中的步驟，便能呼叫 S3DistCp。可在啟動時將步驟新增至叢集，或使用主控台、CLI 或 API 將步驟加入至執行中的叢集。以下範例示範了如何將 S3DistCp 步驟新增至執行中的叢集。如需有關將步驟新增至叢集的詳細資訊，請參閱《Amazon EMR 管理指南》**中的[將工作提交至叢集](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-work-with-steps.html)。

**使用 將 S3DistCp 步驟新增至執行中的叢集 AWS CLI**

如需在 中使用 Amazon EMR 命令的詳細資訊 AWS CLI，請參閱 [AWS CLI 命令參考](https://docs.aws.amazon.com/cli/latest/reference/emr)。
+ 若要將呼叫 S3DistCp 的步驟新增至叢集，請將指定 S3DistCp 如何將複製操作當做引數執行的參數傳遞過去。

  下列範例會將常駐程式日誌從 Amazon S3 複製到 `hdfs:///output`。在下列命令中：
  + `‑‑cluster-id` 指定了叢集
  + `Jar` 是 S3DistCp JAR 檔案的位置。如需有關如何使用 command-runner.jar 在叢集上執行命令的範例，請參閱[提交自訂 JAR 步驟以執行指令碼或命令](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-commandrunner.html#emr-commandrunner-examples)。
  + `Args` 是要傳遞到 S3DistCp 的選項名稱值組的逗號分隔清單。如需可用選項的完整清單，請參閱 [S3DistCp 選項](#UsingEMR_s3distcp.options)。

  若要將 S3DistCp 複製步驟新增到執行中的叢集，請將以下內容放置在儲存於 Amazon S3 中的 JSON 檔案或您的本機檔案系統中，在此範例為 `myStep.json`。將 *j-3GYXXXXXX9IOK* 取代為您的叢集 ID，並將 *amzn-s3-demo-bucket* 取代為您的 Amazon S3 儲存貯體名稱。

  ```
  [
      {
          "Name":"S3DistCp step",
          "Args":["s3-dist-cp","‑‑s3Endpoint=s3.amazonaws.com","‑‑src=s3://amzn-s3-demo-bucket/logs/j-3GYXXXXXX9IOJ/node/","‑‑dest=hdfs:///output","‑‑srcPattern=.*[a-zA-Z,]+"],
          "ActionOnFailure":"CONTINUE",
          "Type":"CUSTOM_JAR",
          "Jar":"command-runner.jar"        
      }
  ]
  ```

  ```
  aws emr add-steps ‑‑cluster-id j-3GYXXXXXX9IOK ‑‑steps file://./myStep.json
  ```

**Example 將日誌檔案從 Amazon S3 複製到 HDFS**  
此範例也會說明如何透過將步驟新增至執行中的叢集，來將儲存在 Amazon S3 儲存貯體內的日誌檔案複製到 HDFS。在此範例中，`‑‑srcPattern` 選項適用於限制複製到精靈記錄檔的資料。  
若要使用 `‑‑srcPattern` 選項將日誌檔案從 Amazon S3 複製到 HDFS，請將以下內容放置在儲存於 Amazon S3 中的 JSON 檔案或您的本機檔案系統中，在此範例為 `myStep.json`。將 *j-3GYXXXXXX9IOK* 取代為您的叢集 ID，並將 *amzn-s3-demo-bucket* 取代為您的 Amazon S3 儲存貯體名稱。  

```
[
    {
        "Name":"S3DistCp step",
        "Args":["s3-dist-cp","‑‑s3Endpoint=s3.amazonaws.com","‑‑src=s3://amzn-s3-demo-bucket/logs/j-3GYXXXXXX9IOJ/node/","‑‑dest=hdfs:///output","‑‑srcPattern=.*daemons.*-hadoop-.*"],
        "ActionOnFailure":"CONTINUE",
        "Type":"CUSTOM_JAR",
        "Jar":"command-runner.jar"        
    }
]
```