Amazon EMR 上的 Hive 的区别和注意事项 - Amazon EMR
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

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

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

Hive 授权

Amazon EMR 对于 HDFS 支持 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 EMR 6.1.0 及更高版本支持 Hive ACID(原子性、一致性、隔离、持久性)事务,因此它符合数据库的 ACID 属性。借助此功能,您可以使用 Amazon Simple Storage Service(Amazon S3)中的数据在 Hive 托管表中运行 INSERT、UPDATE、DELETE 和 MERGE 操作。

Hive Live Long and Process (LLAP)

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

Amazon EMR 版本 6.0.0 及更高版本支持 Hive 的 Live Long and Process(LLAP)功能。有关更多信息,请参阅使用 Hive LLAP

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 为大多数工作流提供了改进的性能。

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

Amazon EMR 上的 Hive 的额外功能

Amazon EMR 通过支持 Hive 与其他 Amazon 服务集成的读取和写入 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. 通过以下链接打开 Amazon EMR 控制台:https://console.aws.amazon.com/emr

  2. 选择创建集群

  3. 步骤部分中,对于 Add Step (添加步骤),从列表中选择 Hive Program (Hive 程序),然后选择 Configure and add (配置并添加)

  4. Add Step (添加步骤) 对话框中,参考下表指定参数,然后选择添加

    字段 操作
    脚本 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://amzn-s3-demo-bucket/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';

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

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

    出现故障时的操作

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

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

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

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

  5. 根据需要选择值,然后选择创建集群

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

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

  • 注意

    为了便于读取,包含 Linux 行继续符(\)。它们可以通过 Linux 命令删除或使用。对于 Windows,请将它们删除或替换为脱字号(^)。

    aws emr create-cluster --name "Test cluster" --release-label emr-7.3.0 \ --applications Name=Hive Name=Pig --use-default-roles --ec2-attributes KeyName=myKey --instance-type m5.xlarge --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://amzn-s3-demo-bucket/hive-ads/output/,-d,SAMPLE=s3://elasticmapreduce/samples/hive-ads/]

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

使用 Java 开发工具包将变量值传递到 Hive 步骤
  • 以下示例演示如何使用开发工具包将变量传递到步骤。有关更多信息,请参阅《Amazon SDK for Java API 参考》中的 Class StepFactory

    StepFactory stepFactory = new StepFactory(); StepConfig runHive = new StepConfig() .withName("Run Hive Script") .withActionOnFailure("TERMINATE_JOB_FLOW") .withHadoopJarStep(stepFactory.newRunHiveScriptStep(“s3://amzn-s3-demo-bucket/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 从指定表选择一些项目 (行) 并包括这些项目对应的所有列的数据。
SELECT column1_name, column2_name, column3_name FROM table_name; 从指定表选择所有项目 (行) 并包括这些项目对应的一些列的数据。
SELECT column1_name, column2_name, column3_name FROM table_name WHERE field_name =value; 从指定表选择一些项目 (行) 并包括这些项目对应的一些列的数据。

在不同 Amazon 区域的 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");