
# 配置HBase慢查询语句查杀功能
#### 操作场景
为了提升HBase组件的集群可靠性及易运维性，便于运维人员可以快速发现存在问题的查询请求并支持选择性手动终止，HBase提供了对慢查询语句的查看、查杀、主动识别和主动拦截能力。
为了保证集群功能的兼容性，慢查询查杀功能默认关闭，需要通过修改参数"hbase.slow.query.check.enabled"的值为"true"开启。
#### 约束与限制
该章节操作仅适用于MRS 3.6.0-LTS.1及之后版本。
#### 配置HBase慢查询语句查杀功能
1. 登录Manager界面，选择"集群 \> 服务 \> HBase \> 配置"。 
   登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
   
   
2. 搜索"hbase.slow.query.check.enabled"参数，并修改参数值为"true"开启HBase慢查询查杀功能。
3. 登录HBase客户端。 
   1. 登录安装HBase客户端的节点，并切换至客户端安装目录：
      ```
      cd 客户端安装目录
      ```
      
   
   2. 配置环境变量：
      ```
      source bigdata_env
      ```
      
   
   3. 认证用户，集群未启用Kerberos认证（普通模式）请跳过该操作：
      ```
      kinit 组件业务用户
      ```
      其中：
      - HBase未启用Ranger鉴权，即使用ACL鉴权，该业务用户所绑定的HBase角色需具有"global"资源的"管理"权限，即创建HBase角色时，"配置资源权限"需选择"集群 \> HBase \> HBase Scope"，勾选"global"所在行的"管理"权限。
      
      - HBase已启用Ranger鉴权，则需要在Ranger策略配置界面，修改HBase默认策略"all - table, column-family, column"，在"Allow Conditions"区域新增策略允许条件，并在"Select User"列选择该业务用户，例如"admintest"，"Permissions"列添加"Admin"权限。
       
   
   4. 登录HBase客户端：
      ```
      hbase shell
      ```
      
   
   
   
   
4. 配置慢查询阈值。 
   - 全局参数配置 在HBase参数配置页面，搜索"hbase.slow.query.check.threshold"参数，设置慢查询的阈值，即scan查询持续的时间超过该阈值就会被定义为慢查询。参数的取值范围为1000\~2147483647，单位为毫秒。
     
   
   - 表级别参数配置（优先级高于集群参数配置） 也可以在hbase shell命令行中，执行以下命令设置指定表的慢查询阈值：
     ```
     alter '表名', CONFIGURATION => {'hbase.slow.query.check.threshold' => 阈值}
     ```
     
   
   
   **建议该阈值不要配置过低，否则会因为将大量请求都识别为慢查询影响服务的性能。**
   
   
5. 开启慢查询事前拦截。 
   - 拦截一
     - 全局参数配置
       1. 在HBase参数配置页面，搜索"hbase.multi.region.scan.enabled"参数，修改参数值为"false"，关闭跨Region的scan查询。 可用于拦截跨单Region的查询请求，即关闭跨Region的查询后，默认拦截所有的跨单Region区间的scan请求。
          
       
       2. 搜索"hbase.region.scan.limit.threshold"参数，配置scan查询允许扫描的数据条数，且只有未超过该参数配置的阈值的scan查询才允许被执行。
        
     
     - 表级别参数配置（优先级高于集群参数配置）
       也可以在hbase shell命令行中，执行以下命令配置指定表关闭跨Region的scan查询及配置查询阈值：
       ```
       alter '表名', CONFIGURATION => {'hbase.multi.region.scan.enabled' => false, 'hbase.region.scan.limit.threshold' => 阈值}
       ```
       
      
   
   - 拦截二 如果scan查询未设置caching参数或者超过阈值，表示该查询每次请求缓存的数据条数过多，该查询请求将被拦截。
     可通过在HBase参数配置页面调整"hbase.client.scanner.caching.max"参数值，避免拦截单次缓存大量数据的查询请求，或将该参数值设置为"2147483647"关闭拦截。
     也可以在hbase shell命令行中，执行以下命令对指定表进行配置：
     ```
     alter '表名', CONFIGURATION => {'hbase.client.scanner.caching.max' => 阈值}
     ```
     
   
   
   
   
6. 开启慢查询事中拦截。 
   - 全局参数配置
     1. 在HBase参数配置页面，搜索"hbase.regionserver.scan.block.size.threshold"参数，用于检测并限制scan查询每次从服务端扫描的数据大小（包括未命中查询条件的数据），当超过该阈值时，查询请求将被中止。
     
     2. 搜索"hbase.regionserver.scan.response.size.threshold"参数，用于检测并限制scan查询每次从服务端缓存的数据数据大小（仅包括命中查询条件的数据），当超过该阈值时，查询请求将被中止。
      
   
   - 表级别参数配置（优先级高于集群参数配置） 也可以在hbase shell命令行中，执行以下命令配置指定表的对应阈值：
     ```
     alter '表名', CONFIGURATION => {'hbase.regionserver.scan.block.size.threshold' => 阈值, 'hbase.regionserver.scan.response.size.threshold' => 阈值}
     ```
     
   
   
   更多HBase慢查询相关参数介绍请参见[表1]。
   
   
7. 在HBase参数配置页面修改参数值后，单击"保存"保存配置。 
   还需在hbase shell命令行执行以下命令，配置即可在服务端动态生效：
   ```
   update_all_config
   ```
   
   
 
#### HBase慢查询接口使用说明
- 查看慢查询
  - HBase Shell命令
    ```
    get_slow_query
    ```
    该命令支持查看当前所有的慢查询，包括指定表的慢查询和指定来自指定客户端IP的慢查询。可以在**hbase shell**执行以下操作获取命令帮助：
    ```
    help 'get_slow_query'
    ```
    图1查看HBase慢查询   
    ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000002530959794.png "点击放大") 
  
  - API接口 可参考如下代码片段：
    如果集群已启用Kerberos认证（安全模式），请先配置安全认证，具体操作请参见[HBase数据读写示例安全认证（单集群场景）](https://support.huaweicloud.com/devg-lts-mrs/mrs_07_080009.html)。
    ```
    /**
    * 查看慢查询记录
    * @param admin
    */
    private static void getSlowQuery(Admin admin) throws IOException {
    // 获取当前所有的慢查询记录
    List<SlowQueryInfo> slowQueryList = admin.getSlowQuery();
    slowQueryList.forEach(slowQueryInfo -> printSlowQueryInfo(slowQueryInfo));
    // 获取来自指定客户端IP的慢查询记录
    slowQueryList = admin.getSlowQueryByClientIp(Arrays.asList("ip1", "ip2"));
    // 获取指定表的慢查询记录
    slowQueryList = admin.getSlowQueryByTable(Arrays.asList("table1", "table2"));
    }
    private static void printSlowQueryInfo(SlowQueryInfo slowQueryInfo) {
    // 获取QueryID
    long queryId = slowQueryInfo.getQueryId();
    // 获取客户端IP
    String clientIp = slowQueryInfo.getClientIp();
    // 获取表名
    String tableName = slowQueryInfo.getTableName();
    // 获取查询开始的时间戳
    long starTime = slowQueryInfo.getStartTime();
    // 获取查询的详细信息
    String scanDetail = slowQueryInfo.getQueryDetails();
    // 打印慢查询信息
    System.out.println(slowQueryInfo);
    }
    ```
    
   
- 终止慢查询
  - HBase Shell命令
    ```
    abort_slow_query
    ```
    该命令支持终止指定QueryID的慢查询，如果需要同时终止多个，可以同时指定多个QueryID，中间使用逗号分隔。可以在**hbase shell**执行以下操作获取命令帮助：
    ```
    help 'abort_slow_query'
    ```
    图2终止HBase慢查询   
    ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000002552512801.png "点击放大") 
  
  - API接口 可参考如下代码片段：
    如果集群已启用Kerberos认证（安全模式），请先配置安全认证，具体操作请参见[HBase数据读写示例安全认证（单集群场景）](https://support.huaweicloud.com/devg-lts-mrs/mrs_07_080009.html)。
    ```
    /**
    * 终止慢查询
    * @param admin
    */
    private static void abortSlowQuery(Admin admin) throws IOException {
    // 指定待终止的QueryID
    List<Long> queryIds = new ArrayList<>();
    queryIds.add(123456789L);
    queryIds.add(987654321L);
    // 终止指定的一个或多个慢查询
    AbortSlowQueryResponse response = admin.abortSlowQueries(queryIds);
    // 未知的慢查询，有可能在发起abort慢查询时，该QueryID对应的查询请求已结束
    AbortSlowQueryResponse.ResultGroup unknownItems = response.getUnknownItems();
    if(unknownItems != null) {
    List<Long> unknownQueryIds = unknownItems.getQueryIds();
    unknownQueryIds.forEach(id -> {
    System.out.println("unknown: " + id);
    // 移除未知的QueryID
    queryIds.removeIf(id::equals);
    });
    }
    // 因为异常原因导致终止失败的慢查询
    AbortSlowQueryResponse.ResultGroup failedItems = response.getFailedItems();
    if(failedItems != null) {
    List<Long> failedQueryIds = failedItems.getQueryIds();
    failedQueryIds.forEach(id -> {
    System.out.println("failed: " + id);
    // 移除未知的QueryID
    queryIds.removeIf(id::equals);
    });
    }
    // 移除未知和终止失败的QueryID，剩下的则为成功的QueryID
    queryIds.forEach(id -> System.out.println("success: " + id));
    }
    ```
    
   
 
#### HBase慢查询参数介绍
 表1慢查询参数介绍 
| **参数名称**                                        | **参数说明**                                                                                                                                                                   | **默认值** | **取值范围**                                                                                                                                                                                                                                                                                                                                                                        | **是否支持表级别配置** |
|:---|:---|:---|:---|:---|
| hbase.slow.query.check.enabled                  | 启用/禁用HBase慢查询查杀功能。                                                                                                                                                         | false   | - true：启用HBase慢查询查杀功能。  - false：禁用HBase慢查询查杀功能。             | 否             |
| hbase.slow.query.check.threshold                | 当启用HBase慢查询查杀功能后，scan查询执行时间超过该参数配置的阈值将被识别为慢查询，单位为毫秒。 过小的阈值会导致大量的请求被识别为慢请求，影响服务的性能。                            | 10000   | 1000\~ 2147483647                                                                                                                                                                                                                                                                                                                                                               | 是             |
| hbase.query.intercept.enabled                   | 用于启用或禁用慢查询拦截功能，当启用时，RegionServer会拦截查询，否则只打印日志信息。                                                                                                                           | false   | - true：启用慢查询拦截功能。  - false：禁用慢查询拦截功能。                     | 否             |
| hbase.multi.region.scan.enabled                 | 启用/禁用跨Region的scan查询拦截。 **注意：如果将该参数值修改为** **"false"，所有未设置或者设置的limit超过阈值的跨Region scan都会被拦截，请谨慎评估影响或仅单表进行配置。** | true    | - true：启用跨Region的scan查询拦截。  - false：禁用跨Region的scan查询拦截。   | 是             |
| hbase.region.scan.limit.threshold               | 当禁用跨Region的scan查询拦截时，只有scan查询设置了limit限制返回的数据条数且不超过该参数设置的阈值时才会被允许执行，否则该请求将被拦截。                                                                                              | -1      | -1\~2147483647                                                                                                                                                                                                                                                                                                                                                                  | 是             |
| hbase.regionserver.scan.block.size.threshold    | 检测并限制scan查询每次从服务端扫描的数据大小（包括未命中查询条件的数据），当超过该阈值时，查询请求将被中止。单位为Byte。 值为"-1"时关闭该检查。                                 | -1      | -1\~ 9223372036854775807                                                                                                                                                                                                                                                                                                                                                        | 是             |
| hbase.regionserver.scan.response.size.threshold | 检测并限制scan查询每次从服务端扫描的数据大小（包括未命中查询条件的数据），当超过该阈值时，查询请求将被中止。单位为Byte。 值为"-1"时关闭该检查。                               | -1      | -1\~ 9223372036854775807                                                                                                                                                                                                                                                                                                                                                        | 是             |
| hbase.client.scanner.caching.max                | 如果scan的caching参数的值超过该阈值时，该请求将被拦截。 默认值为空或者"2147483647"时关闭该检查。                                                  | -       | 1\~2147483647                                                                                                                                                                                                                                                                                                                                                                   | 是             |
| hbase.slow.query.znode.limit                    | 用于限制HBase服务慢查询记录的数量，如果慢查询ZNode节点的数量超过该限制，新生成的慢查询记录将仅记录到日志。 **过多的慢查询记录会影响服务端的正常响应。**                            | 10000   | 1\~2147483647                                                                                                                                                                                                                                                                                                                                                                   | 否             |
| hbase.slow.query.znode.content.limit            | 单条慢查询记录的大小，单位为Byte。慢查询记录中包含了Filter的信息，如果查询条件中包含的Filter过多，会导致单条慢查询记录过大，占用过多的服务端资源。 当记录超过该大小时，会对Filter的信息进行裁剪。 | 10240   | 1024\~2097152                                                                                                                                                                                                                                                                                                                                                                   | 否             |
| hbase.slow.query.znode.cleaner.interval         | 检查残留慢查询记录的周期，单位为毫秒。定期检查是否存在残留的慢查询记录并进行清理。                                                                                                                                  | 300000  | 1\~2147483647                                                                                                                                                                                                                                                                                                                                                                   | 否             |
| hbase.slow.query.znode.ttl                      | 慢查询记录的保留时间，单位为毫秒。为了防止异常场景下的操作记录残留，会定期进行检查和清理。                                                                                                                              | 600000  | 1\~2147483647                                                                                                                                                                                                                                                                                                                                                                   | 否             |
   
