![721aedd3dac2a0257a046dd65f1217cd.png](https://i-blog.csdnimg.cn/blog_migrate/51479862d10735f17b950a9adf55087d.jpeg)
本文作者:Bang,Harry
来源:微信公众号:滴滴技术
出处:https://mp.weixin.qq.com/s?__biz=MzU1ODEzNjI2NA==&mid=2247521918&idx=1&sn=2cc3a18d4b0bc7438fed5280a57798f3
导读: HBase作为Hadoop生态中表现较为突出的分布式在线数据存储产品,在滴滴有着非常广泛的应用, 但同样存在比较突出的短板问题——例如可用性较弱、毛刺严重等,一定程度上 限制了它的业务边界。 本文主要介绍在此背景下,HBase团队近期进行的一些探索工作。
1.
背景
HBase 是一个基于 HDFS 的低成本、分布式LSM结构数据库,可以支持毫秒级别查询;支持海量的PB级的大数据存储,适用于高QPS的随机读写和前缀范围查询等场景。此外,优秀的开源环境使得HBase还可以支持丰富的上下游生态与离线任务。
目前在滴滴内部,HBase基本覆盖了全部业务线,数据量PB规模,吞吐超千万级别;业务包含司乘轨迹、订单、特征工程、推荐引擎、IOT、APM等各种场景,基于HBase的多模生态诸如OLAP(Kylin)、时序(OpenTSDB)、时空(GeoMesa)、图(JanusGraph)亦均有应用。
![6b7a4f347840d568d815f791da2a1850.png](https://i-blog.csdnimg.cn/blog_migrate/02804b2c0009472c73a37d7c57d7cbf5.jpeg)
2020年下半年,HBase团队逐渐将视野投向端上/类端上业务,希望能够承载更加重要的流量。然而对于HBase自身架构和实现而言,主要存在两方面痛点:
▍ 1. 可用性问题
架构层面看,HBase在CAP定理中选择了C,以较弱的可用性为代价换取强一致性,数据层面依赖HDFS保证数据安全,计算层面region无副本。
这样当region迁移、分裂、合并、RS宕机等情况发生时,对应region都会有短时不可用;而作为高吞吐的数据服务,客户端往往都会大量使用线程池,少量region不可用会迅速形成木桶短板,进而放大为整体TPS掉底。
而这种“预期内的”抖动、掉底,是无法满足互联网行业端上场景的可用性要求的。
社区提供的region replica功能一定程度上可以缓解这一问题,但一方面目前这个feature可靠性还不算高,社区仍在推进各种加固和改善,目测稳定的目标release版本可能要放到未发布的3.0了;另一方面端上服务需要双机房,保证容灾和降级,而replica是集群内的region副本,显然也不能支持。
▍ 2. 毛刺问题
HBase主要受Java GC和底层HDFS共用影响,HBase的毛刺相对突出,是进一步提升性能的瓶颈点。
基于以上两个痛点问题,HBase团队近半年进行了一些尝试与探索,主要是基于 replication的客户端多路读功能 与 HBase-ZGC应用实践,预期能够优化HBase的可用性与毛刺问题,简单分享给大家。
2.
基于replication的客户端多路读功
2020年来,为提升HBase可用性,我们大体经历了两个阶段:
1 . replication主备
replication是HBase的异步数据同步机制,和Mysql利用Binlog实现主从库类似,HBase利用WAL实现主备集群的数据同步。大致流程为主集群记录写入的WAL,并将数据异步发送给备集群,备集群接收数据并将其转换为put/delete操作,批量写入备集群。提供最终一致性保证。
![7d1abc07066bf328fc895cca880b46ce.png](https://i-blog.csdnimg.cn/blog_migrate/931bbfede0dba3bcaec77d9c05a5a2af.jpeg)
图片来源:HBase官方文档
detailed_information_about_cluster_replication
这一阶段存在的问题:
- 故障时用户有感知,需用户侧切读;
- 备集群利用率较低,资源闲置存在浪费;
2. replication + failover
failover是滴滴HBase团队基于replication自研的增强feature,架构如下图:
![8491b6d694e32533ae76470b9e469178.png](https://i-blog.csdnimg.cn/blog_migrate/661c4ac2ae4479fd07b43231f7481ad9.jpeg)
- 相比第一阶段,failover可以基于zk实现服务切换,不需用户操作。但仍然存在用户有感知、备集群无法充分利用的问题;
- 基于以上背景,我们又开发了基于replication的客户端多路读功能,预期解决以下问题:
- 故障时用户无感知;
- 提升备集群利用率;
- 打磨HBase毛刺;
▍ 1. 设计
![4887592b29c70a059387ac825ee3c6f4.png](https://i-blog.csdnimg.cn/blog_migrate/954a08832a793b67115ba467f5a60932.jpeg)
整体设计参考HDFS的hedgedRead功能,客户端首先向主集群发起读请求,一定时间没有返回结果则并发向备集群发起请求,两者取先完成者返回。
实际上HBase的regionReplica也是类似的实现。
▍ 2.新增配置
param
default value
desc
hbase.client.hedged.read
false
是否开启多路读
hbase.client.hedged.read.timeout
50
启动备集群读线程的时间阈值
hbase.zookeeper.quorum.hedged.read
-
备集群zk地址
▍ 3.性能测试
3.1 用例设计
- 两个集群分别创建主备测试表,构建replication
- ycsb打入100w测试数据
- 测试组打开多路读,对照组关闭多路读,各发起10w次scan
- 客户端统计max、P999、P99
3.2 测试结论
![c1fcac8ec1ad7a84bd1cd5b2895fb67f.png](https://i-blog.csdnimg.cn/blog_migrate/774caccbb242292d9aa02cb16480860e.jpeg)
max对比
![def9d2e29b105c254c73f7f84ca4b853.png](https://i-blog.csdnimg.cn/blog_migrate/2b6ccc407fb6d99ac3f7d6d088a0dc8e.jpeg)
P999对比
![88a39251606bd71529f4dee26b5b8ec4.png](https://i-blog.csdnimg.cn/blog_migrate/5098c475cde9b16b3fa7b751008bb848.jpeg)
P99对比
多路读对于max和P999有较佳优化效果,可以有效打磨毛刺。
▍ 4.未尽事项和思考
1. 多路读功能基于replication实现,因此只能实现最终一致性,备集群读到的数据有可能和主集群存在差异;
2. 目前此功能仅作用于查询,主集群宕机时,最新数据无法同步,因此备集群查询最新数据可能查询不到;
3. HBase的scan操作可能分解为多次RPC,由于相关session信息在不同集群间没有同步,数据也不能保证完全一致,因此多路读只在第一次RPC时生效,之后的请求会固定访问第一次RPC时最终使用的集群。
多路读本质上是多活建设,但CAP较难跨越,多活可以提供高可用能力,但强一致性很难得到保障。
但我们可以通过“让用户选择”的方式来解决这一问题:
- 方案一:多活 + 最终一致性
- 方案二:主备 + 强一致性
对于方案一,当前的多路读实现 了读链 路的多活,写链路仍有优化空间,例如提升replication效率、降低两集群间数据lag等;
对于方案二,可以基于社区的同步replication实现,此外failover的功能仍需我们做更多工作,实现更加智能的自动切换,降低用户感知。
3.
HBase-ZGC应用实践
▍ 1.为什么要更换GC算法?
随着滴滴内部越来越多的端上和类端上业务使用HBase作为存储引擎,用户对HBase读写延迟稳定性的要求也越来越高,HBase的GC毛刺问题尤为突出,G1无法满足性能需求。
好消息是JDK15在9月15号正式发布,划时代的ZGC正式转正,我们决定尝试用ZGC来解决GC毛刺问题。
![ff547272b9844a6cbf9f5d676f25bd69.png](https://i-blog.csdnimg.cn/blog_migrate/7faa83caf9ef66884ce60dd2a62ee7c0.jpeg)
ZGC(The Z Garbage Collector) :ZGC是JDK11之后发布的一款可伸缩的低延迟JVM垃圾收集器。
ZGC官方的设计目标如下:
- Max pause times of a few milliseconds(*)
- Pause times do not increase with the heap or live-set size (*)
- Handle heaps ranging from a 8MB to 16TB in size
ZGC 是一个并发的、单代的、基于区域的、NUMA 感知的压缩收集器,Stop-the-world 阶段仅限于根扫描,因此 GC 暂停时间不会随堆或活动集(live set)的变大而增加。
ZGC 的核心设计原则是将Load barriers与染色对象指针结合使用,这使得 ZGC 能够在 Java 应用程序线程运行时执行并发操作,例如对象重定向。从 Java 线程的角度来看,在 Java 对象中加载引用字段的行为受到加载屏障的影响。除了对象地址之外,colored oops 还包含加载屏障使用的信息,以确定在允许 Java 线程使用指针之前是否需要采取某些操作。
ZGC相比G1
- 更低延迟:GC停顿时间更短,不超过 10ms
- 更大内存:堆内存支持范围更大(8MB-16TB)
SPECjbb 2015基准测试,128G堆,ZGC的暂停时间远低于G1
![2b7fa4c6b91dbf790225dbe82bd37ac9.png](https://i-blog.csdnimg.cn/blog_migrate/72a606f1ae005612a422e0d3ed208dd8.jpeg)
相较于G1只有写屏障没有读屏障,复制移动的过程需要Stop the world,ZGC通过读屏障、Remark标记和重定向表来并发拷贝非GC Roots对象,尽可能的减少了Stop the world。
官方的性能测试对比可以参考JEP333。本文主要介绍HBase场景的ZGC应用实践,对ZGC的原理不展开介绍。
▍ 2. HBase应用ZGC实践
2.1 选择JDK版本
由于需要在生产环境使用,而Orace JDK商业使用开始收费,所以我们需要一个免费版的JDK。经过对比,我们最终选取了AdoptOpenJDK的JDK15版本。
1)AdoptOpenJDK 是社区(伦敦JUG)维护版的OpenJDK,提供预构建的二进制文件,主要维护LTS及最新版本;和OpenJDK一样,AdoptOpenJDK 也支持 GPL 协议且免费,不同的是OpenJDK只会由Oracle提供6个月的安全更新,而AdoptOpenJDK则由社区提供至少4年的免费长期支持(LTS)。
2)选择JDK15的原因:
- JDK11存在小概率crash的问题
- ZGC在JDK15版本正式生产环境可用
2.2 编译HBase(基于AdoptOpenJDK15)
滴滴内部使用的HBase版本是基于社区1.4.8基础上开发的版本,不支持JDK11及以上版本的编译,所以需要解决一些编译问题。
社区3.x及2.3.x版本开始支持JDK11,参考 HBASE-22972。在1.4.8版本的编译过程中,主要遇到了以下几类编译问题:
- 1. 部分类找不到或被删除,比如javax.xml.ws.http.HTTPException。解决办法:找到替换类或依赖包;
- 2. 一些类不可读,比如sun.nio.ch.DirectBuffer。解决办法:运行时添加--add-exports=java.base/sun.nio.ch=ALL-UNNAMED;
- 3. 依赖的组件包不支持JDK15,如Jetty、Jruby等。解决办法:升级对应的组件到高版本;
- 4. 编译插件不支持JDK15,如maven-shade-plugin、extra-enforcer-rules等。解决办法:升级对应的插件到高版本。
2.3 应用ZGC的效果:
1、顺序读场景ZGC和G1性能表现对比
Scan场景下,ZGC的P99延迟降低20%,P999降低40%。
![f0461a881c6b9ae652cadd5d4a2b21eb.png](https://i-blog.csdnimg.cn/blog_migrate/9390a17bf213e01f4139f69ae94e9552.jpeg)
![3c2f844f38a5c15268eac442c00a194e.png](https://i-blog.csdnimg.cn/blog_migrate/b3fc851bf648e28e6521c7d67e5d906f.jpeg)
![1e5bc1168b9b8bac41a499986bac76ff.png](https://i-blog.csdnimg.cn/blog_migrate/679620b78a6ab8b62a71ede89c2b5a52.jpeg)
2、压力测试场景对比ZGC和G1的性能表现
构造写压力测试场景,RegionServer的全局Memstore写满,触发Upper Limit,G1GC回收不过来,触发Full GC,耗时超过40s(ZK会话的超时时间),RS服务会宕机。
对比同等写入压力下,ZGC 99.93%的回收时间都在10ms以内,只有2次在10~20ms之间,RS服务未宕机。
备注:如果内存分配过快,ZGC也可能会出现回收不过来的问题,这种情况下可以通过增大堆内存的方式缓解。
![800eee2d1097250f15402c8b1cd2744b.png](https://i-blog.csdnimg.cn/blog_migrate/3763e4c9982ec16911719ee91d5931e7.jpeg)
HBase使用ZGC可以有效的降低了服务端P99及P999的延时,非常适合对延迟较敏感的业务场景。
3.
总结
HBase在真正海量数据的离线应用场景下具备毋庸置疑的竞争力,但受其自身实现短板的限制,距离端上应用的标准还是存在一定距离的。滴滴HBase希望通过一系列优化手段,服务好离线业务的同时,未来可以接入更多的不涉及核心流程的线上/类线上业务,欢迎感兴趣的同学一起交流。
本文作者:Bang,Harry
来源:微信公众号:滴滴技术
出处:https://mp.weixin.qq.com/s?__biz=MzU1ODEzNjI2NA==&mid=2247521918&idx=1&sn=2cc3a18d4b0bc7438fed5280a57798f3