在 DynamoDB 和 HDFS 之间复制数据 - Amazon DynamoDB

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 DynamoDB 和 HDFS 之间复制数据

如果 DynamoDB 表有数据,则可以使用 Hive 将数据复制到 Hadoop Distributed File System(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^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

例 从 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';
  2. 将数据复制到 DynamoDB。

    INSERT OVERWRITE TABLE ddb_features SELECT * FROM hdfs_features_unformatted;

使用用户指定格式复制数据

如果要使用不同字段分隔符,则可以创建映射到 HDFS 目录的外部表。可以使用此技术创建具有逗号分隔值 (CSV) 的数据文件。

例 从 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';
  2. 从 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
  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");

  2. 创建另一个与 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';
  3. 将数据从 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

例 从 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 命令(例如 catcpmvrm)处理 HDFS 的文件和目录。应使用 hadoop fs 命令执行此类任务。

以下步骤假设已使用本节介绍的一种方法,将数据从 DynamoDB 复制到 HDFS。

  1. 如果当前处于 Hive 命令提示符下,请退出到 Linux 命令提示符。

    hive> exit;
  2. 列出 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) 系统生成。

  3. 查看文件的内容:

    hadoop fs -cat /user/hadoop/hive-test/000000_0
    注意

    在此示例中,文件相对较小(约 29 KB)。对非常大或包含不可打印字符的文件使用此命令时,请小心。

  4. (可选)可以将数据文件从 HDFS 复制到主节点的本地文件系统。执行此操作后,可以使用标准 Linux 命令行实用程序处理文件中的数据。

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

    此命令不会覆盖文件。

    注意

    主节点的本地文件系统容量有限。请勿将此命令用于大于本地文件系统可用空间的文件。