云HBase内核解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 摘要:在2018年1月25号数据库直播大讲堂上云HBase技术团队郭泽晖带来“云HBase内核”演讲,比如先讲对HBase做了简介,接着云HBase内核解析,并重点介绍了GC优化和更适合随机读的编码格式,分享了两个实战优化案例,还对云HBase 2.0进行了展望。

摘要:在2018年1月25号数据库直播大讲堂上云HBase技术团队郭泽晖带来“云HBase内核”演讲,比如先讲对HBase做了简介,接着云HBase内核解析,并重点介绍了GC优化和更适合随机读的编码格式,分享了两个实战优化案例,还对云HBase 2.0进行了展望。

直播视频:https://yq.aliyun.com/video/play/1333
PPT下载:https://yq.aliyun.com/download/2461
以下为精彩视频内容整理:

1. HBase简介

HBase是提供强一致、面向列的结构化键值存储。它使用普通的磁盘,并且支持多种压缩算法,成本相对较低。而且它本身支持横向扩展,满足千万级QPS的需求。其分布式的存储、可以轻松满足从GB到PB的需求。依托Hadoop生态圈,拥有许多分析工具:Phoenix(二级索引),Spark(机器学习的分析),MapReduce等。

2. 云HBase内核解析

2.1 GC优化

1


云HBase是基于开源1.1版本发展而来,与阿里内部使用的版本相同,且其经历了双十一严格检验,性能领先开源版本,尤其是在读写方面。
HBase一直以来的存在GC问题。虽然Java简化了编程,提供了内存对象,同时也带来了GC问题,还有延迟问题,但是数据库对延迟高度敏感的。大内存Full GC影响RegionServer服务。情况好时,GC一分钟会或恢复,情况坏时会直接崩溃。针对GC问题,社区已经进行了优化:BucketCache, MemStoreChunkPool。

2


其中MemStoreChunkPool是一个写缓存,当数据写到region里面之后,每个region里面都会有若干个MemStore。当通过客户端把数据写入到region里面时,会先在MemStore写一份。以后在查询的时候,直接从文件中读取,而是先在MemStore读取,这也是HBase保持强一致性的地方。当条件满足的时候,MemStore的数据才会异步写入到磁盘,形成HFile。这就是数据在MemStore的生命周期。
云HBase基于社区已有的BucketCache、 MemStoreChunkPool做了细节的优化,使得云HBase内核优化后:YGC延迟降低50%~70%,吞吐提升20%~30%,几乎不会发生Full GC问题。
MemStoreChunkPool利用了ChunkPool。ChunkPool本质上管理着非常多的Chunk,每个Chunk为2M左右的连续内存。如果不使用ChunkPool,由于数据的本身不规则的,当数据从堆上释放的时候,会产生很多碎片。为了消除这些碎片,写入数据的时候,会申请一个Chunk,数据会写在Chunk,让Chunk来管理这些不规则的数据。MemStoreChunkPool是在ChunkPool上面提出来的,因为在写比较快的时候,会生成很多的Chunk,会给GC造成压力。MemStoreChunkPool在内存中保留一些不释放的Chunk。

3


原生的MemStore是用跳跃链表来维护的,其插入复杂度为 O(logn)、查询复杂度为 O(logn)。是基于ConcurrentSkipListMap来实现key-value的维护。选择跳跃链表而不是其他树结构(其复杂度也是O(logn)),是因为从代码上看跳跃链的常数更低,不做插入后做节点的调整和旋转,实际的时间复杂度比其他数据结构要低。

4


但是基于ConcurrentSkipListMap的MemStore也存在一些问题:数据会在内存中存在一些时间,之前插入的节点会变为年老代,年轻代节点与年老代节点之间存在引用关系,这个引用关系会导致在最年轻代GC的时候,需要扫描年老代。这对年轻代的YGC来说并不友好。而且对象本身占用内存空间以及空间申请过程,都非常零碎。当对象多的时候会产生很多的碎片,当内存过大对内存的开销也非常大。当数据规模不断增大和不断插对象,就会不断产生新索引,要维护的SkipList索引对象就越多,索引数量近O(2n)。

2.2高度聚合的memstore

5
6


云HBase的MemStore是索引对象和数据内存空间高度聚合,使得CPU缓存效率高,无碎片对GC友好,可以避免Full GC。云HBase比之前的MemStore节约内存近40%,吞吐提升20%~30%,YGC时间减少70%以上。
云HBase的MemStore是基于数组来实现SkipList。每次申请连续的Chunk内存(即1个Chunk默认2M)。云HBase会管理Chunk,本质是字节数组。因为使用JDK的SkipList会产生很多的index对象,这些对象会有对象头的开销,而数组本身是只有一个对象,会大大减少对象的数量,并且将索引和数据是放在连续的Chunk里面,其数据紧凑程度会比JDK的SkipList使用率高,测试的吞吐也比较好

7


上面是跳跃链表的结构, 其Chunk是连续的。Chunk上面存储着节点信息,指针的信息,key-value的信息、level的信息,这些信息最后相互关联起来,形成了跳跃链表。在实现的时候,为了降低内存和减少GC,一些信息被压缩在若干个bit内,比如Level信息被压缩在5个bit内,存放于header中。其中每个Node内存结构都是相同的,第一个是Header,占用8个字节的数组长度,NextOffet是解析后一个具体的位置,指向下一个Chunk。
跳跃链表使用的链表,其中链表一般有两种选择,arealist和linklist,这取决于元素的数量,如果元素的数量比较大,也知道数量范围,这时候,选择arealist。原理根SkipList一样,Arealist底层只有一个数组,linklist则会产生非常多的节点,这对内存是很大的开销。

8


bucket cache是一个读缓存,它跟前面的MemStoreChunkPool非常类似。它先申请bucket(默认为2M),当把Block从文件中读出来的时候,会选择一个合适的bucket进行存放,每个bucket有一个size的标签,决定它能放多大的Block。之前的bucket cache存在一个问题,当有多个线程和有多个用户,访问一个数据块的时候,会把Block从 bucket cache拷贝到栈上面。这样会带来额外的拷贝开销,释放内存的时候,会带来GC的问题。为了解决这个问题,参考C++的智能指针的实现,基于引用计数实现Block的智能指针,实现Block管理。使用bucket cache之后,会减少一半的YGC时间。这也是线上不会出现full GC的重要原因。

2.3更适合随机读的编码格式

9


HFile层面数据查询定位过程:根据索引记录nextoffset,通过二分索引可以定位某行某列数据在哪个DataBlock中。seek后读取DataBlock,并对DataBlock进行解码,从头扫描Block获取指KeyValue数据。扫描过程中不断解码。一般使用DataBlock编码格式DIFF来节约空间。

10


使用DIFF编码的好处是:利用和前一个KeyValue公共前缀压缩空间,利用压缩int节约空间。根据不同场景可以节约2-5倍空间。但是DIFF也存在一些问题:(1)DataBlock需要顺序,不断解码才能找到KeyValue。因为DIFF是利用DataBlock的前一个key-value,公共前缀去压缩空间,也就意味着,如果要在DataBlock查找一个key-value,必须要不断地从头开始扫描。(2)从头开始顺序扫Block会成为随机读瓶颈。

11


云HBase Indexable Delta编码是基于DIFF编码做出了改进:隔一段距离设置完整的key-value。通过offset信息在完整key-value中二分。从最近的完整key-value开始解码。这样会跳过大量的数据,读延迟减少10%-15%,存储开销仅增加3%-5%。

3. 客户实战优化案例分享

3.1读写分离降延迟
客户为杭州某公司,其嫌99.9%延迟太高,业务不能接受。通过了解发现,客户会定期持续导入数据,对读延迟要求99.9%的延迟要在40ms内。监控显示99.9%延迟很稳定,与客户业务上监控到的99.9%延迟差距较大,且发现请求有排队现象,考虑写入请求阻塞了读请求。
定时的写请求,影响了服务质量。所以建议用户调整一下读写分离。在用户侧业务监控99.9%延迟,发现调整后将时间从90ms降到了40ms,提高了一倍以上。
3.2压缩&编码降低存储成本

12


客户Soul公司嫌存储成本过高。通过分析发现用户的所有表都没有开启压缩,用的是无编码模式。通过建议用户使用SNAPPY压缩和DIFF编码后(使用DIFF会节省3-5倍的空间)。这两个组合起来编码之后,空间降为原来的1/7,大大节省了使用成本。

4. 云HBase 2.0展望

13


HBase 2.0提供更稳定更快的分布式数据库服务,对稳定性做了很大的改善,这对云上的场景来说比较重要。因为云上的用户对自动化要求很高,如果代码有1%的问题,那么每100个用户里面就需要处理一个用户的问题,随着客户的增加,那么就会应对不过来。原来的RIT经常会卡住,只能重启才能解决问题,主要因为是region的状态是没有统一管理,比较复杂。HBase 2.0是在master上面管理region,解决了RIT问题。
HBase 2.0只有一个region,这样如果维护region的那台region server挂掉之后,会有一段时间是不可服务。现在提供了region副本,如果一个region挂了,可以从备份中去读。通过牺牲一些可读性,来换取强一致性。
如果对可靠性要求比较高,比如99.99%,那么可以在HBase 2.0上面开启这样的功能,但是这样要耗费更多的资源,因为region会有很多,而且同一个region有多个副本,这样region的数量会非常大。
in memory compaction这个功能是减少写放大,这个功能是在内存中先压缩一部分,避免了把文件从HBase上面拉出来,再压缩,再写回去的过程。

本文由云栖志愿小组王朝阳整理,百见编辑。

相关实践学习
云数据库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
目录
相关文章
|
2月前
|
机器学习/深度学习 人工智能 负载均衡
深度解析:Linux内核调度策略的演变与优化
【5月更文挑战第30天】 随着计算技术的不断进步,操作系统的性能调优成为了提升计算机系统效率的关键。在众多操作系统中,Linux因其开源和高度可定制性而备受青睐。本文将深入剖析Linux操作系统的内核调度策略,追溯其历史演变过程,并重点探讨近年来为适应多核处理器和实时性要求而产生的调度策略优化。通过分析比较不同的调度算法,如CFS(完全公平调度器)、实时调度类和批处理作业的调度需求,本文旨在为系统管理员和开发者提供对Linux调度机制深层次理解,同时指出未来可能的发展趋势。
|
28天前
|
存储 大数据 分布式数据库
使用Apache HBase进行大数据存储:技术解析与实践
【6月更文挑战第7天】Apache HBase,一个基于HDFS的列式存储NoSQL数据库,提供高可靠、高性能的大数据存储。其特点是列式存储、可扩展至PB级数据、低延迟读写及多版本控制。适用场景包括大规模数据存储、实时分析、日志存储和推荐系统。实践包括集群环境搭建、数据模型设计、导入、查询及性能优化。HBase在大数据存储领域扮演关键角色,未来有望在更多领域发挥作用。
|
2月前
|
Linux 编译器 调度
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
本文介绍了如何将POSIX应用程序编译为在Xenomai实时内核上运行的程序。
75 1
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
|
2月前
|
存储 Linux API
xenomai内核解析--双核系统调用(一)
本文介绍了Xenomai内核系统调用的实现,探讨了在Linux内核与Xenomai实时内核共存时,系统调用如何区分和交互。系统调用是用户空间与内核空间通信的关键,它提供了硬件抽象、系统稳定性、安全性和可移植性。在32位系统中,通过`int 0x80`指令触发,而在64位系统中,使用`syscall`指令。Xenomai通过I-pipe拦截系统调用,区分实时与非实时任务,并通过`cobalt_syscalls`表执行相应操作。文章还详细解析了系统调用表的生成和权限控制机制。
95 1
xenomai内核解析--双核系统调用(一)
|
2月前
|
消息中间件 调度 数据安全/隐私保护
xenomai内核解析--任务同步互斥机制(一)--优先级倒置
本文是关于Xenomai实时操作系统中资源管理和优先级倒置问题的概述。Xenomai使用`xnobject`和`xnregistry`管理任务间的同步互斥资源,如信号量、互斥锁等。资源管理涉及访问控制和资源保存,确保共享资源的正确调度。文章还介绍了优先级倒置现象,即高优先级任务因低优先级任务持有资源而被阻塞。为解决此问题,Xenomai采用了优先级继承策略,临时提升低优先级任务的优先级,以防止持续的优先级反转。文章后续将深入分析`xnsynch`模块和优先级倒置解决方案。
78 1
xenomai内核解析--任务同步互斥机制(一)--优先级倒置
|
2月前
|
算法 Linux 调度
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
190 1
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
|
2月前
|
API 调度
xenomai内核解析--双核系统调用(三)--如何为xenomai添加一个系统调用
本文介绍了如何在Xenomai中添加自定义系统调用`get_timer_hits()`,该调用用于获取CPU定时器中断次数。首先,在`syscall.h`中定义127号系统调用,并在`clock.h`和`clock.c`中声明和实现该函数。接着,更新libcobalt库以包含新接口。最后,提供了一个示例应用,演示如何在实时任务中使用此系统调用。编译内核和库后,运行示例程序显示定时器中断次数,体现了Xenomai的tickless特性。
44 1
|
2月前
|
机器学习/深度学习 算法 Linux
xenomai内核解析--实时内存管理--xnheap
Xenomai是一个实时操作系统(RTOS)层,用于Linux,旨在提供确定性的任务调度和服务。其内存管理机制包括一个名为xnheap的内存池,确保内存分配和释放的时间确定性,以满足硬实时系统的严格需求。
92 0
xenomai内核解析--实时内存管理--xnheap
|
2月前
|
Linux 测试技术 API
xenomai内核解析之xenomai初探
本文是关于Xenomai实时操作系统的初探,Xenomai是一个实时性增强的Linux系统,它通过实时内核和用户空间库提供硬实时性能。Xenomai 3主要由实时内核Cobalt、实时驱动模型RTDM、用户空间库libcobalt等组成,支持两种构建实时系统的方式:Cobalt和Mercury。Cobalt在内核空间与标准Linux内核并存,通过I-Pipe处理中断,确保实时任务的执行。Mercury则是通过修改Linux内核实现。
144 0
xenomai内核解析之xenomai初探
|
2月前
|
存储 消息中间件 Linux
xenomai内核解析--实时IPC概述
本文介绍了在Xenomai实时内核下,实时任务与非实时任务如何进行通讯
60 0
xenomai内核解析--实时IPC概述

推荐镜像

更多