官方文档地址:https://www.cloudera.com/documentation/enterprise/5-15-x/topics/impala_sync_ddl.html
由于Impala的架构设计,每一个impalad(coordinator角色)都会缓存一份自己的元数据信息。因此,当我们通过一个impalad节点执行一个DDL操作(CREATE/ALTER TABLE),再立马连接至另一个impalad节点查询时,此时可能无法查到最新的修改。因为任何一个DDL操作所造成的元数据更改,都需要通过catalog服务来广播到集群中的每一个节点(执行DDL的节点除外,因为执行DDL返回之后,该节点上的元数据缓存已经是最新的了)。
当我们在通过同一个impalad节点上执行DDL和SELECT是没有这种问题。但是在实际生产环境中,我们往往通过load-balancing的模式,将请求发送到不同的impalad节点(例如通过写zk节点的方式)。这种情况下,DDL和SELECT操作就有可能落在两个不同的impalad上。此时就会存在一个同步元数据的时间延时,在这个延时区间内,部分impalad节点无法查询到最新的元数据信息(显示执行invalidate metadata table/refresh table可以立即刷新当前impalad的元数据缓存信息,但是对于用户来说十分不友好),虽然这个延时可能只有几秒钟。
所幸的是,Impala提供一个叫做SYNC_DDL的query option参数。设置该参数为true之后,每次执行DDL操作,catalog服务都会先将所有的元数据更改同步到每个impalad节点,然后执行结果才会返回到提交SQL的节点上,这种就类似同步操作。这样的话,通过impala-shell连接到不同的节点时,就可以立即获取最新的元数据信息。这个参数默认为FALSE,表示异步执行DDL操作。
虽然INSERT操作被定义为DML,当设置了SYNC_DDL为true之后,执行INSERT语句的结果,也会等到元数据更新同步到每个节点之后才会返回。本质上来说,Impala的insert语句和传统数据库的DDL操作存在着一定的相似性。对于Impala来说构造元数据信息需要记录HDFS上的block位置,对于分区表也需要做分区更新记录,而insert into/overwrite操作也会在HDFS上生成新的文件。
注意:SYNC_DDL参数在每一个操作完成之后都会产生一个延时区间。对于执行CREATE DATABASE, CREATE TABLE, ALTER TABLE, INSERT这样的一个SQL序列,或者是在脚本中执行类似的一系列SQL,那么可以在最后一个DDL语句执行完成之前,设置SYNC_DDL参数位true,这样可以在最小程度上较少这个时延。
参数类型:Boolean;1和0,或者true和false都可以识别,其他的任何值都会被当做false。
默认值:false
有三个地方可以配置该参数:
- 在impalad.conf中配置:-default_query_options=sync_ddl=true,这样配置之后,所有提交到该impalad上的SQL都会默认设置这个参数,此impalad节点需要为coordinator角色;
- 在acl文件llama-site.xml中配置队列级别的,配置如下参数:
<property>
<name>impala.admission-control.pool-default-query-options.root.queueA</name>
<value>sync_ddl=true</value>
</property>
此时,所有提交到该队列上的SQL都会配置这个参数;
- 在session中直接执行set sync_ddl=true,这个只对当前的会话有效,断开连接后失效。
以上三种方式的配置,优先级从低到高,可以根据实际需求进行相应的配置。
请注意,配置了该参数之后,DDL的执行时间会有一定的增加,所以请根据具体的业务场景判断是否需要开启该功能。