配置Hive自读自写SQL防御规则
操作场景
Hive支持对自读自写的SQL语句进行拦截。如果一条SQL语句中查询的表、分区或目录与插入的表、分区或目录一致,且以覆盖的方式插入查询的结果数据,便可判定存在自读自写的场景,用户可以在SQL防御界面通过添加规则ID为“dynamic_0004”的防御规则开启该拦截功能。
该章节仅适用于MRS 3.5.0及之后版本。
Hive自读自写的SQL样例如下:
- 非分区表:
- 静态分区表:
INSERT OVERWRITE TABLE tbl_b PARTITION (ds='20240101') SELECT * FROM tbl_b WHERE ds='20240101';
- 动态分区:
INSERT OVERWRITE TABLE tbl_c PARTITION(pday) SELECT id,name,pday FROM tbl_c WHERE id > 100;
- 写入数据到HDFS的表中:
INSERT OVERWRITE DIRECTORY 'hdfs://hacluster/user/hive/warehouse/tbl_d' SELECT * FROM tbl_d;
操作步骤
- 使用具有Manager界面管理权限的用户登录FusionInsight Manager。
- 选择“集群 > SQL防御”,单击“添加规则”,输入当前用户密码并单击“确定”,进入添加规则界面。
- 在添加规则界面配置以下参数并单击“确定”:
- 规则名称:输入SQL防御规则名称,例如:test。
- 规则ID:选择“dynamic_0004”。
- 租户:单击“添加”选择可适用当前防御规则的租户名称,例如:default。
- 服务与动作:单击“添加”,在添加服务与动作页面配置以下参数并单击“确定”:
- 服务:选择“Hive”。
- 根据业务实际需求开启“提示”或“拦截”按钮。
图1 创建Hive SQL防御规则
- 登录安装有Hive客户端的节点,执行以下命令,切换到客户端安装目录。
cd /opt/client
执行以下命令,配置环境变量。
source bigdata_env
执行以下命令认证当前用户(若集群未启用Kerberos认证(普通模式)请跳过该操作):
kinit 具有Hive操作权限的组件业务用户
- 执行以下命令登录Hive客户端:
beeline
- 执行以下命令创建一个表并插入数据:
drop table tbl_a;
create table tbl_a(id int, name string);
insert into table tbl_a values(123,'sjk'),(234,'shen'),(111,'aaa');
- (可选)在SQL防御中配置了自读自写拦截规则后,对于涉及动态分区场景默认情况下是按照nonstrict模式拦截的,如果需要按照分区精准拦截,可执行以下命令进行设置,参数介绍请参见设置Hive动态分区表精准拦截:
set hive-ext.dynamic.partition.intercept.mode=strict;
- 执行以下SQL语句命令,检查当前SQL防御规则是否生效。
insert overwrite table tbl_a select * from tbl_a;
若配置的动作为”提示”,当系统识别到SQL语句满足防御规则后,系统会打印告警信息,SQL任务继续运行,提示信息如下:
WARN : DYNAMIC_0004 Self-read and self-overwrite operations are not allowed.
若配置的动作为”拦截”,当系统识别到SQL语句满足防御规则后,SQL任务将被拦截,不会继续运行,系统回显信息如下:
Error: Error while compiling statement: FAILED: RuleException DYNAMIC_0004 Self-read and self-overwrite operations are not allowed. (state=42000,code=40000)
设置Hive动态分区表精准拦截
针对涉及动态分区的自读自写场景,由于动态分区在编译阶段获取不到输出的分区信息,无法判断是否存在自读自写场景,为了实现拦截功能,提供了nonstrict和strict两种拦截模式供用户选择。其中:
- nonstrict模式是按照表进行拦截的,即对提交的SQL任务判断是否存在查询的表和写入的表是同一张表,如果存在就进行拦截,否则不拦截。nonstrict模式的拦截逻辑是在SQL编译阶段完成的,该模式优点是拦截效率高,缺点是查询和写入分区所对应的表相同,分区不同时也会被拦截。
- strict模式是按照分区进行拦截的,即对提交的SQL任务判断是否存在查询的分区和写入的分区相同,如果存在就进行拦截,否则不拦截。strict模式的拦截逻辑是在SQL任务执行MoveTask阶段完成的,该模式优点是拦截精度高,缺点是拦截成本高,因为需要等到SQL任务大部分逻辑运行完且运行到MoveTask阶段才识别是否需要进行拦截。
在SQL防御中配置了自读自写拦截规则,对于涉及动态分区场景默认情况下是按照nonstrict模式拦截的,如果需要按照分区精准拦截,还需要将表1的“hive-ext.lakeformation.transform.role”参数的值设置为“strict”。该参数值建议对单个任务进行设置,例如执行SQL语句set hive-ext.dynamic.partition.intercept.mode=strict;,不建议全局配置。