设置 Hive 表来运行 Hive 命令 - Amazon EMR
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

设置 Hive 表来运行 Hive 命令

Apache Hive 是一种可用于使用类似 SQL 的语言查询 Amazon EMR 集群中包含的数据的数据仓库应用程序。有关 Hive 的更多信息,请参阅 http://hive.apache.org/

下面的程序假定您已创建集群并指定了 Amazon EC2 密钥对。要了解如何开始创建集群,请参阅《Amazon EMR 管理指南》中的 Amazon EMR 入门

配置 Hive 来使用 MapReduce

在您使用 Amazon EMR 上的 Hive 查询 DynamoDB 表时,如果 Hive 使用默认执行引擎 Tez,则可能会出现错误。因此,在按照本节中所述创建具有与 DynamoDB 集成的 Hive 的集群时,我们建议您使用将 Hive 设置为使用 MapReduce 的配置分类。有关更多信息,请参阅配置应用程序

以下代码段显示用于将 MapReduce 设置为 Hive 执行引擎的配置分类和属性:

[ { "Classification": "hive-site", "Properties": { "hive.execution.engine": "mr" } } ]
以交互方式运行 Hive 命令
  1. 连接到主节点。有关更多信息,请参阅《Amazon EMR 管理指南》中的使用 SSH 连接到主节点

  2. 当命令提示输入当前主节点时,键入 hive

    您应看到 Hive 提示符:hive>

  3. 输入用于将 Hive 应用程序中的表映射到 DynamoDB 中的数据的 Hive 命令。该表充当对 Amazon DynamoDB 中存储的数据的引用;数据未存储在本地的 Hive 中,每次运行命令时,使用此表的任何查询将针对 DynamoDB 中的实时数据运行,从而占用此表的读取或写入容量。如果您需要对同一数据集运行多个 Hive 命令,请考虑先将其导出。

    下面说明将 Hive 表映射到 DynamoDB 表的语法。

    CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename", "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...");

    当您在 Hive 中从 DynamoDB 创建表时,必须使用关键字 EXTERNAL 将该表创建为外部表。外部表与内部表之间的区别是:删除内部表时,将删除内部表中的数据。当连接 Amazon DynamoDB 时,这不是所需行为,因此仅支持外部表。

    例如,以下 Hive 命令在 Hive 中创建名为 hivetable1 的表,该表引用名为 dynamodbtable1 的 DynamoDB 表。DynamoDB 表 dynamodbtable1 具有 hash-and-range 主键架构。哈希键元素是 name (字符串类型)。范围键元素是 year (数字类型)。每个项目都有 holidays (字符串集类型) 的属性值。

    CREATE EXTERNAL TABLE hivetable1 (col1 string, col2 bigint, col3 array<string>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");

    第 1 行使用 HiveQL CREATE EXTERNAL TABLE 语句。对于 hivetable1,您需要为 DynamoDB 表中的每个属性名称/值对建立一列,并提供数据类型。这些值不区分大小写,并且您可以为列提供任何名称 (保留字除外)。

    第 2 行使用 STORED BY 语句。STORED BY 的值是用于处理 Hive 与 DynamoDB 之间连接的类的名称。该值应设置为 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'

    第 3 行使用 TBLPROPERTIES 语句将“hivetable1”与 DynamoDB 中相应的表和架构相关联。为 TBLPROPERTIES 提供 dynamodb.table.name 参数和 dynamodb.column.mapping 参数的值。这些值区分大小写的。

    注意

    此表的所有 DynamoDB 属性名称必须在 Hive 表中有对应的列。根据您的 Amazon EMR 版本,如果不存在一对一映射,则会发生以下情况:

    • 在 Amazon EMR 5.27.0 及更高版本上,连接器具有验证功能,以确保 DynamoDB 属性名称与 Hive 表中的列之间一一对应。如果不存在一对一映射,则会发生错误。

    • 在 Amazon EMR 5.26.0 及更低版本上,Hive 表将不包含来自 DynamoDB 的名称/值对。如果您未映射 DynamoDB 主键属性,则 Hive 将生成错误。如果您未映射非主键属性,则不会生成错误,但您将无法查看 Hive 表中的数据。如果数据类型不匹配,则值为空。

然后,您可以开始对 hivetable1 运行 Hive 操作。根据 hivetable1 运行的查询也根据 DynamoDB 账户的 DynamoDB 表 dynamodbtable1 在内部运行,在每次执行运行时消耗读取或写入单位。

对 DynamoDB 表运行 Hive 查询时,您需要确保已预置足量的读取容量单位。

例如,假设您为 DynamoDB 表预配置了 100 个读取容量单位。这将允许您每秒执行 100 次读取或读取 409600 字节。如果该表包含 20GB 的数据(21474836480 字节)并且您的 Hive 查询执行全表扫描,则可以估算执行查询将花费多长时间:

21474836480/409600 = 52429 秒 = 14.56 小时

减少所需时间的唯一方法是调整源 DynamoDB 表的读取容量单位。添加更多 Amazon EMR 节点将不会有帮助。

在 Hive 输出中,当一个或多个映射器进程已完成时,将更新完成百分比。对于预配置的读取容量设置较低的大型 DynamoDB 表,完成百分比输出可能会很长时间不更新;在上面的示例中,作业将在几个小时内显示为完成 0%。有关作业进度的详细状态,请转到 Amazon EMR 控制台;您将可以查看单个映射器任务状态和数据读取统计数据。您还可以登录主节点的 Hadoop 界面,查看 Hadoop 统计数据。该界面将向您显示单个映射任务状态和一些数据读取统计数据。有关更多信息,请参阅以下主题:

有关用于执行从 DynamoDB 导出或导入数据和联接表等任务的示例 HiveQL 语句的更多信息,请参阅用于在 DynamoDB 中导出、导入和查询数据的 Hive 命令示例

取消 Hive 请求

执行 Hive 查询时,来自服务器的初始响应包含用于取消请求的命令。要在此过程中随时取消请求,请使用服务器响应中的 Kill 命令

  1. 输入 Ctrl+C 可退出命令行客户端。

  2. 在 Shell 提示符下,输入服务器对您的请求的初始响应中的 Kill 命令

    或者,您也可以从主节点的命令行运行以下命令来终止 Hadoop 任务,其中 job-id 是 Hadoop 任务的标识符,可从 Hadoop 用户界面检索到。

    hadoop job -kill job-id

Hive 和 DynamoDB 的数据类型

下表显示了可用的 Hive 数据类型、它们对应的默认 DynamoDB 类型以及它们也可以映射到的备用 DynamoDB 类型。

Hive 类型 默认 DynamoDB 类型 备用 DynamoDB 类型
字符串

字符串

bigint 或 double

数字 (N)

binary

二进制 (B)

布尔值

boolean (BOOL)

数组 list (L)

数字集 (NS)、字符串集 (SS) 或二进制集 (BS)

map<string,string> 项目

map (M)

map<string,?> map (M)
null (NULL)

如果要将 Hive 数据作为对应的备用 DynamoDB 类型写入,或者您的 DynamoDB 数据包含备用 DynamoDB 类型的属性值,则可以使用 dynamodb.type.mapping 参数指定列和 DynamoDB 类型。以下示例显示了用于指定备用类型映射的语法。

CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename", "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...", "dynamodb.type.mapping" = "hive_column1_name:dynamodb_attribute1_datatype");

类型映射参数是可选的,仅必须为使用备用类型的列指定它。

例如,以下 Hive 命令在 Hive 中创建名为 hivetable2 的表,该表引用 DynamoDB 表 dynamodbtable2。它与 hivetable1 相似,不同之处在于它将 col3 列映射到字符串集 (SS) 类型。

CREATE EXTERNAL TABLE hivetable2 (col1 string, col2 bigint, col3 array<string>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable2", "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays", "dynamodb.type.mapping" = "col3:SS");

在 Hive 中,hivetable1hivetable2 是相同的。但是,将这些表中的数据写入其对应的 DynamoDB 表时,dynamodbtable1 将包含列表,而 dynamodbtable2 将包含字符串集。

如果要将 Hive null 值作为 DynamoDB null 类型的属性写入,则您可以使用 dynamodb.null.serialization 参数来写入。以下示例显示了用于指定 null 序列化的语法。

CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename", "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...", "dynamodb.null.serialization" = "true");

空序列化参数是可选的,如果未指定,则设置为 false。请注意,无论参数设置如何,DynamoDB null 属性都将作为 Hive 中的 null 值进行读取。仅当将空序列化参数指定为 true 时,才能将具有 null 值的 Hive 集合写入 DynamoDB。否则,将出现 Hive 错误。

就精度而言,Hive 中的 bigint 类型与 Java long 类型相同,而 Hive double 类型与 Java double 类型相同。这意味着,如果您有精度高于 Hive 数据类型所提供精度的数值数据存储在 DynamoDB 中,则使用 Hive 导出、导入或引用 DynamoDB 数据会导致精度损失或 Hive 查询失败。

从 DynamoDB 导出到 Amazon Simple Storage Service(Amazon S3)或 HDFS 的二进制类型作为 Base64 编码的字符串进行存储。如果您要将 Amazon S3 或 HDFS 中的数据导入到 DynamoDB 二进制类型,则该数据应编码为 Base64 字符串。

Hive 选项

您可以设置以下 Hive 选项来管理从 Amazon DynamoDB 的数据传出。这些选项只针对当前 Hive 会话保留。如果您在集群上关闭 Hive 命令提示符并稍后重新打开,则这些设置将恢复为默认值。

Hive 选项 描述
dynamodb.throughput.read.percent

设置读取操作的速率,在为您的表分配的范围内保持 DynamoDB 预配置的吞吐速率。该值介于 0.11.5 之间(包含端点)。

值 0.5 是默认读取速率,这意味着,Hive 将在表的整个资源中尝试占用一半的预配读取量。增加此值使之高于 0.5 将提高读取请求速率。减少此值使之低于 0.5 将降低读取请求速率。此读取速率是近似值。实际读取速率取决于 DynamoDB 中是否存在统一分配的键等因素。

如果您发现 Hive 操作经常超出您预配的吞吐量,或者如果过多限制了实时读取流量,则可以减少此值使之低于 0.5。如果您有足够的容量并希望 Hive 操作的速度更快,请将此值设置为高于 0.5。如果您认为有可用的输入/输出操作未使用,则还可以通过将此值设置到最高 1.5 来进行超额预订。

dynamodb.throughput.write.percent

设置写入操作的速率,在为您的表分配的范围内保持 DynamoDB 预配置的吞吐速率。该值介于 0.11.5 之间(包含端点)。

值 0.5 是默认写入速率,这意味着,Hive 将在表的整个资源中尝试占用一半的预配写入量。增加此值使之高于 0.5 将提高写入请求速率。减少此值使之低于 0.5 将降低写入请求速率。此写入速率是近似值。实际写入速率取决于 DynamoDB 中是否存在统一分配的键等因素

如果您发现 Hive 操作经常超出您预配的吞吐量,或者如果过多限制了实时写入流量,则可以减少此值使之低于 0.5。如果您有足够的容量并希望 Hive 操作的速度更快,请将此值设置为高于 0.5。如果您认为有可用的输入/输出操作未使用或者这是到表的初始数据上载,还没有实时流量,则还可以通过将此值设置到最高 1.5 来进行超额预订。

dynamodb.endpoint

为 DynamoDB 服务指定终端节点。有关可用 DynamoDB 终端节点的更多信息,请参阅区域和终端节点

dynamodb.max.map.tasks

指定在从 DynamoDB 读取数据时,映射任务的最大数量。此值必须等于或大于 1。

dynamodb.retry.duration

指定要用作重试 Hive 命令的超时时间的分钟数。此值必须是大于或等于 0 的整数。默认超时持续时间为 2 分钟。

这些选项是使用 SET 命令设置的,如以下示例所示。

SET dynamodb.throughput.read.percent=1.0; INSERT OVERWRITE TABLE s3_export SELECT * FROM hiveTableName;