

# DynamoDB と HDFS 間のデータをコピー
<a name="EMRforDynamoDB.CopyingData.HDFS"></a>

DynamoDB テーブルにあるデータであれば、Hive を使用して Hadoop Distributed File System (HDFS) にコピーすることができます。

DynamoDB からのデータを必要とする MapReduce ジョブを実行している場合などに、この操作を行います。DynamoDB から HDFS にデータをコピーする際には、Amazon EMR クラスターで使用可能なすべてのノードを並行して使用しながら、Hadoop がそのデータの処理を行います。MapReduce ジョブの完了時、その結果を HDFSからDDBに書き込むことができます。

次の例では、Hive が、ここに示す HDFS ディレクトリ `/user/hadoop/hive-test` に対する読み書きを実行しています。

**注記**  
このセクションの例は、[チュートリアル:Amazon DynamoDB と Apache Hive の使用](EMRforDynamoDB.Tutorial.md) の手順が正確に完了していること、および、ddb\_features という名前の外部テーブルが DynamoDB に存在することを前提に書かれています。

**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 ステートメントにより、DynamoDB テーブルに HDFS からのデータを書き込むことができます。  

```
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 ステートメントにより、DynamoDB テーブルに HDFS からのデータを書き込むことができます。  

```
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
   ```

   このコマンドでは、ファイルの上書きは行われません。
**注記**  
リーダーノードのローカルファイルシステムには、容量に関する制限があります。ローカルファイルシステム内で使用可能な領域より大きいサイズのファイルに対しては、このコマンドを使用しないでください。