在 DynamoDB 和 HDFS 之间复制数据
如果 DynamoDB 表有数据,则可以使用 Hive 将数据复制到 Hadoop 分布式文件系统 (HDFS)。
如果运行的 MapReduce 任务需要 DynamoDB 数据,则可以执行此操作。如果将数据从 DynamoDB 复制到 HDFS,Hadoop 可以并行使用 Amazon EMR 集群的所有可用节点进行处理。MapReduce 任务完成后,可以将结果从 HDFS 写入 DDB。
在以下示例中,Hive 将读取和写入以下 HDFS 目录:/user/hadoop/hive-test
本部分中的示例假定已遵循 教程:使用 Amazon DynamoDB 和 Apache Hive 步骤,在 DynamoDB 中有一个名为 ddb_features 的外部表。
使用 Hive 默认格式复制数据
例 从 DynamoDB 到 HDFS
使用 INSERT OVERWRITE
语句直接写入 HDFS。
INSERT OVERWRITE DIRECTORY 'hdfs:///user/hadoop/hive-test' SELECT * FROM ddb_features;
HDFS 的数据文件如下所示:
920709
^A
Soldiers Farewell Hill^A
Summit^A
NM^A
32.3564729^A
-108.33004616135 1178153^A
Jones Run^A
Stream^A
PA^A
41.2120086^A
-79.25920781260 253838^A
Sentinel Dome^A
Summit^A
CA^A
37.7229821^A
-119.584338133 264054^A
Neversweet Gulch^A
Valley^A
CA^A
41.6565269^A
-122.83614322900 115905^A
Chacaloochee Bay^A
Bay^A
AL^A
30.6979676^A
-87.97388530
每个字段由一个 SOH 字符分隔(标题开头,0x01)。在文件中,SOH 显示为 ^A
。
例 从 HDFS 到 DynamoDB
-
创建一个映射到 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';
-
将数据复制到 DynamoDB。
INSERT OVERWRITE TABLE ddb_features SELECT * FROM hdfs_features_unformatted;
使用用户指定的格式复制数据
如果要使用不同字段分隔符,则可以创建映射到 HDFS 目录的外部表。可以使用此技术创建具有逗号分隔值 (CSV) 的数据文件。
例 从 DynamoDB 到 HDFS
-
创建映射到 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';
-
从 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
例 从 HDFS 到 DynamoDB
使用单个 HiveQL 语句,可以用 HDFS 的数据填充 DynamoDB 表:
INSERT OVERWRITE TABLE ddb_features SELECT * FROM hdfs_features_csv;
复制没有列映射的数据
可以采用原始格式从 DynamoDB 复制数据,写入 HDFS,无需指定任何数据类型或列映射。您可以使用此方法创建 DynamoDB 数据存档,存储在 HDFS。
如果 DynamoDB 表包含 Map、List、Boolean 或 Null 类型的属性,则这是使用 Hive 将数据从 DynamoDB 复制到 HDFS 的唯一方法。
例 从 DynamoDB 到 HDFS
-
创建与 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");
-
创建另一个与 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';
-
将数据从 DynamoDB 复制到 HDFS。
INSERT OVERWRITE TABLE hdfs_features_no_mapping SELECT * FROM ddb_features_no_mapping;
HDFS 中的数据文件如下所示:
Name
^C
{"s":"Soldiers Farewell Hill"}^B
State^C
{"s":"NM"}^B
Class^C
{"s":"Summit"}^B
Elevation^C
{"n":"6135"}^B
Latitude^C
{"n":"32.3564729"}^B
Id^C
{"n":"920709"}^B
Longitude^C
{"n":"-108.3300461"} Name^C
{"s":"Jones Run"}^B
State^C
{"s":"PA"}^B
Class^C
{"s":"Stream"}^B
Elevation^C
{"n":"1260"}^B
Latitude^C
{"n":"41.2120086"}^B
Id^C
{"n":"1178153"}^B
Longitude^C
{"n":"-79.2592078"} Name^C
{"s":"Sentinel Dome"}^B
State^C
{"s":"CA"}^B
Class^C
{"s":"Summit"}^B
Elevation^C
{"n":"8133"}^B
Latitude^C
{"n":"37.7229821"}^B
Id^C
{"n":"253838"}^B
Longitude^C
{"n":"-119.58433"} Name^C
{"s":"Neversweet Gulch"}^B
State^C
{"s":"CA"}^B
Class^C
{"s":"Valley"}^B
Elevation^C
{"n":"2900"}^B
Latitude^C
{"n":"41.6565269"}^B
Id^C
{"n":"264054"}^B
Longitude^C
{"n":"-122.8361432"} Name^C
{"s":"Chacaloochee Bay"}^B
State^C
{"s":"AL"}^B
Class^C
{"s":"Bay"}^B
Elevation^C
{"n":"0"}^B
Latitude^C
{"n":"30.6979676"}^B
Id^C
{"n":"115905"}^B
Longitude^C
{"n":"-87.9738853"}
每个字段以 STX 字符(文本开头,0x02)开头,以 ETX 字符(文本末尾,0x03)结尾。在文件中,STX 显示为 ^B
,ETX 显示为 ^C
。
例 从 HDFS 到 DynamoDB
使用单个 HiveQL 语句,可以用 HDFS 的数据填充 DynamoDB 表:
INSERT OVERWRITE TABLE ddb_features_no_mapping SELECT * FROM hdfs_features_no_mapping;
访问 HDFS 的数据
HDFS 是一个分布式文件系统,可供 Amazon EMR 集群的所有节点访问。如果使用 SSH 连接主节点,则可以使用命令行工具访问 Hive 写入 HDFS 的数据。
HDFS 与主节点的本地文件系统不一样。无法使用标准 Linux 命令(例如 cat
、cp
、mv
或 rm
)处理 HDFS 的文件和目录。应使用 hadoop
fs
命令执行此类任务。
以下步骤假设已使用本节介绍的一种方法,将数据从 DynamoDB 复制到 HDFS。
-
如果当前处于 Hive 命令提示符下,请退出到 Linux 命令提示符。
hive> exit;
-
列出 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) 系统生成。
-
查看文件的内容:
hadoop fs -cat /user/hadoop/hive-test/000000_0
注意 在此示例中,文件相对较小(约 29 KB)。对非常大或包含不可打印字符的文件使用此命令时,请小心。
-
(可选)可以将数据文件从 HDFS 复制到主节点的本地文件系统。执行此操作后,可以使用标准 Linux 命令行实用程序处理文件中的数据。
hadoop fs -get /user/hadoop/hive-test/000000_0
此命令不会覆盖文件。
注意 主节点的本地文件系统容量有限。请勿将此命令用于大于本地文件系统可用空间的文件。