

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

# 设置 Hive 表来运行 Hive 命令
<a name="EMR_Interactive_Hive"></a>

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

下面的程序假定您已创建集群并指定了 Amazon EC2 密钥对。要了解如何开始创建集群，请参阅《Amazon EMR 管理指南》**中的 [Amazon EMR 入门](https://docs.amazonaws.cn/emr/latest/ManagementGuide/emr-gs)。

## 配置 Hive 以供使用 MapReduce
<a name="hive-mapreduce"></a>

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

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

```
[
                {
                    "Classification": "hive-site",
                    "Properties": {
                        "hive.execution.engine": "mr"
                    }
                }
             ]
```<a name="EMR_Interactive_Hive_session"></a>

**以交互方式运行 Hive 命令**

1. 连接到主节点。有关更多信息，请参阅《Amazon EMR 管理指南》**中的[使用 SSH 连接到主节点](https://docs.amazonaws.cn/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html)。

1. 当命令提示输入当前主节点时，键入 `hive`。

   您应看到 Hive 提示符：`hive>`

1.  输入用于将 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 表 dynamodbt *able1* 具有主键架构。 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 版本，如果 one-to-one映射不存在，则会出现以下情况：  
在 Amazon EMR 5.27.0 及更高版本上，连接器经过验证，可确保 DynamoDB 属性名称与 Hive 表中的列 one-to-one之间存在映射。如果 one-to-one映射不存在，则会发生错误。
在 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 统计数据。该界面将向您显示单个映射任务状态和一些数据读取统计数据。有关更多信息，请参阅以下主题：
+ [托管在主节点 (master node) 上的 Web 界面](https://docs.amazonaws.cn/emr/latest/ManagementGuide/emr-web-interfaces.html)
+ [查看 Hadoop Web 界面](https://docs.amazonaws.cn/emr/latest/ManagementGuide/UsingtheHadoopUserInterface.html)

有关用于执行从 DynamoDB 导出或导入数据和联接表等任务的示例 HiveQL 语句的更多信息，请参阅[用于在 DynamoDB 中导出、导入和查询数据的 Hive 命令示例](EMR_Hive_Commands.md)。<a name="EMR_Hive_Cancel"></a>

**取消 Hive 请求**

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

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

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

    或者，您可以从主节点的命令行运行以下命令来终止 Hadoop 作业，其中*job-id*是 Hadoop 作业的标识符，可以从 Hadoop 用户界面中检索。

   ```
   hadoop job -kill job-id
   ```

## Hive 和 DynamoDB 的数据类型
<a name="EMR_Hive_Properties"></a>

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


| Hive 类型 | 默认 DynamoDB 类型 | 备用 DynamoDB 类型 | 
| --- | --- | --- | 
| 字符串 | 字符串 |  | 
| bigint 或 double | 数字 (N) |  | 
| binary | 二进制 (B) |  | 
| 布尔值 | boolean (BOOL) |  | 
| array | 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 中，`hivetable1` 和 `hivetable2` 是相同的。但是，将这些表中的数据写入其对应的 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 选项
<a name="EMR_Hive_Options"></a>

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


| Hive 选项 | 说明 | 
| --- | --- | 
| dynamodb.throughput.read.percent |   设置读取操作的速率，在为您的表分配的范围内保持 DynamoDB 预配置的吞吐速率。该值介于 `0.1` 到 `1.5` 之间（包含端点）。  值 0.5 是默认读取速率，这意味着，Hive 将在表的整个资源中尝试占用一半的预配读取量。增加此值使之高于 0.5 将提高读取请求速率。减少此值使之低于 0.5 将降低读取请求速率。此读取速率是近似值。实际读取速率取决于 DynamoDB 中是否存在统一分配的键等因素。  如果您发现 Hive 操作经常超出您预配的吞吐量，或者如果过多限制了实时读取流量，则可以减少此值使之低于 `0.5`。如果您有足够的容量并希望 Hive 操作的速度更快，请将此值设置为高于 `0.5`。如果您认为有可用的输入/输出操作未使用，则还可以通过将此值设置到最高 1.5 来进行超额预订。  | 
| dynamodb.throughput.write.percent |   设置写入操作的速率，在为您的表分配的范围内保持 DynamoDB 预配置的吞吐速率。该值介于 `0.1` 到 `1.5` 之间（包含端点）。  值 0.5 是默认写入速率，这意味着，Hive 将在表的整个资源中尝试占用一半的预配写入量。增加此值使之高于 0.5 将提高写入请求速率。减少此值使之低于 0.5 将降低写入请求速率。此写入速率是近似值。实际写入速率取决于 DynamoDB 中是否存在统一分配的键等因素   如果您发现 Hive 操作经常超出您预配的吞吐量，或者如果过多限制了实时写入流量，则可以减少此值使之低于 `0.5`。如果您有足够的容量并希望 Hive 操作的速度更快，请将此值设置为高于 `0.5`。如果您认为有可用的输入/输出操作未使用或者这是到表的初始数据上载，还没有实时流量，则还可以通过将此值设置到最高 1.5 来进行超额预订。  | 
| dynamodb.endpoint | 为 DynamoDB 服务指定终端节点。有关可用 DynamoDB 终端节点的更多信息，请参阅[区域和终端节点](https://docs.amazonaws.cn/general/latest/gr/rande.html#ddb_region)。  | 
| 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;
```