HBase最佳实践-多租户机制简析

简介:

背景介绍

在HBase1.1.0发布之前,HBase同一集群上的用户、表都是平等的,没有优劣之分。这种’大同’社会看起来完美,实际上有很多问题。最棘手的主要有这么两个,其一是某些业务较其他业务重要,需要在资源有限的情况下优先保证核心重要业务的正常运行,其二是有些业务在某些场景下会时常’抽风’,QPS常常居高不下,严重消耗系统资源,导致其他业务无法正常运转。
这实际上是典型的多租户问题,社区针对这个问题提出了相应的应对措施,主要有如下三点:

(1)资源限制,主要针对用户、namespace以及表的QPS和请求大小进行限制,详见HBase-11598
(2)资源调度,主要针对任务进行优先级调度,通常会优先调度实时交互而且小的任务,而批量操作任务或者长时间操作任务(大scan)优先级相对较低,详见HBase-10993
(3)资源隔离,将不同表通过物理隔离的方式分布到不同的RegionServer上,详见HBase-6721

本文将会重点介绍HBase中的资源限制方案 – Quotas,主要对其使用方式、实现原理进行介绍,并对其实际效果通过实践进行验证。另外,本文还会对HBase的资源调度原理进行简单介绍,并对主要配置进行讲解。


资源限制-Quotas

Quotas使用条件

(1)HBase版本在1.1.0以上,或者低版本HBase应用了对应的Patch(HBase-11598)
(2)Quotas功能默认是关闭的,需要在配置文件hbase-site.xml中通过设置hbase.quota.enabled为true打开。设置完成之后,需要重启HMaster才能生效。

Quotas语句详解

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

(1)Quotas分别支持表级别以及用户级别资源限制,或者同时支持表级别和用户级别,如示例所示
(2)THROTTLE_TYPE可以取值READ / WRITE,分别对随机读和随机写进行限制
(3)LIMIT 可以从两个维度对资源进行限制,分别为req/time 和 size/time,前者限制单位时间内的请求数,后者限制单位时间内的请求数据量。需要指明的是time的单位可以是sec | min | hour | day,size的单位可以是B(bytes) | K | M | G | T | P,因此LIMIT可以表示为’1000req/min’或者’100G/day’,分别表示’限制1分钟的请求数在1000次以内’,’限制每天的数据量为100G’


常用Quotas语句

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

注意事项

(1)set_quota命令执行的限制都是针对单个RegionServer来说的,并不是针对整个集群
(2)set_quota命令默认执行后并不会立刻生效,需要等待一段时间才会生效,等待时间默认为5min。可以通过参数 hbase.quota.refresh.period 进行设置,比如可以通过设置
hbase.quota.refresh.period = 60000将生效时间缩短为1min
(3)可以通过命令list_quotas查看当前所有执行的set_quota命令

Quotas – 实现原理

原理很简单,如果请求数超过设置的Quota数,就抛出异常!有同学会说也没在日志中看到任何异常嘛,这是因为这类异常日志级别是debug,而默认的日志输出级别为info,可以通过调整log4j来查看。但是这类异常实在太多,没有必要输出。

Quotas – 实践效果

了解了Quotas的使用方法以及基本原理,是不是很想试一试它的功效,笔者在测试环境做了如下的测试:

1. 测试硬件情况
集群规模
RS JVM内存配置
硬盘
HBase版本
YCSB版本
4台RegionServer
72G
12 * 3.6T
1.1.2
0.8.0

2. 测试环境新建两张表,分别称为A和B。两张表的数据构成都相同,10亿条数据,每条数据500Bytes,总大小500G左右。
3. 分别使用两个YCSB客户端分别对这两张表执行读写混合操作(读写比为1:1),再然后对B表不断执行set_quota操作,对该表QPS进行限制。再分别观察A表和B表的QPS以及读延迟变化情况。
4. 为了方便理解,下面测试结果中A表称为Unthrottle_Table,B表称为Throttle_Table。测试结果如下:


3.png

clipboard
通过测试基本可以看出,随着B表执行的QPS限制越来越严格,上图中Throttle_Table表对应的吞吐量(红色柱状图)越来越小,相应Unthrottle_Table表(紫色柱状图)对应的吞吐量却越来越大,这是因为B表执行QPS限制之后各种硬件资源就会更多地分配给A表。
总体来说,Quotas功能总体看来基本完成了资源限制的职能,达到了资源限制的目的。同时支持用户级别和表级别,另外同时支持请求大小和请求数量两个维度,基本涵盖了常见的资源限制维度;另外,易用性也是一大亮点,比较人性化,只需要在Shell界面上敲一行命令就可以搞定。


资源调度

在 0.99版本之前,HBase只提供了一种请求队列类型:FIFO队列,意为先到的请求会优先被处理,后到的请求需要等待之前的请求被处理完。这样的设计有一个致命的缺陷,就是在线交互式查询有可能会被离线大scan长时间阻塞,而从优先级的角度讲在线交互式查询无疑更加重要。

0.99版本之后,HBase将默认请求队列由FIFO类型改为了Deadline类型,用来解决上述缺陷。提起DeadLine队列,很多对Linux  IO调度算法比较了解的同学并不陌生,Linux IO常用调度算法主要有Noop、CFQ(Completely Fair Queuing)以及Deadline,其中Noop调度算法基本可以认为就是FIFO算法,因此同样存在上述弊端;而CFQ算法会按照IO请求的地址进行排序,这样处理的目的在于尽量少地减少磁盘移动,实际效果来看确实极大的提升了IO的吞吐率,但是相比Noop,部分IO请求有可能会一直排到队尾,存在饿死的情况。Deadline算法首先将读写IO队列进行了分离,而且读IO优先级要高于写IO优先级;除此之外,它还会为每一个IO请求设置一个时间戳,用以判断请求是否长时间没有得到处理,进而需要优先处理。需要知道的是,对于常见数据库环境来说(Oracle,MySQL等),Deadline算法总是最佳选择。

那HBase新增的Deadline算法和Linux IO中Deadline算法是否一样呢?答案是肯定的,至少两者实现思路基本是一致的。接下来主要结合HBase请求调度源码对Deadline算法进行深入分析。
Deadline算法基于Deadline类型队列实现,Deadline类型队列和FIFO类型队列不同,属于优先级队列,里面的元素会按照优先级进行排序,优先级高的排在队首,优先级低的排在队尾。很显然,Deadline算法目标是使得在线交互式查询请求优先级更高,而离线长scan请求优先级更低。除此之外还有一个通常不会被注意的目标:不能出现任何请求被饿死!在弄懂具体的实现机制前,需要首先搞清楚一个问题:如何量化一个scan的请求长短?

如何量化一个scan的请求长短:这个问题的理解需要对scan的流程有一个大体认识,一次scan请求并不会将所有数据查询返回,这一方面是因为在数据量大的场景下诸如带宽之类的系统资源会被严重消耗,另一方面也有可能会因为数据量大导致客户端OOM。因此HBase实际上将一次scan请求分为多次连续的next小请求执行,每次查询纪录数用户可以配置,默认为100条。这样假如一次scan查询总纪录数为1000,每次查询返回100条,就需要10次客户端到服务器端的next请求。看到这里,很多童鞋已经明白,可以通过当前RPC请求次数(即next RPC调用次数)粗略地衡量scan的长短,比如当前scanA的RPC请求次数为10,scanB的RPC请求次数为5,就可以认为scanA长于scanB,那理论上scanA的这次请求优先级就会低于scanB的这次请求。
HBase在具体实现中会为每一个请求设置一个deadline(时间期限),代表这个请求的处理期限,deadline越小,请求优先级越高。

2

这个deadline参数是理解HBase资源调度的关键,它由两部分构成:后半部分的核心在于vtime,代表当前scan的next请求次数,可见vtime越大(scan越长),对应的deadline越大,优先级越低;因为设定get操作的vtime为0,因此同等条件下get操作优先级最高;可见,通过vtime就可以实现请求优先级功能。那对于长scan,会不会出现因为优先级太低长时间得不到处理饿死的情况呢?这就需要看看前半部分,timestamp表示请求点的绝对时间戳,设置绝对时间戳是为了保证该请求的deadline肯定早于5s(等式后面部分最大就是5s)之后所有请求的deadline,从而能够保证不会被饿死;


好吧,上面不是说Linux IO调度系统中Deadline算法还实现了读IO和写IO的分离,那HBase实现了么?当然,用户只需要通过简单的配置就不仅可以实现读请求和写请求的分离,还可以实现了scan请求的分离。

默认场景下,HBase只提供一个队列,所有请求都会进入该队列进行优先级排序。用户可以通过设置参数hbase.ipc.server.callqueue.handler.factor来设置多个队列,队列个数等于该参数 * handlercount,比如该参数设置为0.1,总的handlercount胃150,则会产生15个独立队列。
独立队列产生之后,可以通过参数 hbase.ipc.server.callqueue.read.ratio 来设置读写队列比例,比如设置0.6,则表示会有9个队列用于接收读请求,6个用于接收写请求;另外,可以通过参数 hbase.ipc.server.callqueue.scan.ratio 设置get和scan的队列比例,比如设置为0.1,表示1个队列用于scan请求,另外8个用于get请求;



本文主要介绍了HBase中多租户实现中的两个重要手段:资源限制以及资源调度,对其工作原理以及使用方法进行了解析。后续再针对资源隔离这个重头戏进行深入解析~


本文转载自:http://hbasefly.com

原文链接

相关实践学习
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
存储 分布式数据库 Hbase
HBase scan过程简析
HBase scan过程简析。 scan过程总体上是分层处理的,与存储上的组织方式一致,脉络比较清晰; 具体来说,就是region->store→hfile/memstore,分别都有对应的scanner实现进行数据读取; scan请求本身设置的条件,以及server和table层面的一些参数限制,会根据需要分布在不同层次的scanner中进行处理; 2.
1942 0
HBase scan过程简析
|
SQL 搜索推荐 Java
「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践
「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践
406 0
「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践
|
存储 监控 安全
HBase集群多租户实践
HBase集群多租户实践
401 0
HBase集群多租户实践
|
存储 缓存 算法
生产环境使用HBase,你必须知道的最佳实践
生产环境使用HBase,你必须知道的最佳实践
249 0
|
存储 缓存 算法
生产环境使用HBase,你必须知道的最佳实践
前面,我们已经打下了很多关于HBase的理论基础,今天,我们主要聊聊在实际开发使用HBase中,需要关注的一些最佳实践经验。 1.Schema设计七大原则 1)每个region的大小应该控制在10G到50G之间; 2)一个表最好保持在 50到100个 region的规模; 3)每个cell最大不应该超过10MB,如果超过,应该有些考虑业务拆分,如果实在无法拆分,那就只能使用mob; 4)跟传统的关系型数据库不同,一个HBase的表中列族最多不超过3个,列族中的列可以动态添加的,不要设计过多列族; 5)列族名必须尽量短,因为我们知道在存储的时候,每个keyvalue都会包含列族名;
152 0
|
机器学习/深度学习 SQL 分布式计算
云HBase Phoenix索引构建最佳实践
介绍三种的不同的索引构建方法及其适用场景
2587 0
|
Java Shell 分布式数据库
hbase shell实现原理简析
hbase的交互式命令行是通过jruby实现的,当我们输入hbase shell时,实际上最终执行的是org.jruby.Main,并以bin/hirb.rb作为参数,注意是根目录下bin目录中的hirb.
1999 0
|
监控 分布式数据库 Python
云HBase Thrift使用最佳实践
  HBase原生只提供了JAVA API客户端,针对诸如python、php、c++等非java语言一般都是通过Thrift代理的方式访问HBase服务,本文从thrift架构、hbase thrift api使用以及如何监控thrift等几个方面详细介绍云HBase Thrift使用最佳实践;  Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。
1838 0
|
监控 分布式数据库 API
HBase TB级数据规模不停机迁移最佳实践
有关HBase集群如何做不停服的数据迁移一直都是云HBase被问的比较多的一个问题,目前有许多开源的工具或者HBase本身集成的方案在性能、稳定性、使用体验上都不是很好,因此阿里云提供了BDS迁移服务,可以帮助云上客户实现TB级数据规模不停机迁移
5824 0