阅读 470

阿里云在HBase冷热分离的实践

内容来源:2018 年 09 月 01 日,阿里云技术专家郭泽晖在“中国HBase技术社区第3届 MeetUp 杭州站 ——HBase应用实践专场”进行《云上HBase冷热分离实践》的演讲分享。IT 大咖说作为独家视频合作方,经主办方和讲者审阅授权发布。

阅读字数:3825 | 10分钟阅读

观看嘉宾完整演讲视频及PPT,请点击:t.cn/ELx5wUX

摘要

本次演讲主要分享的是在云端怎么样做一个HBase的产品,首先会介绍一下冷数据的典型场景,以及HBase在云端的一个实现方案。

典型数据场景

一般冷数据的定义是访问的比较少,且访问频次会随着时间的流逝而减少的数据,比如监控的数据、线上台账数据,如果在业务上出现问题,我们查看的肯定是最近一段时间的数据,而不会查看诸如半年前的监控数据。

而我们这边对冷数据的定义,根据时间成本来估算的话,大概是平均每GB数据月度访问不超过10万次这个层次的数据。同时对成本敏感的数据也可以做冷热分离。

传统方案

如果是传统的开源的HBase要做冷热分离,方案只能是搞两个集群,一个集群是SSD的配置,负责在线查询,另一个集群是机械盘HDD的配置。 这两张表之间需要手动进行同步,并且客户端需要感知两个集群的配置。

这样做的优点就是不需要改HBase代码,缺点也很明显,要同时维护两个集群,开销肯定是比较大的,而且对于冷集群来说,如果查的比较少,集群上cpu资源浪费也会比较多。

在2.0的HBase的版本中新加入了一个特性,可以指定表的HDFS存在哪种介质上。这利用了HDFS的分级存储功能,HDFS的分级存储功能,可以将DataNode配置到不同介质的盘。比如上图中有三块是机械盘一块SSD,在表上可以设置这样的策略,指定表的HDFS是写在冷介质还是热介质上,最后调到HDFS接口的时候,会根据设置的文件的属性放置数据。

这样2.0的HBASE就可以做到在一个集群内既有冷表也有热表,相对来说比1.x版本更好管理。当然它也有一个缺点,因为要根据业务配比集群的硬件配置,如果集群上混合了比较多的业务,或将来业务的场景有了一些变化,集群的硬件配置是很难调整的。

云HBase云端方案

所以我们云端的方案,将会是一个比较弹性的方案。在介绍云端的冷存储方案之前,我先大概介绍一下我们云HBase,它是一个存储计算分离完全的架构。

由于HBase部署的节点访问磁盘都是远程读的,因此我们能做到动态调整磁盘大小,做到完全弹性。这里面还有一个多模式,在云HBase上除开HBase本身的KV功能以外,我们还架设了一些其他的开源组件。最底下的存储层上,目前我们的应用数据场景主要有两块,一般的数据是放在云盘,冷数据放在OSS。

基于OSS的HBase冷存储

下面介绍一下基于OSS怎么做HBase冷存储。前面提到过,我们做的是一个完全弹性的模式,所以我们的冷存储方案,其实并没有配置磁盘,冷表的数据是直接放在OSS上,并且在同一个集群内也能实现冷表和热表。

可能有朋友不太了解OSS,这里简单介绍下。OSS是阿里云的一款对象存储产品,可以理解为也是一个KV存储,它特点在于能生成非常大的对象,可达到TB级别。 同时还能保证9个9的数据可靠性,并且成本非常低。

成本优势

OSS的成本如果跟云盘对比的话,云盘大概是每GB每个月0.7元,OSS则只要两毛钱成本,相差了3.5倍的。

再举一个具体的例子,和一个汽车企业相关,该企业大概有10万辆车,每30秒会上传一个7K的包,并且数据是基本上半年之后就不会访问,这样计算下来三年的数据量大约是2P左右,和OSS相比每个月成本的开销会差2.5倍,如果完全采用云盘架构大概是140万左右,混合OSS加云盘大概是60万的成本。

基于OSS架设HBase的问题

对于在阿里云上使用OSS作为HBase的底层存储的形式,其实现在的Hadoop 社区已经实现了一个叫NativeFileSystem的类,它继承至FileSystem,我们可以把FileSystem的实现类在配置里边替换掉,这样数据读写就可以直接转发到OSS上。

不过由于NativeFileSystem是针对mapReduce这样的离线作业产品实现的,所以在模拟文件系统过程中会有几个问题。前面说过OSS实际上是一个对象存储,没有文件系统的结构的。

因此常规路径中的反斜杠分割符并不代表目录,只能表示对象名字中的字符。 而要模拟出目录的效果的话,创建目标对象的同时,必须还要创建额外的对象才能模拟出目录结构(如图所示)。这样的模拟存在一个问题,我们对文件目录操作实际上不是原子的,类似rename这种操作,如果中途crash,会出现不一致,无法保证原子性。对于依赖目录操作原子性的一些系统使用社区实践,就会存在问题,最后会使得目录或文件不一致。

对于该问题云HBase的解决方案是,自己实现了一个OSSFileSystem,它能避免刚才说的原子的问题。具体的实现上,我们是把云数据的管理放在HDFS上,HBase调用FileSystem的API时候,调用的其实是我们实现ApsaraDistnbutedFileSystem,由它来控制文件是放在HDFS里还是OSS上。HLog依然是完全放在HDFS上,主要是考虑写入性能。

云HBase冷存架构

云数据操作通过ApsaraFileSystem直接请求能用的进行操作,热表的数据调用Hadoop的FileSystem,冷数据会在HDFS里创建一个文件,这个文件有一个属性的标记表示该数据是冷的,读冷文件时候会把读通道转发到OSS上,然后构建一个OSS的input stream和OSS output stream。

社区版对比

除了架构上区别于社区版,保证HBase能正常使用外。我们对性能也做了优化。架设在对象存储上的实现会存在一些限制,第一请求是要收费的,第二Hadoop FileSystem是提供OutPutStream让用户输入数据,而OSS SDK提供的是InputStream让用户输入。这样的话,要实现Hadoop FileSystem接口嫁接OSS,就必须做一个OutPutStream到InputStream的转换。

对此社区版实现是这样的,数据写入到NativeOSSOutPutStream上的时候,实际会写到磁盘上,在磁盘上会有buffer文件,当文件写满128兆的时候,会被包装成FileInputStream提交给OSS的SDK,由一个异步线程池负责。

这样的实现有几个问题,首先写入过程需要过磁盘,性能上有一些损耗。 其次会比较依赖于磁盘的性能,以及机型内存的大小,配置参数等因素影响。

理论环境下这个线程池可以并发提交,如果写入速度足够快,一下子就能在磁盘上产生,比如十个128兆的buffer文件,这样线程池就相当于有十个线程将这10个buffer一起提交,速度是可以说是很快的。

但是这只是理论环境,正常HBase下来的数据最多只有100多兆,而且也不可能有那个速度瞬间产生十个128兆个文件。所以实际社区设计的这套写入流程,写入行数不够快的话,这个异步发送线程池会退化成一个单线程,就相当于一个文件只有一个线程在提交。

另外一个问题在于crash的时候,会在磁盘上残留一些文件,对运维来说还是比较麻烦的。

云Hbase的设计的OSSFileSystem,整个写入过程是不会在磁盘上落地的,这中间有一个RingBuffer,大概有几兆,用户的写入会到这里。RingBuffer里面是由固定数量的page组成,一个page差不多是两兆,总共是有五个page。

写入page之后,蓝色区域相当于用户写好的page。绿色这块有一个异步线程,每个文件写入会有一个独立的异步线程,这个线程会把蓝色写好的page数据读出来,然后包装成InputStream。

每当InputStream被OSS的SDK读完128兆的时候会return 一个EOF等于-1,相当于欺骗OSS,告诉它这个数据结束了,然后把这128兆数据提交一下,之后再有数据写入,会再包装一个新的InputStream。所以从成本上来说,虽然跟社区的方案一样,都是128兆提交一次,但是我们的写入过程是完全不需要落地磁盘的,并且占的内存开销也非常少。同时我们考虑到了冷热表混合的场景,buffer内存都是自己管理的,避免了YGC,并解决了元数据操作原子性的问题,而HBase恰好依赖于这样的原子性来完成一些操作。

在云HBase上使用这样的特性,也非常简单,在建表的时候,如上图配置就可以了。设置成冷之后,表的所有数据写入都会存到OSS里面。

冷存储建议使用场景

对于冷存储使用的场景,我们的建议的是写多读少以及顺序读。如果持续get,我们会限制冷存储读的IOPS,对于偶尔访问,IOPS限制会适当动态放宽,顺序读写流量不做限制。

以上为今天的分享内容,谢谢大家!

编者:IT大咖说,转载请标明版权和出处


关注下面的标签,发现更多相似文章
评论