Presto Hive Connector


1 概述

HiveConnector允许查询存储在Hive数据仓库中的数据。

Hive由以下三个部分组成:

  • 各种格式的数据文件:通常存储在Hadoop分布式文件系统(HDFS)或AmazonS3中
  • 描述数据文件如何映射到模式(schema)和表(table)的元数据:此元数据存储在MySQL等数据库中,可通过Hive元存储服务访问
  • HiveQL查询语言:这种查询语言在分布式计算框架上运行,例如MapReduceTez

Presto只使用前两个组件:数据文件元数据

2 支持文件类型

Hive Connector支持以下文件类型:

  • ORC
  • Parquet
  • Avro
  • RCFile
  • SequenceFile
  • JSON
  • Text

3 配置

Hive连接器支持ApacheHadoop2.x衍生发行版,包括ClouderaCDH5Hortonworks数据平台(HDP)。
etc/catalog/hive.properties使用以下内容创建以将hive-hadoop2连接器挂载为hive目录,替换example.net:9083为HiveMetastoreThrift服务的正确主机和端口:

connector.name=hive-hadoop2
hive.metastore.uri=thrift://example.net:9083

1)多个Hive集群

您可以根据需要创建任意数量的目录(catalog),因此如果您有其他Hive集群,只需添加另一个etc/catalog具有不同名称的属性文件,并确保以.properties结尾。

2)HDFS配置

对于基本设置,Presto会自动配置HDFS客户端,不需要任何配置文件。

在某些情况例如使用联合HDFS或NameNode高可用性时,需要指定额外的HDFS客户端选项才能访问您的HDFS集群。

为此,添加hive.config.resources属性以引用您的HDFS配置文件:

hive.config.resources=/etc/hadoop/conf/core-site.xml,/etc/hadoop/conf/hdfs-site.xml

3)HDFS用户名

当Kerberos不与HDFS一起运行使用时,Presto将通过Presto进程的OS用户访问HDFS。

4)访问受Kerberos身份验证保护的Hadoop集群

HDFS和Hive元存储均支持Kerberos身份验证

4 Hive属性配置

1)Metastore配置属性

可以使用许多属性配置所需的Hive元存储。

PropertyName

描述

默认

hive.metastore-timeout

Hive元存储请求超时。

10s

hive.metastore-cache-ttl

缓存的Metastore数据应被视为有效的持续时间。

0s

hive.metastore-cache-maximum-size

HiveMetastore缓存最大大小。

10000

hive.metastore-refresh-interval

访问后异步刷新缓存的Metastore数据,如果它比这更旧但尚未过期,则允许后续访问查看新数据。

0s

hive.metastore-refresh-max-threads

用于刷新缓存的元存储数据的最大线程数。

100

2)AWSGlue目录配置属

PropertyName

描述

hive.metastore.glue.region

Glue目录的AWS区域。当不在EC2中运行或目录位于不同区域时,这是必需的。例子:us-east-1

hive.metastore.glue.pin-client-to-current-region

将Glue请求固定到与运行Presto的EC2实例相同的区域(默认为false)。

hive.metastore.glue.max-connections

到Glue的最大并发连接数(默认为5)。

hive.metastore.glue.max-error-retries

Glue客户端的最大错误重试次数,默认为10.

hive.metastore.glue.default-warehouse-dir

HiveGlueMetastore默认仓库目录

hive.metastore.glue.aws-access-key

用于连接到Glue目录的AWS访问密钥。如果与一起指定hive.metastore.glue.aws-secret-key,则此参数优先于hive.metastore.glue.iam-role

hive.metastore.glue.aws-secret-key

用于连接到Glue目录的AWS密钥。如果与一起指定hive.metastore.glue.aws-access-key,则此参数优先于hive.metastore.glue.iam-role

hive.metastore.glue.catalogid

元数据数据库所在的Glue目录的ID。

hive.metastore.glue.endpoint-url

GlueAPI端点URL(可选)。例子:https://glue.us-east-1.amazonaws.com

hive.metastore.glue.partitions-segments

分区Glue表的段数。

hive.metastore.glue.get-partition-threads

从Glue获取并行分区的线程数。

hive.metastore.glue.iam-role

连接到Glue目录时要承担的IAM角色的ARN。

3)AmazonS3配置

Hive连接器可以读取写入存储在S3中的表,这是通过使用S3前缀而不是HDFS前缀的表或数据库位置来实现的。

Presto使用自己的S3文件系统作为URI前缀s3://,s3n://和s3a://.

  • S3配置属性

PropertyName

描述

hive.s3.use-instance-credentials

使用EC2元数据服务检索API凭证(默认为true)。这适用于EC2中的IAM角色。

hive.s3.aws-access-key

要使用的默认AWS访问密钥。

hive.s3.aws-secret-key

要使用的默认AWS密钥。

hive.s3.iam-role

要承担的IAM角色。

hive.s3.endpoint

S3存储端点服务器。这可用于连接到S3兼容的存储系统而不是AWS。使用v4签名时,建议将其设置为特定于AWS区域的端点(例如,http[s]://<bucket>.s3-<AWS-region>.amazonaws.com)。

hive.s3.storage-class

写入数据时使用的S3存储类。目前仅支持STANDARDINTELLIGENT_TIERING存储类。默认存储类别是STANDARD

hive.s3.signer-type

为S3兼容存储指定不同的签名者类型。示例:S3SignerType对于v2签名者类型

hive.s3.path-style-access

对S3兼容存储的所有请求使用路径样式访问。这适用于不支持虚拟托管式访问的S3兼容存储。(默认为false

hive.s3.staging-directory

写入S3的数据的本地暂存目录。这默认为JVM系统属性指定的Java临时目录java.io.tmpdir

hive.s3.pin-client-to-current-region

将S3请求固定到与运行Presto的EC2实例相同的区域(默认为false)。

hive.s3.ssl.enabled

使用HTTPS与S3API通信(默认为true)。

hive.s3.sse.enabled

使用S3服务器端加密(默认为false)。

hive.s3.sse.type

S3服务器端加密的密钥管理类型。使用S3了S3管理或KMS对KMS管理键(默认S3)。

hive.s3.sse.kms-key-id

用于使用KMS管理的密钥进行S3服务器端加密的KMS密钥ID。如果未设置,则使用默认密钥。

hive.s3.kms-key-id

如果设置,则使用S3客户端加密并使用AWSKMS存储加密密钥,并使用此属性的值作为新创建对象的KMS密钥ID。

hive.s3.encryption-materials-provider

如果设置,则使用S3客户端加密并将此属性的值用作实现AWS开发工具包EncryptionMaterialsProvider接口的Java类的完全限定名称。如果该类也Configurable从HadoopAPI实现,则将在创建对象后传入Hadoop配置。

hive.s3.upload-acl-type

将文件上传到S3时使用的预制ACL(默认为Private)。

hive.s3.skip-glacier-objects

忽略Glacier对象而不是使查询失败。这将跳过可能是表或分区的一部分的数据。默认为false.

  • S3凭证

如果您在AmazonEC2上使用EMR或在其他设备运行期间,我们建议您将hive.s3.use-instance-credentials设定为true,并使用IAM角色EC2实例到S3的访问。

这种情况下,您的EC2实例将需要分配一个IAM角色,该角色授予您希望使用的S3数据适当的访问权限。您还可以配置一个IAM角色,hive.s3.iam-role该角色将被假定用于访问任何S3存储空间。

  • 调整属性

以下调整属性会影响PrestoS3文件系统在与S3通信时使用的客户端的行为。这些参数中的大多数会影响ClientConfigurationAmazonS3Client

PropertyName

描述

默认

hive.s3.max-error-retries

在S3客户端上设置的最大错误重试次数。

10

hive.s3.max-client-retries

重试的最大读取尝试次数。

5

hive.s3.max-backoff-time

与S3通信时,使用指数退避从1秒开始到此最大值。

10minutes

hive.s3.max-retry-time

重试与S3通信的最长时间。

10minutes

hive.s3.connect-timeout

TCP连接超时。

5seconds

hive.s3.socket-timeout

TCP套接字读取超时。

5seconds

hive.s3.max-connections

到S3的最大同时打开连接数。

500

hive.s3.multipart.min-file-size

使用分段上传到S3之前的最小文件大小。

16MB

hive.s3.multipart.min-part-size

最小分段上传分段大小。

5MB

  • S3数据加密

Presto支持使用S3托管密钥的服务器端加密和使用AmazonKMS或软件插件管理AES加密密钥的客户端加密在S3中读取和写入加密数据。

使用S3服务器端加密(在Amazon文档中称为SSE-S3),S3基础设施负责所有加密和解密工作(客户端的SSL除外,假设您已hive.s3.ssl.enabled设置为true)。S3还为您管理所有加密密钥。要启用此功能,请设置hive.s3.sse.enabled为true。

使用S3客户端加密,S3存储加密数据并且加密密钥在S3基础架构之外进行管理。数据由Presto加密和解密,而不是在S3基础设施中。在这种情况下,可以使用AWSKMS或您自己的密钥管理系统来管理加密密钥。要使用AWSKMS进行密钥管理,请设置hive.s3.kms-key-id为KMS密钥的UUID。您的AWS凭证或EC2IAM角色也需要被授予使用给定密钥的权限。

要使用自定义加密密钥管理系统,请设置hive.s3.encryption-materials-provider为实现来自AWSJava开发工具包的EncryptionMaterialsProvider接口的类的完全限定名称。Hive连接器必须可以通过类路径访问此类,并且必须能够与您的自定义密钥管理系统进行通信。如果这个类也实现了org.apache.hadoop.conf.Configurable来自HadoopJavaAPI的接口,那么Hadoop配置将在对象实例创建之后和被要求提供或检索任何加密密钥之前传入。

  • S3SelectPushdown

S3SelectPushdown启用将投影(SELECT)和谓词(WHERE)处理下推到S3Select。使用S3SelectPushdownPresto仅从S3检索所需数据,而不是从整个S3对象检索所需的数据,从而减少延迟和网络使用。

4)Alluxio配置

Presto可以读取和写入存储在Alluxio数据编排系统Alluxio中的表,利用Alluxio的分布式块级读/写缓存功能。这些表必须在带有alluxio://位置前缀的Hive元存储中创建(有关详细信息和示例,请参阅使用Alluxio运行ApacheHive)。然后,Presto查询将从各种不同的存储系统(包括HDFS和S3)透明地检索和缓存文件或对象。

  • Alluxio客户端配置

要在Presto上配置Alluxio客户端属性,请将Alluxio配置目录(${ALLUXIO_HOME}/conf)附加到PrestoJVM类路径,以便可以将Alluxio属性文件alluxio-site.properties作为资源加载。更新PrestoJVM配置文件etc/jvm.config以包含以下内容:

-Xbootclasspath/a:<path-to-alluxio-conf>

这种方法的优点是所有Alluxio属性都在单个alluxio-site.properties文件中设置。

或者,将Alluxio配置属性添加到Hadoop配置文件(core-site.xml,hdfs-site.xml)并配置Hive连接器以通过连接器属性使用Hadoop配置文件hive.config.resources。

  • 使用Presto部署Alluxio

为了在Alluxio上运行Presto获得最佳性能,建议将PrestoWorker与AlluxioWorker搭配使用。这允许读取和写入绕过网络。

  • Alluxio目录服务

Presto与Alluxio交互的另一种方式是通过Alluxio目录服务。.使用Alluxio目录服务的主要好处是使用Presto更简单地部署Alluxio,并启用架构感知优化,例如透明缓存和转换。目前,目录服务支持只读工作负载。

AlluxioCatalogService是一个元存储,可以缓存来自不同底层元存储的信息。它目前支持HiveMetastore作为底层Metastore。为了让AlluxioCatalog管理其他现有Metastore的元数据,其他Metastore必须“附加”到Alluxio目录。要将现有的Hive元存储附加到Alluxio目录,只需使用AlluxioCLIattachdb命令。需要提供适当的Hive元存储位置和Hive数据库名称。

./bin/alluxiotableattachdbhivethrift://HOSTNAME:9083hive_db_name

一旦附加了Metastore,AlluxioCatalog就可以管理信息并将其提供给Presto。要为Alluxio目录服务配置Hive连接器,只需将连接器配置为使用Alluxio元存储类型,并为Alluxio集群提供位置。例如,您etc/catalog/catalog_alluxio.properties将包括以下内容(将Alluxio地址替换为适当的位置):

connector.name=hive-hadoop2
hive.metastore=alluxio
hive.metastore.alluxio.master.address=HOSTNAME:PORT

现在,Presto查询可以利用Alluxio目录服务,例如透明缓存和透明转换,而无需对现有Hive元存储部署进行任何修改。

5 表格统计

Hive连接器会自动收集有关和操作的基本统计信息(、、)。numFiles’,“numRowsrawDataSizetotalSizeINSERTCREATETABLEAS

Hive连接器还可以收集列级统计信息:

列类型

可收集的统计数据

TINYINT

空值数量、不同值的数量、最小值/最大值

SMALLINT

空值数量、不同值的数量、最小值/最大值

INTEGER

空值数量、不同值的数量、最小值/最大值

BIGINT

空值数量、不同值的数量、最小值/最大值

DOUBLE

空值数量、不同值的数量、最小值/最大值

REAL

空值数量、不同值的数量、最小值/最大值

DECIMAL

空值数量、不同值的数量、最小值/最大值

DATE

空值数量、不同值的数量、最小值/最大值

TIMESTAMP

空值数量、不同值的数量、最小值/最大值

VARCHAR

空值的数量,不同值的数量

CHAR

空值的数量,不同值的数量

VARBINARY

空值的数量

BOOLEAN

空值的数量,真/假值的数量

写入时自动收集列级统计信息由collect-column-statistics-on-write目录会话属性控制。

6 收集表和列统计信息

Hive连接器支持通过ANALYZE语句收集表和分区统计信息。在分析分区表时,可以通过可选partitions属性指定要分析的分区,该属性是一个包含分区键值的数组,按它们在表模式中声明的顺序排列:

ANALYZEhive.salesWITH(
partitions=ARRAY[
ARRAY['partition1_value1','partition1_value2'],
ARRAY['partition2_value1','partition2_value2']]);

此查询将使用键收集2个分区的统计信息:

  1. partition1_value1,partition1_value2
  2. partition2_value1,partition2_value2
  • 模式演变

Hive允许表中的分区具有与表不同的架构。当分区已经存在(使用原始列类型)后更改表的列类型时,会发生这种情况。Hive连接器通过允许与Hive相同的转换来支持这一点:

  1. varchar往返tinyint,smallint,integer和bigint
  2. real到double
  3. 整数的tinyint扩展转换,例如到smallint

任何转换失败都会导致null,这与Hive的行为相同。例如,将字符串’foo’转换为数字,或将字符串转换’1234’为atinyint(最大值为127)。

  • Avro架构演进

Presto支持使用Avro存储格式查询和操作Hive表,该格式具有基于Avro架构文件/文字的架构集。也可以在Presto中创建表,从位于本地或远程HDFS/Web服务器中的有效Avro模式文件推断模式。

要指定应使用Avro模式来解释表的数据,必须使用avro_schema_url表属性。该模式可以远程放置在HDFS(例如)、S3(例如)、Web服务器(例如)以及本地文件系统中。架构所在的url必须可以从HiveMetastore和Presto协调器/工作器节点访问。avro_schema_url=’hdfs://user/avro/schema/avro_data.avsc’avro_schema_url=’s3n:///schema_bucket/schema/avro_data.avsc’avro_schema_url=’http://example.org/schema/avro_data.avsc’

在Presto中使用创建的表的avro_schema_url行为方式与使用avro.schema.url或avro.schema.literal设置的Hive表相同。

例子:

CREATETABLEhive.avro.avro_data(
idbigint
)
WITH(
format='AVRO',
avro_schema_url='/usr/local/avro_data.avsc'
)

id如果avro_schema_url指定,则DDL中列出的列(在上面的示例中)将被忽略。表架构将匹配Avro架构文件中的架构。在任何读取操作之前,都会访问Avro模式,以便查询结果反映模式中的任何更改。因此,Presto利用了Avro的向后兼容性能力。

如果Avro架构文件中表的架构发生变化,新架构仍可用于读取旧数据。新添加/重命名的字段必须在Avro架构文件中具有默认值。

模式演化行为如下:

在新模式中添加的列:当表使用新模式时,使用旧模式创建的数据将产生默认值。

在新模式中删除的列:使用旧模式创建的数据将不再从已删除的列中输出数据。

列在新模式中重命名:这相当于删除列并添加新列,当表使用新模式时,使用旧模式创建的数据将产生默认值。

更改新架构中的列类型:如果Avro或Hive连接器支持类型强制,则会发生转换。不兼容的类型会引发错误。

7 程序

  • system.create_empty_partition(schema_name,table_name,partition_columns,partition_values)

在指定的表中创建一个空分区。

  • system.sync_partition_metadata(schema_name,table_name,mode,case_sensitive)

检查并更新Metastore中的分区列表。共有三种模式可供选择:

  1. ADD:添加文件系统上存在但不在Metastore中的任何分区。
  2. DROP:删除Metastore中存在但不在文件系统中的任何分区。
  3. FULL:执行ADD和DROP。

case_sensitive参数是可选。默认值是true为了与Hive的行为兼容,它期望文件系统路径中的分区列名称使用小写(例如)。文件系统上不符合此约定的分区将被忽略,除非参数设置为。MSCKREPAIRTABLEcol_x=SomeValuefalse

8 额外的隐藏列

Hive连接器在Hive表中公开额外的隐藏元数据列。您可以像表的任何其他列一样将这些列作为SQL查询的一部分进行查询。

  • $path:给定行数据的文件路径
  • $file_size:给定行的文件大小
  • $file_modified_time:给定行的最后文件修改时间

9 例子

Hive连接器支持查询和操作Hive表和架构(数据库)。虽然一些不常见的操作需要直接使用Hive执行,但大多数操作都可以使用Presto执行。

创建一个名为的新Hive架构web,将表存储在名为的S3存储桶中my-bucket:

CREATESCHEMAhive.web
WITH(location='s3://my-bucket/')

创建一个以模式命名的新Hive表page_views,该表web使用ORC文件格式存储,按日期和国家/地区分区,并由用户分50桶到桶中(请注意,Hive要求分区列是表中的最后一列):

CREATETABLEhive.web.page_views(
view_timetimestamp,
user_idbigint,
page_urlvarchar,
dsdate,
countryvarchar
)
WITH(
format='ORC',
partitioned_by=ARRAY['ds','country'],
bucketed_by=ARRAY['user_id'],
bucket_count=50
)

从page_views表中删除一个分区:

DELETEFROMhive.web.page_views
WHEREds=DATE'2016-08-09'
ANDcountry='US'

向page_views表中添加一个空分区:

CALLsystem.create_empty_partition(
schema_name=>'web',
table_name=>'page_views',
partition_columns=>ARRAY['ds','country'],
partition_values=>ARRAY['2016-08-09','US']);

查询page_views表:

SELECT*FROMhive.web.page_views

列出表的分区page_views:

SELECT*FROMhive.web."page_views$partitions"

创建一个名为request_logs指向S3中现有数据的外部Hive表:

CREATETABLEhive.web.request_logs(
request_timetimestamp,
urlvarchar,
ipvarchar,
user_agentvarchar
)
WITH(
format='TEXTFILE',
external_location='s3://my-bucket/data/logs/'
)

删除外部表request_logs。这只会删除表的元数据。引用的数据目录不会被删除:

DROPTABLEhive.web.request_logs

删除架构:

DROPSCHEMAhive.web