Hbase限流 -- HBase Quota调研

news2025/1/16 1:13:46

1 背景

HBase的生产环境中,每个业务之间的重要性是不一致的,每个业务的数据量、读写需求也不一致,一个集群中往往有很多个业务,有的同学可以执行一个耗时的scan操作,整个集群的资源被大量占用,其它非常重要的业务就被挤压资源,造成一系列的事故。而当请求量异常大时,也会造成RegionServer不稳定。基于这些问题,hbase提出了Quotas,它可以限制namespace,user,table这些级别,涉及read/write以及storage的限制,包括限制单位时间的条数、size以及表或者namesapce的存储等。

本文重点介绍HBase中的资源限制方案Quotas,主要对其使用方式、实现原理进行介绍,对hbase1.2版本的限流和2.1版本的限流进行比较,最后指出当前hbase quota存在的问题。

2 使用方式介绍

2.1 Quotas的启用

Quotas默认是关闭的,如果需要使用时,只需要在hbase-site.xml配置中增加hbase.quota.enabled=true即可,相关的配置如下:

<property>

    <name>hbase.quota.enabled</name>

    <value>true</value>

</property>

<property>

    <name>hbase.quota.rate.limiter</name>

    <value>org.apache.hadoop.hbase.quotas.AverageIntervalRateLimiter</value>

</property>

2.2 Quota语法

  • Quota主要针对用户、namespace以及表的QPS和请求大小进行限制;
  • THROTTLE_TYPE可以取值read、write或者read+write(默认)
  • 时间单位可以是:sec、min、hour、day
  • size限制单位表示:B(字节)、K(千字节)、M(兆字节)、G(千兆字节)、T(兆兆字节)、P(PB级);
  • 请求数的限制表示为整数,后跟字符串 req、req/time 或者 size/time,例如:10req/day或者100P/hour;
  • table或namespace的数量表示为整数,比如一个namespace限制创建多少张表;

配置的维度

Limit限制的类型

请求Size还是请求的次数

单位时间

NAMESPACE

USER

TABLE

USER+NAMESPACE

USER+TABLE

READ

WRITE

READ+WRITE

请求次数:req

请求Size:bkmgtp

sec, min, hour, day

2.3 Setting Request Quotas

你可以事先设置quota,也可以在运行时修改阈值。默认修改后5分钟生效。该时间可以通过hbase-site.xml中的hbase.quota.refresh.period配置项进行修改,该配置项的单位是毫秒。

设置quota的示例:

#将用户u1限制为每秒10个请求

hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10req/sec' 

#将用户u1限制为每秒10个读取请求

hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', LIMIT => '10req/sec' 

#将用户u1限制为每天10 M

hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10M/day' 

#将用户u1限制为每秒10 M写入大小

hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => WRITE, USER => 'u1', LIMIT => '10M/sec' 

# 将用户u1限制为每分钟5k在表t2

hbase> set_quota TYPE => THROTTLE, USER => 'u1', TABLE => 't2', LIMIT => '5K/min' 

#在表t2上将用户u1限制为每秒10次读取请求

hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', TABLE => 't2', LIMIT => '10req/sec' 

# 在用户名u1上删除用户u1的现有限制ns2

hbase> set_quota TYPE => THROTTLE, USER => 'u1', NAMESPACE => 'ns2', LIMIT => NONE 

#限制所有用户在命名空间ns1上每小时发出10个请求

hbase> set_quota TYPE => THROTTLE, NAMESPACE => 'ns1', LIMIT => '10req/hour' 

# 在表t1 上将所有用户限制为每小时10T

hbase> set_quota TYPE => THROTTLE, TABLE => 't1', LIMIT => '10T/hour' 

#从用户u1中删除所有现有限制

hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => NONE 

#列出命名空间ns2中用户u1的所有

quotahbase> list_quotas USER => 'u1, NAMESPACE => 'ns2' 

#列出名称空间ns2的所有quota

hbase> list_quotas NAMESPACE => 'ns2' 

#列出表t1的所有quotas

hbase> list_quotas TABLE => 't1' 

# list all quotas

hbase> list_quotas

可以通过应用GLOBAL_BYPASS属性来设置全局限制并从限制中排除用户或表

#列出命名空间ns1的限制

hbase> set_quota NAMESPACE => 'ns1', LIMIT => '100req/min'

#用户u1不受限制               

hbase> set_quota USER => 'u1', GLOBAL_BYPASS => true                    

2.4 Limiting Tables Per Namespace

# 创建一个最多包含5个表的命名空间

hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxtables'=>'5'} 

# 更改现有命名空间,最多包含8个表

hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxtables'=>'8'} 

# 显示命名空间的quota信息

hbase> describe_namespace 'ns2' 

# 更改现有命名空间以删除quota

hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=>'hbase.namespace.quota.maxtables'}

2.5 Limiting Regions Per Namespace

# 创建一个最多包含10个region的命名空间

hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxregions'=>'10' 

# 显示命名空间hbase的quota信息

hbase> describe_namespace 'ns1' 

# 更改现有命名空间最多有20个表

hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxregions'=>'20'} 

# 更改现有命名空间以删除quota

hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=> 'hbase.namespace.quota.maxregions'}

2.6 Space Quotas(HBase2.X)

HBASE-16961引入了一种新的HBase Quotas来利用:filesystem quotas。这些'space'qutas能限制namespace和table的size大小。如果不加限制的话,用户可以无限制的往表中写数据,极端的情况是,大量的数据写入,造成没有空间可以,hbase无法预写日志或者同步数据。

可以通过set_quota和list_quota的HBase shell命令设置空间配额。空间配额的TYPE是SPACE,并且具有LIMIT和POLICY两个属性。LIMIT是一个字符串,指的是表或命名空间最大占用的空间量。例如有效的LIMIT可以是'10G','2T',或'256M'。POLICY指当配额对象的使用量超过配额时,HBase采取的行动,具体包括以下几种:

POLICY

含义

NO_INSERTS

No new data may be written (e.g. Put, Increment, Append)

NO_WRITES

Same as NO_INSERTS but Deletes are also disallowed

NO_WRITES_COMPACTIONS

Same as NO_WRITES but compactions are also disallowed

This policy only prevents user-submitted compactions. System can still run compactions

DISABLE

The table(s) are disabled, preventing all read/write access

Space quota的例子:

# 在表't1'上限制最大1GB, 超过时禁止Puts/Increments/Appends

hbase> set_quota TYPE => SPACE, TABLE => 't1', LIMIT => '1G', POLICY => NO_INSERTS 

# 在'ns1'上限制最大50TB, 超过时禁止Puts/Increments/Appends/Deletes

hbase> set_quota TYPE => SPACE, NAMESPACE => 'ns1', LIMIT => '50T', POLICY => NO_WRITES 

# 在表't3'上限制最大2TB, 超过时禁止writes and compactions

hbase> set_quota TYPE => SPACE, TABLE => 't3', LIMIT => '2T', POLICY => NO_WRITES_COMPACTIONS 

# 在表't2'上限制最大50GB, 超过时disabling the table

hbase> set_quota TYPE => SPACE, TABLE => 't2', LIMIT => '50G', POLICY => DISABLE

2.7 Table and Namespace space quotas

hbase> create_namespace 'ns1'

hbase> create 'ns1:t1'

hbase> create 'ns1:t2'

hbase> create 'ns1:t3'

hbase> set_quota TYPE => SPACE, NAMESPACE => 'ns1', LIMIT => '100T', POLICY => NO_INSERTS

hbase> set_quota TYPE => SPACE, TABLE => 'ns1:t2', LIMIT => '200G', POLICY => NO_WRITES

hbase> set_quota TYPE => SPACE, TABLE => 'ns1:t3', LIMIT => '20T', POLICY => NO_WRITES

在上面的场景中,ns1不允许命名空间中的表在文件系统上消耗超过100TB的空间。表'ns1:t2'的大小仅允许为200GB,并且当使用率超过此限制时将禁止所有写入。表'ns1:t3'的大小允许增长到20TB,超过时将禁止所有写入和删除。由于'ns1:t1'上没有表配额,它的限制是100TB减去'ns1:t2'和'ns1:t3'的当前使用量。

3 实现原理

3.1 request quota的实现过程

 

3.2 Limiting Tables/ Regions Per Namespace的实现过程

 

3.3 HBase2.1 的space quota的实现过程

 

4 1.2版本与2.1版本的比较

2.1版本比1.2版本新增了一个Space Quota的功能。

5 存在的问题与改进

通过查看了官网和源码,发现hbase的quota可能存在以下的不足(是否不足待讨论),并针对这些不足,提了改进意见,如下表所示:

序号

存在的问题

改进措施

1

Request Quota中,如果达到限流条件,读写请求直接被拒绝

可以增加一个配置项,如果达到限流,该请求可以直接拒绝,也可以重新加入一个自定义的队列,由一个定时任务将限流异常请求回塞到读写请求队列。

2

put/get一次请求,request num就会加1,而scan请求的request num是按照一次完整的scan发送的rpc的次数进行累加的,一次rpc请求数加1

因为scan的一次rpc读取的数据条数肯定远远大于put/get,是否需要给scan加一个权重

3

Hbase quota对hbase的系统表未做限流

是否需要对meta表做限流

4只提供read和write两种类型的粗粒度限流,read中没有区分开get和scan是否需要区分,前一版本的限流的改进就是将read和scan进行了区分

6 附录

6.1 SimpleRpcScheduler初始化读写队列和读写线程数的逻辑

  • 相关的配置

<property>

    <name>hbase.regionserver.handler.count</name>

    <value>128</value>

<description>默认为30,服务器端用来处理用户请求的线程数。生产线上通常需要将该值调到100~200。

</description>

  </property>

  <property>

    <name>hbase.ipc.server.callqueue.handler.factor</name>

    <value>0.1</value>

<description>为0则共享全部队列,默认是0,假如该值为0.1,那么服务器就会设置handler.count * 0.1 = 30 * 0.1 = 3个队列

</description>

  </property>

  <property>

    <name>hbase.ipc.server.callqueue.read.ratio</name>

    <value>0.5</value>

<description>默认为0,服务器端设置读写业务分别占用的队列百分比以及handler百分比。假如该值为0.5,表示读写各占一半队列,同时各占一半handler

</description>

  </property>

  <property>

    <name>hbase.ipc.server.callqueue.scan.ratio</name>

    <value>0.2</value>

  </property>

计算方法:

  • count 是100
  • 队列个数是100 * 0.1 = 10
  • 写队列 10 * 0.5 = 5
  • 读队列总值 10 * 0.5 = 5
  • get 队列 5 - 5 * 0.2 = 4
  • scan队列 5 * 0.2 = 1

2)对应的代码

 

 

6.2 HBase Quota未对系统表做限流

 

 

6.3 HBase space quota相关的参数

参数

含义

默认值

hbase.master.quotas.snapshot.chore.period

定期扫描表存储大小线程的执行间隔时间

1000 * 60 * 5(5分钟)

hbase.master.quotas.snapshot.chore.delay

定期扫描表存储大小线程在多久后执行

1000L * 60L(1分钟)

hbase.master.quotas.snapshot.chore.timeunit

上述两个时间的单位

ms

hbase.regionserver.quotas.policy.refresher.chore.period

Space quota的定时线程的执行间隔时间

1000 * 60 * 1(1分钟)

hbase.regionserver.quotas.policy.refresher.chore.delay

Space quota的定时线程在多久后执行

1000L * 15L(15秒)

hbase.regionserver.quotas.policy.refresher.chore.timeunit

上述两个时间的单位

ms

6.4 一次HBase Scan请求中RPC请求的次数

一次scan请求中RPC的次数与三个参数有关

参数

含义

默认值

setCaching()

单次RPC请求的数据条数

Integer.MAX_VALUE

setBatch()

单次RPC请求的数据列数量

默认一个result包含某row所有的列

setMaxResultSize

单次RPC请求的返回数据量大小

2G

计算公式:

Result 返回的个数 =(row数 * 每行的列数)/ Min(每行列数,Batch大小)

RPC 返回的个数  = (row数 * 每行的列数)/ Min(每行列数,Batch大小) / Caching大小

setCaching 是用来控制rpc的个数,setMaxResultSize 从单次rpc返回的所有Result的总大小来控制某次rpc是否结束。

6.5 Quota判断的相关的代码

对数据请求的quotas限制在region server上进行。RSRpcServices收到RPC请求后,对于get,mutate,scan操作,其执行的RegionServerQuotaManager的checkQuota如下:

 

multi(multiple actions on a table: get, mutate, and/or execCoprocessor)操作,调用RegionServerQuotaManager的如下checkQuota方法进行检查:

 

我们可以看到上面两个方法都调用了同一个checkQuota方法,只是输入参数不同

 

从上面代码中可以看到,这里最重要的两个方法就是getQuota和checkQuota。我们先看getQuota做了什么?

 

简单解释一下代码就是:首先,从Region Server的quotaCache中拿到关于此用户的UserQuotaState。然后从UserQuotaState中提取QuotaLimiter。最后新建一个OperationQuota返回。

再来看DefaultOperationQuota的checkQuota方法:

 

方法中,首先估计各个操作的大小,这个估计的方法很简单,如下面代码所示。不管操作类型是什么,计算方法都一样:

 

回到DefaultOperationQuota的checkQuota方法,最重要的是limiter.checkQuota(writeConsumed, readConsumed)这段代码。进入TimeBasedLimiter的checkQuota()方法:

 

这个函数会把所有的limiter都检查一遍,但凡有一个Limiter不满足条件,就抛出异常。如果所有的判断条件都通过,下面就走到了limiter.grabQuota(writeConsumed, readConsumed)这一步。这个方法的详细代码如下:

 

至此,各个操作的Quota检查就算完成了。但是,在哪调整真正的读写消费量呢?RSRPCServices的get,mutate,scan和multi方法会调用checkQuota方法。拿get方法举例:

 

 

这段代码很长,我们只看与Quota相关的部分。checkQuota部分上面已经介绍了,方法最后有两句代码quota.addGetResult(r)quota.close(),它们是做什么用的呢?先看quota.addGetResult(r)所调用的方法:

 

从代码里不难看出,这是在计算get操作所返回的结果的真正大小,也就是真正的消费量。

直接看quota.close()所调用的方法:

最后进行的步骤就是把真正消费量和估计消费量之间的差额给补齐,多退少补。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/379125.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Servlet篇2】创建一个web项目

在上一篇文章当中&#xff0c;已经提到了什么是Maven&#xff0c;以及如何使用maven从中央仓库下载jar包。【Tomcat与Servlet篇1】认识Tomcat与Maven_革凡成圣211的博客-CSDN博客Tomcat&#xff0c;mavenhttps://blog.csdn.net/weixin_56738054/article/details/129228140?spm…

vue 3 第六章:to全家桶

文章目录1. toRef1.1. 使用toRef函数2. toRefs2.1. 使用toRefs函数3. toRaw3.1. 使用toRaw函数1. toRef 将一个对象中的属性转换成单独的响应式引用接收两个参数&#xff1a;参数一 > 对象 参数二 > 属性转换后的响应式引用会跟踪原始属性的变化转换后的响应式可以被用于…

Mysql从基础入门(1)之数据库建表和增删改

文章目录数据库的介绍1.ER图2.约束Mysql常用命令数据库定义&#xff08;DDL&#xff09;1.DDL操作数据库2.DDL操作表操作数据&#xff08;DML&#xff09;1. 添加数据2. 修改数据3. 删除数据数据库的介绍 数据库&#xff1a;存储和管理数据的仓库&#xff0c;数据是有组织的进…

java 2(程序流程控制)【含例题详解】

java ——程序流程控制 ✍作者&#xff1a;电子科大不知名程序员 &#x1f332;专栏&#xff1a;java学习指导 各位读者如果觉得博主写的不错&#xff0c;请诸位多多支持&#xff1b;如果有错误的地方&#xff0c;欢迎在评论区指出 目录java ——程序流程控制分支结构if-elsesw…

【Redis学习1】Redis安装

Redis基础 什么是Redis REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统&#xff0c;是跨平台的非关系型数据库。 Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-…

什么是钉钉消息推送?

我是3y&#xff0c;一年CRUD经验用十年的markdown程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;常年被誉为职业八股文选手 在前阵子我就已经接入了钉钉的群机器人和工作消息推送&#xff0c;一直没写文章同步到给大家。 像这种接入渠道的工作&#xff0c;虽然我没接入过&…

jQuery 常用API

jQuery 常用API Date: January 19, 2023 Sum: jQuery选择器、样式操作、效果、属性操作、文本属性值、元素操作、尺寸、位置操作 目标&#xff1a; 能够写出常用的 jQuery 选择器 能够操作 jQuery 样式 能够写出常用的 jQuery 动画 能够操作 jQuery 属性 能够操作 jQuery…

Linux教程:基本命令学习

文章目录基本操作命令vim使用Linux yum&apt命令本文采用在Windows操作系统上安装虚拟机Vmware以及Centos的方式。 基本操作命令 登录root [swxlocalhost ~]$ su 密码&#xff1a; [rootlocalhost swx]查看文件夹目录 [rootlocalhost swx]# ls FATE Python-3.…

【ROS学习笔记7】ROS中的常用命令行

【ROS学习笔记7】ROS中的常用命令行 文章目录【ROS学习笔记7】ROS中的常用命令行前言一、rosnode二、rostopic三、rosmsg四、rosservice五、rossrv六、rosparam七、Reference写在前面&#xff0c;本系列笔记参考的是AutoLabor的教程&#xff0c;具体项目地址在 这里 前言 机器…

C++ STL 之双向队列 deque 详解

文章目录Part.I AttentionPart.II FuncitonPart.III CodePart.I Attention deque 是 double-ended queue 的缩写&#xff0c;意即双端队列&#xff0c;详细信息参见官网。deque<T>容器适配器是必须要包含头文件#include <deque>deque相较于vector&#xff1a;①它不…

使用eNSP搭建校园网

哈喽&#xff0c;今天写一篇文章记录一下课上进行的实验说实话&#xff0c;上早八这个脑子他是真的不带转的&#xff0c;家人们有没有什么好方法&#xff0c;能在早八的时候把脑子转起来&#x1f622; 好了&#xff0c;讲一下实验背景。 学校有东西两个校区&#xff0c;东校区…

一文吃透 Spring 中的 AOP 编程

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

C++ STL:容器 Container

文章目录1、序列容器1.1、容器共性1.2、vectorvector 结构* vector 扩容原理* vector 迭代器失效1.3、dequedeque 结构deque 迭代器deque 模拟连续空间1.4、listlist 特殊操作list 结构list 迭代器2、关联式容器2.1、容器共性2.2、容器特性3、无序关联式容器3.1、容器共性3.2、…

【剑指offer】JZ5 替换空格、JZ6 从尾到头打印链表

目录 JZ5 替换空格 思路&#xff1a; 解题步骤&#xff1a; JZ6 从尾到头打印链表 思路&#xff1a; 解题步骤 JZ5 替换空格 描述&#xff1a; 请实现一个函数&#xff0c;将一个字符串s中的每个空格替换成“%20”。 例如&#xff0c;当字符串为We Are Happy.则经过替换之…

LibAFL的安装及基本使用

本教程安装LibAFL使用的是Ubuntu 22.04 操作系统 1. 安装 1.1 Rust 安装 Rust的安装&#xff0c;参照Rust官网&#xff1a;https://www.rust-lang.org/tools/install curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh1.2 LLVM安装 直接apt安装&#xff0c;安…

Day903.自增主键不能保证连续递增 -MySQL实战

自增主键不能保证连续递增 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于自增主键不能保证连续递增的内容。 MySql保证了主键是自增&#xff0c;但不相对连续&#xff1b;帮助开发人员快速识别每个行的唯一性&#xff0c;并提高查询效率。 自增主键可以让主键索引…

2023上半年北京/上海/广州/深圳NPDP产品经理认证报名

产品经理国际资格认证NPDP是国际公认的唯一的新产品开发专业认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年…

【GUI】Robo 3T(Studio 3T Free) for Mongodb安装与使用教程

下载 robo 3T现已更名为studio 3T free&#xff0c;官网即可下载 studio 3T free下载地址 安装 mac电脑下载的是dmg安装包&#xff0c;直接正常安装即可&#xff0c;windows电脑也是一样的&#xff0c;不需要配置环境&#xff0c;安装即可使用。&#xff08;前提是你已经安装…

【C++】二叉搜索树的模拟实现

一、概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的左右子树也分别…

Python---time模块

专栏&#xff1a;python 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;Python在学&#xff0c;希望能够得到各位的支持&#xff01;&#xff01;&#xff01; time模块前言时间戳time.time()将时间戳转换成字符串time.ctime()将时间戳转换为元组time.localtime(时间戳)将元…