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()所调用的方法:

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

Hbase限流 -- HBase Quota调研相关推荐

  1. 限流与代理网关集成调研及应用

    目录 一.限流相关问题概述 为什么使用限流? 限流场景: 限流的处理方式: 限流架构 限流算法 固定窗口算法 滑动窗口算法 漏桶算法 令牌桶算法 限流开源项目 Guava 的 RateLimiter ...

  2. 分布式系统并发请求限流平台Sentinel功能特性调研-集成测试(中篇)

    摘 要 随着近些年系统稳定性要求越来越高,而系统限流则是其中提高系统稳定性的手段之一,而在众多限流平台中Sentinel凭着丰富功能特性和多次阿里双十一的线上实践,成为最热门限流平台之一,本文就Sen ...

  3. 谈谈高并发系统的限流

    开涛大神在博客中说过:在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流.本文结合作者的一些经验介绍限流的相关概念.算法和常规的实现方式. 缓存 缓存比较好理解,在大型高并发系统中,如果没有缓 ...

  4. 慌了,居然被问到怎么做高并发系统的限流

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"加入公众号专属技术群 来源:uee.me/cDuRD 在开发高并发系统时有三把利 ...

  5. 面试官 | 讲一下如何给高并发系统做限流?

    作者 | nick hao 来源 | uee.me/cDuRD 在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流.本文结合作者的一些经验介绍限流的相关概念.算法和常规的实现方式. 缓存 缓存 ...

  6. 高并发系统中的限流应该如何做?

    缓存 缓存比较好理解,在大型高并发系统中,如果没有缓存数据库将分分钟被爆,系统也会瞬间瘫痪. 使用缓存不单单能够提升系统访问速度.提高并发访问量,也是保护数据库.保护系统的有效方式.大型网站一般主要是 ...

  7. javaweb对于高并发策略--限流

    1.对于后端开发来说基本策略:缓存,限流,降级 缓存 缓存比较好理解,在大型高并发系统中,如果没有缓存数据库将分分钟被爆,系统也会瞬间瘫痪.使用缓存不单单能够提升系统访问速度.提高并发访问量,也是保护 ...

  8. 史无前例!肝了30天,终于整出这份[分布式宝典:限流+缓存+通讯]

    无论学习还是备战面试跳槽,必啃限流(ZooKeeper+Nginx).缓存(MongoDB+memcached+Redis).通讯(ActiveMQ+Kafka+RabbitMQ)等三大分布式技术,而 ...

  9. 高并发系统限流最佳实践

    缓存 缓存比较好理解,在大型高并发系统中,如果没有缓存数据库将分分钟被爆,系统也会瞬间瘫痪. 使用缓存不单单能够提升系统访问速度.提高并发访问量,也是保护数据库.保护系统的有效方式.大型网站一般主要是 ...

最新文章

  1. 2021年大数据Kafka(九):kafka消息存储及查询机制原理
  2. 自己写的程序密码功能 ------数字功能
  3. GPU 2014年4月 性能排名
  4. RxJava2学习笔记(3)
  5. Dubbo与SpringBoot整合流程(从实例入手,附代码下载)
  6. 基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET - 系统架构
  7. nginx配合python_人生苦短我用python[0x02] nginx与python结合
  8. java .net des_DES加密解密 JAVA与.NET互通程序代码
  9. PHP开发人员常犯的10个MysqL错误
  10. mysql char(36)_MySQL中char(36)被認為是GUID導致的BUG及解決方案
  11. Java Web下访问外部jar,实例后的Object类型转化的问题
  12. WeX5 - AJAX跨域调用相关知识-CORS和JSONP
  13. OpenCore引导配置说明第五版
  14. 腾讯QQ珊瑚虫外挂原理分析
  15. 国内薪水最高的IT公司排行榜TOP25,大家都说说你们觉得这数据准确吗,我怎么觉得不太准确。。
  16. Python爬取奇书网(用Python下载小说到本地)
  17. Obsidian+SyncTrayzor打造个人文档云同步平台
  18. (附源码)ssm高校学生档案信息管理系统 毕业设计 010936
  19. 一文搞懂业务中台、数据中台、AI中台区别及联系
  20. “泰迪杯”挑战赛 - 基于非侵入式负荷检测与分解针对日常电器的电力数据挖掘

热门文章

  1. itext对已经存在的pdf添加页眉页脚
  2. 数据仓库-基本概念(了解)
  3. 2023最新版彩虹商城时光模板知识付费系统源码 [升级版]
  4. java多线程之——生产者和消费者(详解及提高)
  5. 家用交流电风扇改微风档,改睡眠档,改6档(加电容方案,加档位)
  6. 在线网页更新检查工具
  7. maya mb ma互转时报错解决方案
  8. mysql登_Mysql的登录
  9. 清远凤霞中学2021年高考成绩查询,中学知识:2020清远中考各高中录取分数线公布...
  10. vb6.0服务器组件安装失败,VB6.0安装失败解决办法