更新时间:2024-11-26 GMT+08:00
分享

配置Hive自读自写SQL防御规则

操作场景

Hive支持对自读自写的SQL语句进行拦截。如果一条SQL语句中查询的表、分区或目录与插入的表、分区或目录一致,且以覆盖的方式插入查询的结果数据,便可判定存在自读自写的场景,用户可以在SQL防御界面通过添加规则ID为“dynamic_0004”的防御规则开启该拦截功能。

该章节仅适用于MRS 3.5.0及之后版本。

Hive自读自写的SQL样例如下:

  • 非分区表:

    INSERT OVERWRITE TABLE tbl_a SELECT * FROM tbl_a;

  • 静态分区表:

    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;

操作步骤

  1. 使用具有Manager界面管理权限的用户登录FusionInsight Manager。
  2. 选择“集群 > SQL防御”,单击“添加规则”,输入当前用户密码并单击“确定”,进入添加规则界面。
  3. 在添加规则界面配置以下参数并单击“确定”:

    • 规则名称:输入SQL防御规则名称,例如:test。
    • 规则ID:选择“dynamic_0004”。
    • 租户:单击“添加”选择可适用当前防御规则的租户名称,例如:default。
    • 服务与动作:单击“添加”,在添加服务与动作页面配置以下参数并单击“确定”:
      • 服务:选择“Hive”。
      • 根据业务实际需求开启“提示”或“拦截”按钮。
    图1 创建Hive SQL防御规则

  4. 登录安装有Hive客户端的节点,执行以下命令,切换到客户端安装目录。

    cd /opt/client

    执行以下命令,配置环境变量。

    source bigdata_env

    执行以下命令认证当前用户(若集群未启用Kerberos认证(普通模式)请跳过该操作):

    kinit 具有Hive操作权限的组件业务用户

  5. 执行以下命令登录Hive客户端:

    beeline

  6. 执行以下命令创建一个表并插入数据:

    drop table tbl_a;

    create table tbl_a(id int, name string);

    insert into table tbl_a values(123,'sjk'),(234,'shen'),(111,'aaa');

  7. (可选)在SQL防御中配置了自读自写拦截规则后,对于涉及动态分区场景默认情况下是按照nonstrict模式拦截的,如果需要按照分区精准拦截,可执行以下命令进行设置,参数介绍请参见设置Hive动态分区表精准拦截

    set hive-ext.dynamic.partition.intercept.mode=strict;

  8. 执行以下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;,不建议全局配置。

表1 参数说明

参数名称

默认值

参数描述

hive-ext.dynamic.partition.intercept.mode

nonstrict

设置Hive动态分区表自读自写的拦截方式,包括:

  • nonstrict:按照表进行拦截,即一条SQL语句中查询的表和插入的表数据存在相同的表便会被拦截。
  • strict:按照分区拦截,即一条SQL语句中查询的分区和插入的分区数据存在相同的分区便会被拦截。

相关文档