Amazon EMR
Amazon EMR 版本指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

Amazon EMR 上的 Hive 的区别和注意事项

Amazon EMR 上的 Apache Hive 和 Apache Hive 之间的区别

本节介绍 Amazon EMR 上的 Hive 和 http://svn.apache.org/viewvc/hive/branches/ 上提供的默认 Hive 版本之间的区别。

Hive 授权

对于 HDFS,Amazon EMR 支持 Hive 授权 (但对 EMRFS 和 Amazon S3 不支持)。默认情况下,Amazon EMR 集群在禁用授权的状态下运行。

Amazon S3 中的 Hive 文件合并操作

如果 hive.merge.mapfiles 为 true,那么 Apache Hive 会在仅 map 作业结束时合并小文件,且仅在平均的作业输出大小低于 hive.merge.smallfiles.avgsize 设置时才会触发合并。如果最终输出路径在 HDFS 中,那么 Amazon EMR Hive 会拥有完全相同的行为。如果输出路径在 Amazon S3 中,则会忽略 hive.merge.smallfiles.avgsize 参数。在那种情况下,如果 hive.merge.mapfiles 设置为 true,会始终触发合并任务。

ACID 事务和 Amazon S3

存储在 Amazon S3 中的 Hive 数据不支持 ACID (原子性、一致性、隔离、持久性) 事务。尝试在 Amazon S3 中创建事务表会导致出现异常。

Hive Live Long and Process (LLAP)

在默认 Apache Hive 版本 2.0 中添加的 LLAP 功能在 Amazon EMR 5.0 版上的 Hive 2.1.0 中不受支持。

Hive 在 Amazon EMR 发布版本 4.x 和 5.x 之间的不同

本节介绍在将 Hive 实施从 Amazon EMR 4.x 版上的 Hive 1.0.0 版迁移到 Amazon EMR 5.x 版上的 Hive 2.x 之前要考虑的区别。

操作区别和注意事项

  • 添加了对 ACID (原子性、一致性、隔离和持久性) 事务的支持:Amazon EMR 4.x 上的 Hive 1.0.0 和默认 Apache Hive 之间的这一区别已经消除。

  • 直接写入 Amazon S3 已消除:Amazon EMR 上的 Hive 1.0.0 和默认 Apache Hive 之间的这一区别已经消除。Amazon EMR 5.x 版上的 Hive 2.1.0 现在创建、读取和写入在 Amazon S3 中存储的临时文件。因此,要读取和写入同一个表,您不再需要在集群的本地 HDFS 文件系统中创建一个临时表作为解决办法。如果您使用受版本控制的存储桶,请确保如下所述管理这些临时文件。

  • 使用 Amazon S3 受版本控制的存储桶时管理临时文件:当您在生成数据的目的地是 Amazon S3 的环境中运行 Hive 查询时,会创建许多临时文件和目录。这是新行为,如上所述。如果您使用受版本控制的 S3 存储桶,那么不删除这些临时文件会使 Amazon S3 凌乱并产生费用。请调整生命周期规则,以便包含 /_tmp 前缀的数据在一个短周期 (例如,五天) 后被删除。有关更多信息,请参阅指定生命周期配置

  • Log4j 已更新到 log4j 2:如果您使用 log4j,则可能因为此升级而需要更改您的日志记录配置。有关更多信息,请参阅 Apache log4j 2

性能区别和注意事项

  • 使用 Tez 时的性能区别:对于 Amazon EMR 5.x 版,Tez 是 Hive 的默认执行引擎,而不是 MapReduce。Tez 为大多数工作流提供更高的性能。

  • ORC 文件性能:对于 ORC 文件,查询性能速度可能低于预期。

  • 具有许多分区的表:生成大量动态分区的查询可能会失败,从具有许多分区的表中进行选择的查询可能需要比预期更长的时间才能执行完毕。例如,从 100,000 个分区中进行选择可能需要 10 分钟或更长时间。

Amazon EMR 上的 Hive 的额外功能

Amazon EMR 通过支持 Hive 与其他 AWS 服务集成的新功能 (如读取和写入 Amazon Simple Storage Service (Amazon S3) 和 DynamoDB 的功能) 来扩展 Hive。

Hive 中的变量

您可以使用美元符号和大括号在脚本中包括变量。

add jar ${LIB}/jsonserde.jar

如以下示例所示,您可以在命令行上使用 -d 参数将这些变量的值传递给 Hive:

-d LIB=s3://elasticmapreduce/samples/hive-ads/lib

您还可以将值传递到执行 Hive 脚本的步骤。

使用控制台将变量值传递到 Hive 步骤

  1. Open the Amazon EMR console at https://console.amazonaws.cn/elasticmapreduce/.

  2. 选择 Create cluster

  3. Steps 部分中,对于 Add Step,从列表中选择 Hive Program,然后选择 Configure and add

  4. Add Step 对话框中,参考下表指定参数,然后选择 Add

    字段 操作
    脚本 S3 位置* 指定 Amazon S3 中脚本存储位置的 URI。该值的形式必须是 BucketName/path/ScriptName。例如:s3://elasticmapreduce/samples/hive-ads/libs/response-time-stats.q
    输入 S3 位置 指定 Amazon S3 中输入文件存储位置的 URI (可选)。该值的形式必须是:BucketName/path/。如果指定完毕,则以名为“INPUT”的参数将其传递到 Hive 脚本。例如:s3://elasticmapreduce/samples/hive-ads/tables/
    输出 S3 位置 指定您希望在 Amazon S3 中存储该输出的 URI (可选)。该值的形式必须是:BucketName/path。如果指定完毕,则以名为“OUTPUT”的参数将其传递到 Hive 脚本。例如:s3://mybucket/hive-ads/output/
    参数 输入要传递到 Hive 的参数列表 (以空格分隔的字符串)。如果您在名为 ${SAMPLE} 的 Hive 脚本中定义了一个路径变量,如:
    CREATE EXTERNAL TABLE logs (requestBeginTime STRING, requestEndTime STRING, hostname STRING) PARTITIONED BY (dt STRING) \ ROW FORMAT serde 'com.amazon.elasticmapreduce.JsonSerde' WITH SERDEPROPERTIES ( 'paths'='requestBeginTime, requestEndTime, hostname' ) LOCATION '${SAMPLE}/tables/impressions';

    要传递该变量的值,请在 Arguments (参数) 窗口中键入以下内容:

    -d SAMPLE=s3://elasticmapreduce/samples/hive-ads/.

    出现故障时的操作

    这决定了集群为响应任何错误而执行的操作。此设置的可能值为:

    • Terminate cluster (终止集群):如果该步骤失败,则终止集群。如果集群启用了终止保护和保持活动状态,则它不会终止。

    • Cancel and wait (取消并等待):如果该步骤失败,则取消剩余步骤。如果集群启用了保持活动状态,则集群不会终止。

    • Continue (继续):如果该步骤失败,则继续到下一个步骤。

  5. 根据需要选择值,然后选择 Create cluster

使用 AWS CLI 将变量值传递到 Hive 步骤

要使用 AWS CLI 将变量值传递到 Hive 步骤,请使用 --steps 参数并包括参数列表。

  • 注意

    包含了 Linux 行继续符 (\) 以提高可读性。可以在 Linux 命令中删除或使用它们。对于 Windows,请删除它们或将其替换为脱字号 (^)。

    aws emr create-cluster --name "Test cluster" --release-label emr-5.14.0 \ --applications Name=Hive Name=Pig --use-default-roles --ec2-attributes KeyName=myKey --instance-type m4.large --instance-count 3 \ --steps Type=Hive,Name="Hive Program",ActionOnFailure=CONTINUE,Args=[-f,s3://elasticmapreduce/samples/hive-ads/libs/response-time-stats.q,-d,INPUT=s3://elasticmapreduce/samples/hive-ads/tables,-d,OUTPUT=s3://mybucket/hive-ads/output/,-d,SAMPLE=s3://elasticmapreduce/samples/hive-ads/]

    有关如何在 AWS CLI 中使用 Amazon EMR 命令的更多信息,请参阅 https://docs.amazonaws.cn/cli/latest/reference/emr

使用 Java 开发工具包将变量值传递到 Hive 步骤

  • 以下示例演示如何使用开发工具包将变量传递到步骤。有关更多信息,请参阅适用于 Java API 参考的 AWS 开发工具包 中的 StepFactory 类

    StepFactory stepFactory = new StepFactory(); StepConfig runHive = new StepConfig() .withName("Run Hive Script") .withActionOnFailure("TERMINATE_JOB_FLOW") .withHadoopJarStep(stepFactory.newRunHiveScriptStep(“s3://mybucket/script.q”, Lists.newArrayList(“-d”,”LIB= s3://elasticmapreduce/samples/hive-ads/lib”));

Amazon EMR Hive 查询可适应部分 DynamoDB 架构

在查询 DynamoDB 表时,Amazon EMR Hive 允许您指定一部分列作为数据筛选条件,而不要求您的查询包含所有列,因此可提供最大的灵活性。当采用稀疏数据库架构,并希望根据一些列来筛选记录 (例如根据时间戳筛选) 时,这种部分架构查询技术可以发挥作用。

以下示例显示了如何使用 Hive 查询执行下列操作:

  • 创建 DynamoDB 表。

  • 选择 DynamoDB 中的一部分项目 (行) 并进一步将数据范围缩小到特定列。

  • 将结果数据复制到 Amazon S3。

DROP TABLE dynamodb; DROP TABLE s3; CREATE EXTERNAL TABLE dynamodb(hashKey STRING, recordTimeStamp BIGINT, fullColumn map<String, String>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ( "dynamodb.table.name" = "myTable", "dynamodb.throughput.read.percent" = ".1000", "dynamodb.column.mapping" = "hashKey:HashKey,recordTimeStamp:RangeKey"); CREATE EXTERNAL TABLE s3(map<String, String>) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 's3://bucketname/path/subpath/'; INSERT OVERWRITE TABLE s3 SELECT item fullColumn FROM dynamodb WHERE recordTimeStamp < "2012-01-01";

下表显示了从 DynamoDB 中选择任意项目组合的查询语法。

查询范例 结果描述
table_name 中选择 *; 从指定表选择所有项目 (行) 并包括这些项目对应的所有列的数据。
table_name 中选择 *,其中 field_name =value 从指定表选择一些项目 (行) 并包括这些项目对应的所有列的数据。
table_name 中选择 column1_namecolumn2_namecolumn3_name 从指定表选择所有项目 (行) 并包括这些项目对应的一些列的数据。
table_name 中选择 column1_namecolumn2_namecolumn3_name,其中 field_name =value 从指定表选择一些项目 (行) 并包括这些项目对应的一些列的数据。

在不同 AWS 区域的 DynamoDB 表之间复制数据

Amazon EMR Hive 提供了可以为每个 DynamoDB 表设置的 dynamodb.region 属性。当两个表的 dynamodb.region 设置不同时,您在两个表之间执行的所有数据复制将自动在指定区域之间发生。

以下示例显示了如何通过用于设置 dynamodb.region 属性的 Hive 脚本创建 DynamoDB 表:

注意

每个表的 region 属性会覆盖全局 Hive 属性。

CREATE EXTERNAL TABLE dynamodb(hashKey STRING, recordTimeStamp BIGINT, map<String, String> fullColumn) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ( "dynamodb.table.name" = "myTable", "dynamodb.region" = "eu-west-1", "dynamodb.throughput.read.percent" = ".1000", "dynamodb.column.mapping" = "hashKey:HashKey,recordTimeStamp:RangeKey");

设置每个表的 DynamoDB 吞吐量值

Amazon EMR Hive 允许您在表定义中设置每个表的 DynamoDB readThroughputPercent 和 writeThroughputPercent 设置。以下 Amazon EMR Hive 脚本显示了如何设置吞吐量值。有关 DynamoDB 吞吐量值的更多信息,请参阅指定表的读取和写入要求

CREATE EXTERNAL TABLE dynamodb(hashKey STRING, recordTimeStamp BIGINT, map<String, String> fullColumn) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ( "dynamodb.table.name" = "myTable", "dynamodb.throughput.read.percent" = ".4", "dynamodb.throughput.write.percent" = "1.0", "dynamodb.column.mapping" = "hashKey:HashKey,recordTimeStamp:RangeKey");