

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

# 为 Hive 配置外部元存储
<a name="emr-metastore-external-hive"></a>

默认情况下，Hive 会在主节点的文件系统上的 MySQL 数据库中记录元存储信息。元存储包含表以及在其上构建表的基础数据的描述，包括分区名称、数据类型等。集群终止后，所有集群节点都会关闭，包括主节点。当发生此情况时，本地数据会丢失，因为节点文件系统使用的是短暂存储。如果您需要保留元存储，则必须创建一个存在于集群外部的*外部元存储*。

对于外部元存储，您有两个选项：
+ AWS Glue 数据目录（仅限亚马逊 EMR 版本 5.8.0 或更高版本）。

  有关更多信息，请参阅 [使用 AWS Glue 数据目录作为 Hive 的元数据库](emr-hive-metastore-glue.md)。
+ Amazon RDS 或 Amazon Aurora。

  有关更多信息，请参阅 [使用外部 MySQL 数据库或 Amazon Aurora](emr-hive-metastore-external.md)。

**注意**  
如果您使用 Hive 3 并遇到 Hive 元数据仓的连接太多的问题，请将参数 `datanucleus.connectionPool.maxPoolSize` 配置为一个较小的值或增加数据库服务器可以处理的连接数。连接数量增加是因 Hive 计算 JDBC 连接的最大数量的方式所致。要计算可确保最佳性能的值，请参阅 [Hive 配置属性](https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties#ConfigurationProperties-datanucleus.connectionPool.maxPoolSize.1)。

# 使用 AWS Glue 数据目录作为 Hive 的元数据库
<a name="emr-hive-metastore-glue"></a>

使用 Amazon EMR 版本 5.8.0 或更高版本，您可以将 Hive 配置为使用 Glue 数据目录作为其元 AWS 数据库。当您需要持久的元数据仓或由不同集群、服务、应用程序和 AWS 账户共享的元数据仓时，我们建议使用此配置。

AWS Glue 是一项完全托管的提取、转换和加载 (ETL) 服务，它使对数据进行分类、清理、丰富数据并在各种数据存储之间可靠地移动数据变得简单且经济高效。 AWS Glue 数据目录提供了一个跨各种数据源和数据格式的统一元数据存储库，与亚马逊 EMR 以及亚马逊 RDS、Amazon Redshift、Redshift Spectrum、Athena 以及任何与 Apache Hive 元数据仓兼容的应用程序集成。 AWS Glue 爬网程序可以自动从 Amazon S3 中的源数据推断出架构，并将相关的元数据存储在数据目录中。有关数据目录的更多信息，请参阅 [AWS Glue *开发者指南中的填充 G AWS l* ue 数据目录](https://docs.aws.amazon.com/glue/latest/dg/populate-data-catalog.html)。

Glue 需单独收 AWS 费。在数据目录中存储和访问元数据有月费率，Gl AWS ue ETL 作业和爬虫运行时按小时费率收费，每个预配置的开发端点按每分钟计费。数据目录让您最多可免费存储一百万个对象。如果您存储一百万个以上的对象，将需要为超过一百万的每 100,000 个对象支付 1 美元。数据目录中的对象为表、分区或数据库。有关更多信息，请参阅 [Glue 定价](https://aws.amazon.com/glue/pricing)。

**重要**  
如果您在 2017 年 8 月 14 日之前使用 Amazon Athena 或 Amazon Redshift Spectrum 创建了表，则数据库和表将存储在雅典娜管理的目录中，该目录与 Glue 数据目录是分开的。 AWS 要将 Amazon EMR 与这些表集成，您必须升级到 Glue 数据 AWS 目录。有关更多信息，请参阅*亚马逊 Athena AWS 用户指南中的升级到 Glue* [数据目录](https://docs.aws.amazon.com/athena/latest/ug/glue-upgrade.html)。

## 将 AWS Glue 数据目录指定为元数据库
<a name="emr-hive-glue-configure"></a>

您可以使用 AWS 管理控制台、 AWS CLI或 Amazon EMR API 将 AWS Glue 数据目录指定为元数据库。在使用 CLI 或 API 时，您可以使用 Hive 配置分类指定数据目录。此外，在 Amazon EMR 5.16.0 及更高版本中，您可以使用配置分类在不同的目录中指定数据目录。 AWS 账户在使用控制台时，您可以使用 **Advanced Options (高级选项)** 或 **Quick Options (快速选项)** 指定数据目录。

------
#### [ Console ]

**使用控制台 AWS 将 Glue 数据目录指定为 Hive 元数据仓**

1. [登录 AWS 管理控制台，然后在 /emr 上打开亚马逊 EMR 控制台。https://console.aws.amazon.com](https://console.aws.amazon.com/emr)

1. 在左侧导航窗格中的 **EMR on EC2** 下，选择 **Clusters**（集群），然后选择 **Create cluster**（创建集群）。

1. **在 “**应用程序包**” 下，选择 “**核心 Hadoop**” 或 “自**HBase**定义”。**如果您自定义集群，请确保选择 Hive 或 HCatalog 作为您的应用程序之一。

1. 在**AWS Glue 数据目录设置**下，选择**用于 Hive 表元数据**复选框。

1. 选择适用于集群的任何其他选项。

1. 要启动集群，选择 **Create cluster**（创建集群）。

------
#### [ CLI ]

**要将 AWS Glue 数据目录指定为 Hive 元数据库，请使用 AWS CLI**

有关使用 AWS CLI 和 EMR API 指定配置分类的更多信息，请参阅。[配置应用程序](emr-configure-apps.md)
+ 使用 `hive-site` 配置分类指定 `hive.metastore.client.factory.class` 的值，如下例所示：

  ```
  [
    {
      "Classification": "hive-site",
      "Properties": {
        "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory"
      }
    }
  ]
  ```

  在 EMR 发行版 5.28.0、5.28.1、5.29.0 或 6.x 上，如果您要使用 Glue 数据目录作为元数据仓创建集群，请将 AWS 设置为。`hive.metastore.schema.verification` `false`这会阻止 Hive 和根据 M HCatalog ySQL 验证元数据仓架构。如果没有此配置，则在 Hive 或上重新配置后，主实例组将处于暂停状态。 HCatalog

  ```
  [
    {
      "Classification": "hive-site",
      "Properties": {
        "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory",
        "hive.metastore.schema.verification": "false"
      }
    }
  ]
  ```

  如果您在 EMR 发行版 5.28.0、5.28.1 或 5.29.0 上已有集群，则可以使用以下信息将主实例组 `hive.metastore.schema.verification` 设置为 `false`：

  ```
     
      Classification = hive-site
      Property       = hive.metastore.schema.verification
      Value          = false
  ```

  要在其他 AWS 账户中指定数据目录，请添加`hive.metastore.glue.catalogid`属性，如以下示例所示。将 `acct-id` 替换为数据目录的 AWS 账户。

  ```
  [
    {
      "Classification": "hive-site",
      "Properties": {
        "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory",
        "hive.metastore.schema.verification": "false",
        "hive.metastore.glue.catalogid": "acct-id"
      }
    }
  ]
  ```

------

## IAM 权限
<a name="emr-hive-glue-permissions"></a>

集群的 EC2 实例配置文件必须具有 AWS Glue 操作的 IAM 权限。此外，如果您为 AWS Glue Data Catalog 对象启用加密，则还必须允许该角色加密、解密和生成 AWS KMS key 用于加密的对象。

### AWS Glue 操作的权限
<a name="emr-hive-glue-permissions-actions"></a>

如果使用适用于 Amazon EMR 默认的 EC2 实例配置文件，则无需执行任何操作。附加到的`AmazonElasticMapReduceforEC2Role`托管策略`EMR_EC2_DefaultRole`允许执行所有必要的 AWS Glue 操作。但是，如果您指定自定义 EC2 实例配置文件和权限，则必须配置相应的 AWS Glue 操作。使用 `AmazonElasticMapReduceforEC2Role` 托管策略作为起点。如需了解更多信息，请参阅*《Amazon EMR 管理指南》*中的[集群 EC2 实例的服务角色（EC2 实例配置文件）](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-role-for-ec2.html)。

### 加密和解密 AWS Glue 数据目录的权限
<a name="emr-hive-glue-permissions-encrypt"></a>

您的实例配置文件需要使用密钥加密和解密数据的权限。如果以下语句适用，您*不必*配置这些权限：
+ 您可以使用 Glue 的 AWS 托管密钥为 Glue 数据目录对象启用加密。 AWS 
+ 您使用的集群与 Gl AWS ue 数据目录 AWS 账户 相同。

否则，您必须将以下语句添加到附加到 EC2 实例配置文件的权限策略。

有关 AWS Glue 数据目录加密的更多信息，请参阅 Glu [e *开发者指南中的AWS 加密*数据目录](https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html)。

### 基于资源的权限
<a name="emr-hive-glue-permissions-resource"></a>

如果您在亚马逊 EM AWS R 中将 Glue 与 Hive、Spark 或 Presto 结合使用， AWS Glue 支持基于资源的策略来控制对数据目录资源的访问。这些资源包括数据库、表、连接和用户定义的函数。有关更多信息，请参阅《AWS Glue 开发人员指南》**中的 [AWS Glue 资源策略](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html)。

使用基于资源的策略限制从 Amazon EMR 中访问 AWS Glue 时，您在权限策略中指定的委托人必须是与创建集群时指定的 EC2 实例配置文件关联的角色 ARN。例如，对于附加到目录的基于资源的策略，您可以使用以下示例所示的格式为集群 EC2 实例*EMR\$1EC2\$1DefaultRole*的默认服务角色指定角色 ARN，如下所示：`Principal`

```
arn:aws:iam::acct-id:role/EMR_EC2_DefaultRole
```

*acct-id*可以与 Glue 账 AWS 号 ID 不同。这允许从不同账户中的 EMR 集群进行访问。您可以指定多个委托人，且每个委托人都可以来自不同的账户。

## 使用 AWS Glue 数据目录时的注意事项
<a name="emr-hive-glue-considerations-hive"></a>

使用 AWS Glue 数据目录作为 Hive 的元数据仓时，请考虑以下事项：
+ 不支持 JARs 使用 Hive 外壳添加辅助工具。解决方法是，使用`hive-site`配置分类来设置`hive.aux.jars.path`属性，这会 JARs将辅助属性添加到 Hive 类路径中。
+ 不支持 [Hive 事务](https://cwiki.apache.org/confluence/display/Hive/Hive+Transactions)。
+ 不支持在 AWS Glue 中重命名表。
+ 当您创建 Hive 表而不指定 `LOCATION` 时，表数据存储在通过 `hive.metastore.warehouse.dir` 属性指定的位置。默认情况下，这是 HDFS 中的一个位置。如果另一个集群需要访问该表，则它将失败，除非它有足够的权限访问创建该表的集群。此外，由于 HDFS 存储是暂时性的，因此如果集群终止，表数据将丢失，并且必须重新创建该表。我们建议您在使用 AWS Glue 创建 Hive 表时`LOCATION`在 Amazon S3 中指定。此外，也可以使用 `hive-site` 配置分类来为 `hive.metastore.warehouse.dir` 指定 Amazon S3 中的位置，它适用于所有 Hive 表。如果在 HDFS 位置创建了表，并且创建该表的集群仍在运行，则可以从 Glue 中将该表的位置更新为 Amazon S3 AWS 。有关更多信息，请参阅[《Glue *开发者指南》中的 “在 AWS Glue 控制台AWS 上*使用表格](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html)”。
+ 不支持包含引号和撇号的分区值，例如 `PARTITION (owner="Doe's").`
+ emr-5.31.0 及更高版本支持[列统计数据](https://cwiki.apache.org/confluence/display/Hive/StatsDev#StatsDev-ColumnStatistics)。
+ 不支持使用 [Hive 授权](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Authorization)。作为替代方案，考虑使用[基于AWS Glue 资源的策略](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html)。有关更多信息，请参阅[使用基于资源的策略获得 Amazon EMR 访问 Glue AWS 数据目录。](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-roles-glue.html)
+ 不支持 [Hive 约束](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-Constraints)。
+ 不支持 [Hive 中基于成本的优化](https://cwiki.apache.org/confluence/display/Hive/Cost-based+optimization+in+Hive)。
+ 不支持设置 `hive.metastore.partition.inherit.table.properties`。
+ 不支持使用以下元存储常量：`BUCKET_COUNT, BUCKET_FIELD_NAME, DDL_TIME, FIELD_TO_DIMENSION, FILE_INPUT_FORMAT, FILE_OUTPUT_FORMAT, HIVE_FILTER_FIELD_LAST_ACCESS, HIVE_FILTER_FIELD_OWNER, HIVE_FILTER_FIELD_PARAMS, IS_ARCHIVED, META_TABLE_COLUMNS, META_TABLE_COLUMN_TYPES, META_TABLE_DB, META_TABLE_LOCATION, META_TABLE_NAME, META_TABLE_PARTITION_COLUMNS, META_TABLE_SERDE, META_TABLE_STORAGE, ORIGINAL_LOCATION`。
+ 使用谓词表达式时，显式值必须位于比较运算符的右侧，否则查询可能会失败。
  + **正确**：`SELECT * FROM mytable WHERE time > 11`
  + **错误**：`SELECT * FROM mytable WHERE 11 > time`
+ Amazon EMR 5.32.0 和 6.3.0 及更高版本支持在谓词表达式中使用用户定义的函数 () UDFs。使用早期版本时，查询可能因 Hive 尝试优化查询执行的方式而失败。
+ 不支持[临时表](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-TemporaryTables)。
+ 我们建议通过 Amazon EMR 使用应用程序创建表，而不是直接使用 G AWS lue 创建表。通过 AWS Glue 创建表可能会导致必填字段缺失并导致查询异常。
+ 在 EMR 5.20.0 或更高版本中，当使用 Glue Data Catalog 作为元存储时，Spark 和 Hive 会自动启用并行分区修剪。 AWS 此更改通过并行执行多个请求来检索分区，显著缩短查询计划时间。可同时执行的分段总数介于 1 到 10 之间。默认值为 5，这是建议的设置。您可以通过以下方式更改该值：指定 `hive-site` 配置分类中的属性 `aws.glue.partition.num.segments`。如果发生节流，则可以通过将值更改为 1 来关闭此功能。有关更多信息，请参阅 [AWS Glue 分段结构](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog-partitions.html#aws-glue-api-catalog-partitions-Segment)。

# 使用外部 MySQL 数据库或 Amazon Aurora
<a name="emr-hive-metastore-external"></a>

要使用外部 MySQL 数据库或 Amazon Aurora 作为 Hive 元数据仓，可以覆盖 Hive 中元数据仓的默认配置值，以指定外部数据库位置，无论是在亚马逊 RDS MySQL 实例还是 Amazon Aurora Postgre 上。SQLinstance

**注意**  
Hive 既不支持对元存储表的并发写入访问权限，也不阻止此权限。如果要在两个集群间共享元数据仓信息，您必须确保不会同时写入同一元数据仓表，除非您要写入同一元数据仓表的不同分区。

以下步骤介绍了如何覆盖 Hive 元数据仓位置的默认配置值和使用重新配置的元数据仓位置启动集群。

**创建位于 EMR 集群外的元数据仓**

1. 创建 MySQL 或 Aurora PostgreSQL 数据库。如果您使用 PostgreSQL，则必须在预置集群之后对其进行配置。创建集群时只支持 MySQL。有关 Aurora MySQL 和 Aurora PostgreSQL 之间的区别的信息，请参阅 [Amazon Aurora MySQL 概述](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraMySQL.Overview.html)和[使用 Amazon Aurora PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraPostgreSQL.html)。有关如何创建 Amazon RDS 数据库的总体信息，请参阅[https://aws.amazon.com/rds/](https://aws.amazon.com/rds/)。

1. 修改您的安全组以允许您的数据库和 **ElasticMapReduce-Master** 安全组之间的 JDBC 连接。有关如何修改安全组以进行访问的信息，请参阅[使用 Amazon EMR 托管式安全组](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-man-sec-groups.html)。

1. 在 `hive-site.xml` 中设置 JDBC 配置值：
**重要**  
如果您提供敏感信息（如密码）至 Amazon EMR 配置 API，该信息将仅对拥有充分权限的账户显示。如果您担心此信息可能对其他用户显示，可通过创建以显式方式拒绝 `elasticmapreduce:DescribeCluster` API 密钥许可的角色来使用管理账户创建集群并限制其他用户 (IAM 用户或具有委派凭证的用户) 访问集群服务。

   1. 创建一个名为 `hiveConfiguration.json` 的配置文件，该文件包含对 `hive-site.xml` 的编辑，如以下示例所示。

       *hostname*替换为运行数据库的 Amazon RDS 实例的 DNS 地址，*username*并*password*替换为数据库的证书。有关连接到 MySQL 和 Aurora 数据库实例的更多信息，请参阅*《Amazon RDS 用户指南》*中的[连接到运行 MySQL 数据库引擎的数据库实例](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ConnectToInstance.html)和[连接到 Athena 数据库集群](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Aurora.Connect.html)。`javax.jdo.option.ConnectionURL` 是 JDBC 元存储的 JDBC 连接字符串。`javax.jdo.option.ConnectionDriverName` 是 JDBC 元存储的驱动程序类名。

      MySQL JDBC 驱动程序由 Amazon EMR 进行安装。

      值属性不能包含任何空格或回车。所有内容应显示在一行中。

      ```
      [
          {
            "Classification": "hive-site",
            "Properties": {
              "javax.jdo.option.ConnectionURL": "jdbc:mysql://hostname:3306/hive?createDatabaseIfNotExist=true",
              "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
              "javax.jdo.option.ConnectionUserName": "username",
              "javax.jdo.option.ConnectionPassword": "password"
            }
          }
        ]
      ```

   1. 创建集群时引用该`hiveConfiguration.json`文件，如以下 AWS CLI 命令所示。在此命令中，此文件存储在本地，您也可将此文件上传到 Amazon S3 并在此对其进行引用，例如 `s3://DOC-EXAMPLE-BUCKET/hiveConfiguration.json`。
**注意**  
为了便于读取，包含 Linux 行继续符（\$1）。它们可以通过 Linux 命令删除或使用。对于 Windows，请将它们删除或替换为脱字号（^）。

      ```
      aws emr create-cluster --release-label emr-7.12.0 --instance-type m5.xlarge --instance-count 2 \
      --applications Name=Hive --configurations file://hiveConfiguration.json --use-default-roles
      ```

1. 连接到集群的主节点。

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

1. 通过输入类似以下内容的命令，创建在 Amazon S3 上指定位置的 Hive 表：

   ```
   CREATE EXTERNAL TABLE IF NOT EXISTS table_name
   (
   key int,
   value int
   )
   LOCATION s3://DOC-EXAMPLE-BUCKET/hdfs/
   ```

1. 将 Hive 脚本添加到正在运行的集群。

您的 Hive 集群使用 Amazon RDS 中的元数据运行。通过指定该元数据仓位置，启动共享该元数据仓的所有其他 Hive 集群。