

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

# 在 DynamoDB 與 HDFS 之間複製資料
<a name="EMRforDynamoDB.CopyingData.HDFS"></a>

如果 DynamoDB 資料表中有資料，則可以使用 Hive 將資料複製到 Hadoop 分散式檔案系統 (HDFS)。

如果正在執行需要來自 DynamoDB 之資料的 MapReduce 任務，您可能會執行這項操作。如果您將資料從 DynamoDB 複製到 HDFS，Hadoop 可以處理此資訊，同時會使用 Amazon EMR 叢集中的所有可用節點。完成 MapReduce 任務後，您就能將結果從 HDFS 寫入至 DDB。

在下列範例中，Hive 將在下列 HDFS 目錄讀取及寫入內容：`/user/hadoop/hive-test`

**注意**  
本節中的範例假設您會遵循 [教學課程：使用 Amazon DynamoDB 和 Apache Hive](EMRforDynamoDB.Tutorial.md) 中的步驟，並且在 DynamoDB 中有一個名為 *ddb\_features* 的外部資料表。

**Topics**
+ [使用 Hive 預設格式複製資料](#EMRforDynamoDB.CopyingData.HDFS.DefaultFormat)
+ [以使用者指定格式複製資料](#EMRforDynamoDB.CopyingData.HDFS.UserSpecifiedFormat)
+ [在無資料欄映射的情況下複製資料](#EMRforDynamoDB.CopyingData.HDFS.NoColumnMapping)
+ [存取 HDFS 中的資料](#EMRforDynamoDB.CopyingData.HDFS.ViewingData)

## 使用 Hive 預設格式複製資料
<a name="EMRforDynamoDB.CopyingData.HDFS.DefaultFormat"></a>

**Example 從 DynamoDB 到 HDFS**  
使用 `INSERT OVERWRITE` 陳述式直接寫入至 HDFS。  

```
INSERT OVERWRITE DIRECTORY 'hdfs:///user/hadoop/hive-test'
SELECT * FROM ddb_features;
```
HDFS 中的資料檔案外觀如下：  

```
920709^ASoldiers Farewell Hill^ASummit^ANM^A32.3564729^A-108.33004616135
1178153^AJones Run^AStream^APA^A41.2120086^A-79.25920781260
253838^ASentinel Dome^ASummit^ACA^A37.7229821^A-119.584338133
264054^ANeversweet Gulch^AValley^ACA^A41.6565269^A-122.83614322900
115905^AChacaloochee Bay^ABay^AAL^A30.6979676^A-87.97388530
```
每個欄位都以 SOH 字元分隔 (標題的開頭，0x01)。在檔案中，SOH 會顯示為 **^A**。

**Example 從 HDFS 到 DynamoDB**  

1. 建立映射至 HDFS 中未格式化資料的外部資料表。

   ```
   CREATE EXTERNAL TABLE hdfs_features_unformatted
       (feature_id       BIGINT,
       feature_name      STRING ,
       feature_class     STRING ,
       state_alpha       STRING,
       prim_lat_dec      DOUBLE ,
       prim_long_dec     DOUBLE ,
       elev_in_ft        BIGINT)
   LOCATION 'hdfs:///user/hadoop/hive-test';
   ```

1. 將資料複製到 DynamoDB。

   ```
   INSERT OVERWRITE TABLE ddb_features
   SELECT * FROM hdfs_features_unformatted;
   ```

## 以使用者指定格式複製資料
<a name="EMRforDynamoDB.CopyingData.HDFS.UserSpecifiedFormat"></a>

如果要使用不同的欄位分隔符號字元，則可以建立映射至 HDFS 目錄的外部資料表。您可以使用此技術建立具有逗號分隔值 (CSV) 的資料檔案。

**Example 從 DynamoDB 到 HDFS**  

1. 建立映射至 HDFS 的 Hive 外部資料表。執行此操作時，請確定資料類型與 DynamoDB 外部資料表的資料類型一致。

   ```
   CREATE EXTERNAL TABLE hdfs_features_csv
       (feature_id       BIGINT,
       feature_name      STRING ,
       feature_class     STRING ,
       state_alpha       STRING,
       prim_lat_dec      DOUBLE ,
       prim_long_dec     DOUBLE ,
       elev_in_ft        BIGINT)
   ROW FORMAT DELIMITED
   FIELDS TERMINATED BY ','
   LOCATION 'hdfs:///user/hadoop/hive-test';
   ```

1. 從 DynamoDB 複製資料。

   ```
   INSERT OVERWRITE TABLE hdfs_features_csv
   SELECT * FROM ddb_features;
   ```
HDFS 中的資料檔案外觀如下：  

```
920709,Soldiers Farewell Hill,Summit,NM,32.3564729,-108.3300461,6135
1178153,Jones Run,Stream,PA,41.2120086,-79.2592078,1260
253838,Sentinel Dome,Summit,CA,37.7229821,-119.58433,8133
264054,Neversweet Gulch,Valley,CA,41.6565269,-122.8361432,2900
115905,Chacaloochee Bay,Bay,AL,30.6979676,-87.9738853,0
```

**Example 從 HDFS 到 DynamoDB**  
使用單一 HiveQL 陳述式，您可以使用來自 HDFS 的資料填入 DynamoDB 資料表：  

```
INSERT OVERWRITE TABLE ddb_features
SELECT * FROM hdfs_features_csv;
```

## 在無資料欄映射的情況下複製資料
<a name="EMRforDynamoDB.CopyingData.HDFS.NoColumnMapping"></a>

您可以使用原始格式從 DynamoDB 複製資料，並將其寫入至 HDFS，而無需指定任何資料類型或資料欄映射。您可以使用此方法建立 DynamoDB 資料的封存，並將其存放到 HDFS 中。



**注意**  
如果 DynamoDB 資料表包含 Map、List、Boolean 或 Null 類型的屬性，這便是您可以使用 Hive 將資料從 DynamoDB 複製到 HDFS 的唯一方法。

**Example 從 DynamoDB 到 HDFS**  

1. 建立與 DynamoDB 資料表相關聯的外部資料表。(此 HiveQL 陳述式中沒有 `dynamodb.column.mapping`。)

   ```
   CREATE EXTERNAL TABLE ddb_features_no_mapping
       (item MAP<STRING, STRING>)
   STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'
   TBLPROPERTIES ("dynamodb.table.name" = "Features");
   ```

   

1. 建立另一個與 HDFS 目錄相關聯的外部資料表。

   ```
   CREATE EXTERNAL TABLE hdfs_features_no_mapping
       (item MAP<STRING, STRING>)
   ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\t'
   LINES TERMINATED BY '\n'
   LOCATION 'hdfs:///user/hadoop/hive-test';
   ```

1. 將資料從 DynamoDB 複製到 HDFS。

   ```
   INSERT OVERWRITE TABLE hdfs_features_no_mapping
   SELECT * FROM ddb_features_no_mapping;
   ```
HDFS 中的資料檔案外觀如下：  

```
Name^C{"s":"Soldiers Farewell Hill"}^BState^C{"s":"NM"}^BClass^C{"s":"Summit"}^BElevation^C{"n":"6135"}^BLatitude^C{"n":"32.3564729"}^BId^C{"n":"920709"}^BLongitude^C{"n":"-108.3300461"}
Name^C{"s":"Jones Run"}^BState^C{"s":"PA"}^BClass^C{"s":"Stream"}^BElevation^C{"n":"1260"}^BLatitude^C{"n":"41.2120086"}^BId^C{"n":"1178153"}^BLongitude^C{"n":"-79.2592078"}
Name^C{"s":"Sentinel Dome"}^BState^C{"s":"CA"}^BClass^C{"s":"Summit"}^BElevation^C{"n":"8133"}^BLatitude^C{"n":"37.7229821"}^BId^C{"n":"253838"}^BLongitude^C{"n":"-119.58433"}
Name^C{"s":"Neversweet Gulch"}^BState^C{"s":"CA"}^BClass^C{"s":"Valley"}^BElevation^C{"n":"2900"}^BLatitude^C{"n":"41.6565269"}^BId^C{"n":"264054"}^BLongitude^C{"n":"-122.8361432"}
Name^C{"s":"Chacaloochee Bay"}^BState^C{"s":"AL"}^BClass^C{"s":"Bay"}^BElevation^C{"n":"0"}^BLatitude^C{"n":"30.6979676"}^BId^C{"n":"115905"}^BLongitude^C{"n":"-87.9738853"}
```
每個欄位都以 STX 字元 (文字的開頭，0x02) 開頭，並以 ETX 字元 (文字結尾，0x03) 結尾。在此檔案中，STX 會顯示為 **^B**，ETX 會顯示為 **^C**。

**Example 從 HDFS 到 DynamoDB**  
使用單一 HiveQL 陳述式，您可以使用來自 HDFS 的資料填入 DynamoDB 資料表：  

```
INSERT OVERWRITE TABLE ddb_features_no_mapping
SELECT * FROM hdfs_features_no_mapping;
```

## 存取 HDFS 中的資料
<a name="EMRforDynamoDB.CopyingData.HDFS.ViewingData"></a>

HDFS 是一個分散式檔案系統，可供 Amazon EMR 叢集中的所有節點存取。如果您使用 SSH 連線到領導節點，則可以使用命令列工具來存取 Hive 寫入至 HDFS 的資料。

HDFS 與領導節點上的本機檔案系統不盡相同。您無法使用標準 Linux 命令 (例如 `cat`、`cp`、`mv` 或 `rm`) 處理 HDFS 中的檔案及目錄。這些任務要使用 `hadoop fs` 命令來執行。

以下步驟的撰寫是假設您已使用本節其中一個程序，將資料從 DynamoDB 複製到 HDFS。

1. 如果您目前處於 Hive 命令提示字元，請離開至 Linux 命令提示字元。

   ```
   hive> exit;
   ```

1. 列出 HDFS 中 /user/hadoop/hive-test 目錄的內容。(這是 Hive 從 DynamoDB 複製資料的位置。)

   ```
   hadoop fs -ls /user/hadoop/hive-test
   ```

   回應外觀會與下列類似：

   ```
   Found 1 items
   -rw-r--r-- 1 hadoop hadoop 29504 2016-06-08 23:40 /user/hadoop/hive-test/000000_0
   ```

   檔案名稱 (*000000\_0*) 是由系統產生的。

1. 檢視檔案的內容：

   ```
   hadoop fs -cat /user/hadoop/hive-test/000000_0
   ```
**注意**  
在此範例中，檔案相對較小 (大約 29 KB)。請審慎對非常大或包含不可列印字元的檔案使用此命令。

1. (選用) 您可以將資料檔案從 HDFS 複製到領導節點上的本機檔案系統。執行此操作之後，您可以使用標準 Linux 命令列公用程式來使用檔案中的資料。

   ```
   hadoop fs -get /user/hadoop/hive-test/000000_0
   ```

   此命令不會覆寫檔案。
**注意**  
領導節點上的本機檔案系統容量有限。請勿將此命令與大於本機檔案系統中可用空間的檔案搭配使用。