Impala 与Amazon S3对象结合使用


您可以使用Impala查询驻留在AmazonS3对象存储上的数据。此功能允许方便地访问远程管理、可从任何地方访问并与各种基于云的服务集成的存储系统。Impala可以从S3查询任何支持的文件格式的文件。S3存储位置可以是整个表,也可以是分区表中的单个分区。

将Impala与S3结合使用的最佳实践

以下指南总结了本主题其余部分中描述的最佳实践:

  • 当S3未被指定为默认存储时,对S3位置的任何引用都必须是完全限定的,例如,s3a:://[s3-bucket-name]
  • fs.s3a.connection.maximum对于impalad设置为1500。

fs.s3a.block.size如果Impala查询的大多数Parquet文件是由Hive或ParquetMR作业写入的,则设置为134217728(128MB字节)。

如果Impala查询的大多数Parquet文件是由Impala写入的,请将块大小设置为268435456(256MB字节)。

  • 从Impala3.4.0开始fs.s3a.block.sizePARQUET_OBJECT_STORE_SPLIT_SIZE查询选项控制Parquet特定的拆分大小,而不是。默认值为256MB。
  • DROPTABLE..PURGE比默认的快得多DROPTABLE。这同样适用于ALTERTABLE...DROPPARTITIONPURGE与默认DROPPARTITION操作。由于S3的最终一致性特性,该表或分区的文件在使用PURGE.默认DROPTABLE/PARTITION是慢的,因为Impala将文件复制到S3A垃圾文件夹,并且Impala等待直到所有数据移动。DROPTABLE/PARTITION..PURGE是一个快速删除操作,即使更改可能没有在整个S3中完全传播,Impala语句也会快速完成。
  • INSERT语句比INSERTOVERWRITES3更快。默认情况下S3_SKIP_INSERT_STAGING设置为的查询选项true跳过常规INSERT(但不是INSERTOVERWRITE)的暂存步骤。这使得操作更快,但不能保证一致性:如果节点在执行过程中失败,表可能会以不一致的数据结束。false如果需要更强的一致性,请将此选项设置为,但是,此设置会使INSERT操作变慢。
    • 对于帕拉-ACID表,既INSERTINSERTOVERWRITE表格提供了S3的速度快,无论设置的S3_SKIP_INSERT_STAGING。另外,ACID表保证了一致性。
  • 为远程读取启用数据缓存。
  • 在您的集群中启用S3Guard以实现数据一致性。
  • 表中的文件过多会使S3中的元数据加载和更新速度变慢。如果向S3发出过多请求,S3具有回退机制并且响应速度比平时慢。
    • 如果由于过度粒度分区而有许多小文件,请配置具有多兆字节数据的分区,以便即使是针对单个分区的查询也可以有效地并行化。
    • 如果因为很多小INSERT查询而有很多小文件,请使用bulk,INSERT以便将更多数据写入更少的文件。

ImpalaSQL语句如何与S3配合使用

ImpalaSQL语句处理S3中的数据,如下所示:

  • 在CREATETABLE或ALTERTABLE语句可以指定一个表驻留在S3对象存储通过编码s3a://为前缀LOCATION属性。ALTERTABLE还可以为LOCATION单个分区设置属性,以便表中的某些数据驻留在S3中,而同一个表中的其他数据驻留在HDFS上。
  • 一旦将表或分区指定为驻留在S3中,SELECT语句语句将透明地访问来自适当存储层的数据文件。
  • 如果S3表是内部表,则在删除该表时,DROPTABLE语句会从S3中删除相应的数据文件。
  • 该TRUNCATETABLE表时被截断的语句总是从S3中删除相应的数据文件。
  • 在LOADDATA语句可以将驻留在HDFS的数据文件到S3表。
  • INSERT语句,或CREATETABLEASSELECT所述的形式CREATETABLE的语句,可以从HDFS表或另一个S3表将数据复制到一个S3表。该S3_SKIP_INSERT_STAGING查询选项可以选择是否在陈述过程中出现故障的情况下,使用快速代码路径,这些写入操作S3,与潜在矛盾的折衷。

指定Impala Credentials以访问S3中的数据

要允许Impala访问S3中的数据,请在core-site.xml文件中为以下配置设置指定值:

<property>
<name>fs.s3a.access.key</name>
<value>your_access_key</value>
</property>
<property>
<name>fs.s3a.secret.key</name>
<value>your_secret_key</value>
</property>

指定凭据后,重新启动Impala和Hive服务。需要重新启动Hive,因为Impala语句(例如)CREATETABLE通过HiveMetastore。

重要的:尽管您可以将访问密钥ID和秘密密钥指定为属性中s3a://URL的一部分,但LOCATION这样做会使此敏感信息在许多地方可见,例如DESCRIBEFORMATTED输出和Impala日志文件。因此,请在core-site.xml文件中集中指定此信息,并将对该文件的读取访问权限限制为仅受信任的用户。

将数据加载到S3以进行Impala查询

如果您的ETL管道涉及将数据移动到S3,然后通过Impala查询,您可以使用ImpalaDML语句来创建、移动或复制数据,或者使用与非Impala数据相同的数据加载技术。

对S3数据使用ImpalaDML语句

ImpalaDML语句(INSERTLOADDATACREATETABLEASSELECT)可以将数据写入驻留在S3中的表或分区。DML语句的语法与任何其他表的语法相同,因为表和分区的S3位置由or语句s3a://LOCATION属性中的前缀指定。如果您使用正常的S3传输机制而不是ImpalaDML语句将数据带入S3,请在使用Impala查询S3数据之前为表发出一条语句。CREATETABLEALTERTABLEREFRESH

由于S3和传统文件系统之间的差异,S3表的DML操作可能比HDFS上的表花费更长的时间。例如,无论是LOADDATA陈述和的最后阶段INSERT,并CREATETABLEASSELECT陈述涉及从一个目录移动到另一个文件。(在的情况下INSERTCREATETABLEASSELECT,文件被从临时分段目录移动到最终目标目录)。因为S3不支持“重命名”操作的现有对象,在这些情况下帕拉数据文件实际副本从一个位置到另一个然后删除原始文件。在Impala2.6中,S3_SKIP_INSERT_STAGING查询选项提供了一种加快INSERTS3表和分区语句的方法,但要权衡语句执行期间的问题可能会使数据处于不一致状态。它不适用于INSERTOVERWRITELOADDATA声明。

在S3中手动将数据加载到Impala表中

作为替代方案,或者在不支持S3的DML的早期Impala版本中,您可以使用Amazon提供的方法将数据文件导入S3,以便通过Impala进行查询。

重要的:

为了与Impala2.6及更高版本中的S3写入支持实现最佳兼容性:

  • 使用原生Hadoop技术在S3中创建数据文件,以便通过Impala进行查询。
  • 使用when删除内部(托管)表的PURGE子句DROPTABLE

默认情况下,当您删除内部(托管)表时,数据文件将移动到HDFS垃圾桶。对于驻留在AmazonS3对象存储上的表,此操作的开销很大。因此,对于S3表,更喜欢使用而不是default语句。该子句使Impala立即删除数据文件,跳过HDFS垃圾箱。为了使该子句有效地工作,您最初必须使用Hadoop生态系统中的工具之一在S3上创建数据文件,例如,或者在Impala或Hive中。DROPTABLEtable_namePURGEDROPTABLEPURGEPURGEhadoopfs-cpINSERT

在您将数据文件上传到已映射到Impala表或分区的位置后,或者如果您从该位置删除S3中的文件,请发出REFRESH语句以使Impala了解新的数据文件集。

为存储在S3中的数据创建Impala数据库、表和分区

要创建驻留在S3中的表,请运行带有子句的CREATETABLEorALTERTABLE语句LOCATION

ALTERTABLE可以LOCATION为单个分区设置属性,使一个表中的一些数据驻留在S3中,同一个表中的其他数据驻留在HDFS上。

LOCATION子句的语法是:

LOCATION 's3a://bucket_name/path/to/file'

文件系统前缀始终为s3a://.Impala不支持s3://ors3n://前缀。

对于分区表,要么LOCATION为每个新分区指定一个单独的子句,要么LOCATION为该表指定一个基,并在S3中设置目录结构以反映Impala分区表在S3中的结构方式。

您可以通过在S3中指定单个目录路径(可以是任意目录)来指向S3中的未分区表或单个分区。在S3中复制整个Impala分区表或数据库的结构需要更加小心,目录和子目录嵌套和命名以匹配HDFS中的等效目录树。如有必要,请考虑在HDFS中设置一个空的暂存区,并记录完整的目录结构,以便您可以在S3中复制它。

当处理多个表的数据文件存储在S3中时,您可以创建一个具有LOCATION指向S3路径的属性的数据库。为数据库的属性指定表单的URL。在该数据库内创建的任何表都会自动在数据库属性指定的目录下创建目录。s3a://bucket/root/path/for/databaseLOCATIONLOCATION

以下示例创建一个表,其中2017年的一个分区驻留在HDFS上,而2018年的一个分区驻留在S3中。

2018年的分区包含一个LOCATION带有s3a://URL的属性,因此指的是驻留在S3中的数据,位于存储桶下方的特定路径下impala-demo

CREATE TABLE mostly_on_hdfs (x int) PARTITIONED BY (year INT);
ALTER TABLE mostly_on_hdfs ADD PARTITION (year=2017);
ALTER TABLE mostly_on_hdfs ADD PARTITION (year=2018) 
   LOCATION 's3a://impala-demo/dir1/dir2/dir3/t1';

以下会话创建一个数据库和两个完全驻留在S3中的分区表,一个由单个列分区,另一个由多个列分区。

  • 由于为数据库指定了LOCATION带有s3a://URL的属性,因此该数据库中的表会在S3中的数据库目录下自动创建。
  • 要查看关联子目录的名称(包括分区键值),请使用S3客户端工具检查S3中目录结构的组织方式。
CREATE DATABASE db_on_s3 LOCATION 's3a://impala-demo/dir1/dir2/dir3';
CREATE TABLE partitioned_multiple_keys (x INT)
   PARTITIONED BY (year SMALLINT, month TINYINT, day TINYINT);
ALTER TABLE partitioned_multiple_keys
   ADD PARTITION (year=2015,month=1,day=1);
ALTER TABLE partitioned_multiple_keys
   ADD PARTITION (year=2015,month=1,day=31);
!hdfs dfs -ls -R s3a://impala-demo/dir1/dir2/dir3
2015-03-17 13:56:34          0 dir1/dir2/dir3/
2015-03-17 16:47:13          0 dir1/dir2/dir3/partitioned_multiple_keys/
2015-03-17 16:47:44          0 dir1/dir2/dir3/partitioned_multiple_keys/year=2015/month=1/day=1/
2015-03-17 16:47:50          0 dir1/dir2/dir3/partitioned_multiple_keys/year=2015/month=1/day=31/

CREATEDATABASECREATETABLE,如果他们不存在语句创建相关的目录路径。您可以指定多个级别的目录,该CREATE语句会创建所有适当的级别,类似于使用mkdir-p.

使用标准的S3文件上传方法将实际数据文件放入正确的位置。您还可以在创建关联的Impala数据库或表之前放置目录路径和数据文件,并且在创建关联的数据库和表后,Impala会自动使用来自适当位置的数据。

使用ALTERTABLE带有LOCATION子句的语句来切换现有表或分区是指向HDFS还是S3中的数据。例如,如果您有一个Impala表或分区指向HDFSS3中的数据文件,并且您稍后将这些数据文件传输到其他文件系统,请使用该ALTERTABLE语句调整LOCATION相应表或分区的属性以反映该更改。

位于S3中的内部和外部表

与位于HDFS存储上的表一样,您可以分别使用语法CREATETABLEor将基于S3的表指定为内部(由Impala管理)或外部表CREATEEXTERNALTABLE

当您删除内部表时,与该表关联的文件将被删除,即使它们在S3存储中。当您删除外部表时,与该表关联的文件将单独保留,并且仍可供其他工具或组件访问。

如果S3中的数据旨在长期保存并由除Impala之外的其他工具访问,请使用CREATEEXTERNALTABLE语法创建任何关联的S3表,以便在删除表时不会从S3中删除文件。

如果S3中的数据仅用于Impala查询,并且在Impala工作流完成后可以安全丢弃,请使用该CREATETABLE语法创建关联的S3表,这样删除表也会删除S3中的相应数据文件。

为存储在S3中的数据运行和调整Impala查询

一旦将表或分区指定为驻留在S3中,该SELECT语句就会透明地访问来自适当存储层的数据文件。

  • 针对S3数据的查询支持与HDFS数据相同的所有文件格式。
  • 表可以是未分区的或分区的。对于分区表,要么在S3中手动构建对应于表示分区键值的HDFS目录的路径,要么用于在S3ALTERTABLE...ADDPARTITION中设置适当的路径。
  • HDFSHBase表可以连接到S3表,或者S3表可以相互连接。
  • 无论数据是在HDFS中还是在S3中,控制对数据库、表或列的访问的授权都是一样的。
  • 目录服务器(catalogd)守护进程缓存HDFSS3表的元数据。
  • 针对S3表的查询受制于与HDFS表相同类型的准入控制和资源管理。
  • S3表的元数据存储在与HDFS表相同的Metastore数据库中。
  • 您可以设置引用S3表的视图,与HDFS表相同。
  • COMPUTESTATSSHOWTABLESTATSSHOWCOLUMNSTATS报表S3表工作。

了解和调整S3数据的Impala查询性能

以下是可用于解释针对S3数据的查询的解释计划和配置文件的技术,以及为此类查询实现最佳性能的技巧。

在其他条件相同的情况下,针对S3而非HDFS中的数据运行的查询的性能预计会更低。SELECT当数据在S3中时,语句的实际机制有些不同。尽管工作仍然分布在集群的DataNode上,但Impala可能会以不同的方式并行分布式查询的工作,以处理HDFSS3上的数据。

S3没有与HDFS相同的块概念,因此Impala使用启发式方法来确定如何拆分大型S3文件以进行并行处理。因为所有主机都可以以相同的效率访问任何S3数据文件,所以工作分配可能与HDFS数据不同,HDFS数据是由包含适当块副本的主机使用短路本地读取来物理读取数据块的。尽管读取S3数据的I/O可能均匀分布在集群的主机上,但最初通过网络检索所有数据这一事实意味着S3数据的整体查询性能可能低于HDFS数据.

使用PARQUET_OBJECT_STORE_SPLIT_SIZE查询选项来控制Parquet特定的分割大小。默认值为256MB

在优化复杂查询的方面(例如连接顺序)时,Impala以相同的方式处理HDFSS3上的表。因此,对S3表和HDFS表遵循所有相同的调整建议,例如使用COMPUTESTATS语句来帮助Impala构建行计数和基数的准确估计。

在查询配置文件报告BytesReadLocalBytesReadShortCircuitBytesReadDataNodeCached、和的数字为BytesReadRemoteUnexpected空,因为这些指标来自HDFS。根据定义,S3表的所有I/O都涉及远程读取。

Impala支持S3的限制

ImpalaS3结合使用时适用以下限制:

  • Impala不支持旧s3://的基于块和s3n://文件系统的方案,它只支持s3a://.
  • 尽管S3通常用于存储JSON格式的数据,但当前ImpalaS3的支持不包括直接查询JSON数据。如果您有JSON格式的数据,您可以准备该数据的扁平版本,作为ETL周期的一部分供Impala查询。
  • 您不能将该ALTERTABLE...SETCACHED语句用于位于S3中的表或分区。