Hi,大家好!我叫祝海林,微信号叫祝威廉,本来微博也想叫祝威廉的,可惜被人占了,于是改名叫祝威廉二世。然后总感觉哪里不对。

根据HBase做Storm 实时核算目标存储  hbase 实时计算 第1张

Hi,咱们好!我叫祝海林,微信叫喊祝威廉,原本微博也想叫祝威廉的,惋惜被人占了,所以改名叫祝威廉二世。然后总感觉哪里不对。现在在乐视云数据部门里从事实时核算,数据渠道、查找和引荐等多个方向。曾从事根底结构,查找研制四年,大数据渠道架构、引荐三年多,个人时刻现专心于集群主动化布置,服务办理,资源主动化调度等方向。

这次讨论的主题是:

依据 HBase 做 Storm 实时核算目标存储

HBase 实时目标存储是我入职乐视云后对原有的实时系统改造的

一部分。部分同享内容其实还处于施行阶段。架构计划规划的话应该是仁者见仁智者见智,也会有许多考虑不周的当地,欢迎咱们批评指正。说不定咱们听完同享后好的提议咱们会用到工程上,也为后边的实践课程做好预备。

HBase 存储规划

Storm 成果怎么存储到 HBase

HBase 写入功用优化

与传核算划 (Redis/MySQL) 比照

乐视云内部用 Storm 做 CDN,点播,直播流量的核算,一起还有慢速比,卡顿比等核算目标。相应的目标会由目标称号,事务类型,客户,地域,ISP 等多个维度组成。目标核算一个比较大的问题是 Key 的调集很大。

举个比方,假定咱们有客户 10w,核算目标假定 100 个,5 个 ISP,30 个地域,这样就有亿级以上的 Key 了,咱们还要核算分钟等级,小时等级,天等级,月等级。所以写入量和存储量都不小。

假如选用 Redis/Memcached 写入速度是没有问题的,究竟彻底的内存操作。可是 key 调集太大,其实压力也蛮大的,我去的时分由于加了目标,成果导致 Memcache 被写爆了,所以紧迫做了扩容。

首要是 Redis 查起来的太费事。客户端为了某个查询,需求汇总不计其数个 Key。。。事务方表明很蛋疼,咱们也表明很蛋疼

其次,内存是有限的,只能存当天的。曾经的数据需求转存。

第三,你仍是绕不过耐久化存储,所以引进 MySQL,现在是每天一张表。那 Redis 导入到 MySQL 本身就费事。所以工作量多了,查询也费事,查一个月半年的数据就吐血了。

鉴于以上原因,咱们就想着有没有更适宜的计划。

咱们首要就想到了 HBase,由于 HBase 仍是具有蛮强悍的写入性功用以及优异的可扩展性。而事实上经过调研,咱们发现 HBase 仍是十分合适目标查询的,能够有用的经过列来削减 key 的数量。

举个比方,我现在想制作某一个视频昨日每一分钟的播映量的曲线图。假如是 Redis,你很或许需求查询 1440 个 Key。假如是 HBase,只需一条记载就搞定。

咱们现在上图:

根据HBase做Storm 实时核算目标存储  hbase 实时计算 第2张

这儿,咱们一行能够追寻某个目标一天的状况。假如加再加个维度,无非添加一条记载。而假如是 redis,或许就多了一倍,也便是 2880 个 key 了。

假定该视频是 A,现已在线上 100 天了。咱们会记载这个视频一切的 1 分钟播映数,用 Redis 或许有 100*1440 个 key,可是 HBase只需获取 100 条记载就能够找出来,咱们把时刻粒度转化为了 hbase 的列,然后削减行 (Key)。

咱们知道 HBase 是能够多列族,多 Column,Schemaless 的。所以这儿,咱们建了一个列族,在该列族上,直接建了 1440 个 Column。Column 的数目和时刻粒度有关。假如是一分钟粒度,会有 1440 个,假如是五分钟粒度的会有 288 个,假如是小时粒度的,会有 24 个。不同的粒度,咱们会建不同的表。

写入的时分,咱们能够定位到 rowkey,以及对应的 column,这儿一般不会存在并发写。当然 HBase 的 increment 现已处理了并发问题,可是会形成必定的功用影响。

查询的时分,可依据天的区间查出一条相应的记载。咱们是直接把记载都取出来,Column 仅仅一个 Int/Long 类型,所以 1440 个 Column 数据也不算大。

Storm 核算这一块,还有一个比较有意思的当地。假定 A 目标是五分钟粒度的,也便是说咱们会存储 A 目标每个五分钟的值。可是在实践做存储的时分,他并不是五分钟完毕后就往 HBase 里存储,而是每隔(几秒/或许必定条数后)就 increment 到 HBase 中,然后铲除从头计数。

这儿其实我要着重的是,到 HBase 并不是掩盖某个 Rowkey 特定的 Cloumn 值,而是在它原有的根底上,做加法。这样做能够避免时刻周期比较长的目标,其累计值不会由于有拓扑当掉了而丢掉数据(其实仍是会丢的,但或许丢失的计数比较少罢了)。

丢数据比方你 kill-9 了。

咱们能够幻想一下,假如我核算一个五分钟的目标,到第三分钟挂掉了,此刻累计值是 1000,接着拓扑重启了,五分钟还没完,剩余的两分钟它会接着累计,此刻是 500。假如是掩盖写,就会得到不正确的成果,实践上整个完好的计数是 1500。

避免拓扑当掉并不是这样规划的主要原因,还有一点是核算延时了,比方某个数据片段由于某个原因,延时了十分钟才到 Storm 实时核算集群,这个时分新得到的值还能够加回去,假如是掩盖,数据就错误了。

所以 HBase 存储这块就变成做加法操作而不仅仅是简略的更新了。现在 HBase 添加了计数的功用 (Incrment),可是我发现跨行,没有批量更新的的接口。

而 HBase 的 Client 也是十分的独特,比方 HTablePool 竟然是目标池而不是链接池,多个 HTable 目标是同享一个 Connection 链接的。当然,这儿 HTable 的 Connection 会比较复杂,由于要连 Zookeeper 还有各个 Region。

又没有批量接口,一个 Client 只能有一个 Connection 链接,所以导致客户端的写入量死活上不去。16 台 32G,24 核的服务器,我做了预分区 (60个左右),用了四十个进程,300 个左右的线程去写,也就只能写到 60000/s 罢了。

但实践并发应该是只需 40 左右的。300 个线程并没有起到太多效果。

还有便是,HBase 的 incrementColumnValue 的功用的确不高。至少和批量 Put 距离很大。

但在咱们的测验中,仍是比较平稳的,整个写入状况。颤动不大。

这儿要着重一点,HBase 看场景,在咱们这个场景下是预分区是十分重要的。不然一开始都会集在一台机器的一个 Regin 上写,估量很快写的进程就都堵住了。上线就会挂。

所以我事前搜集了几天的 key,然后预先依据 key 的散布做了分区。我测验过,在咱们的集群上,到了 60 个分区便是一个瓶颈,再加分区现已不能进步写入量。

写入咱们也做了些优化,由于写的线程和 Storm 是混用的(其实便是 Storm 在写)。咱们不能堵住了 Storm。

当用户提交了N条记载进行更新操作,我会做如下操作:

将N条分红10份,每份N/10条。

每个JVM实例会构建一个具有10个线程的线程池。

线程池中的每个线程都会保护一个Connection(经过ThreadLocal完结)。

线程会对自己的这N/10条数据次序进行incrementColumnValue。

做这个优化的原因是我上面说到的,HTable 的衔接池是同享 Connnection 的。咱们这儿是为了让每个线程都有一个 Connection。详细分红多少份(我这儿选用的是 10),是需求依据 CPU 来考量的。咱们的服务器 CPU 并不是许多。值不是越大越好。假如太大,比方我起了 40 个虚拟机。每个虚拟机 10 个线程,那么会有 400 个到 Zookeeper 和 HBase 的衔接。值设置的过大,会对 Zookeeper 有必定的压力。

这种计划我测验的成果是:

吞吐量上去了。在 1500w 左右的测验数据中,原有的方法大约均匀只需 3w/s 左右的写入量。 经过新的方法,大约能够进步到 5.4w/s,只需 4 分钟左右就能完结 1500w 条数据的写入。

峰值稍微进步了一些。之前大约 6.1w/s,现在能够到达 6.6w/s。

由于我用同一集群上的 Spark 模仿的提交,所以或许会对 HBase 的写入有一点影响,假如想要持续进步写入功用,只能重写 HBase 这块客户端的代码。

咱们总结下上面的内容:

Redis/Mysql 存储计划存在的一些缺陷。

HBase 表结构规划,充沛李永乐 HBase 本身的特色,有用的削减Key的数量,进步查询功率。

Storm 写入计划,用以确保呈现数据延时或许 Storm 拓扑当掉后不会导致数据不可用。

咱们再看看整个存储系统完好的拓扑图。

根据HBase做Storm 实时核算目标存储  hbase 实时计算 第3张

第五个圆圈是为了在实时核算犯错时,经过 Spark/MR 进行数据康复。

第二个圆圈和第四个圆圈是为了做维度仿制,比方我核算了五分钟的值,这些值其实能够主动叠加到对应的小时和天上。咱们称为割裂程序

第三个圆圈便是对外吐出数据了,由咱们的一致查询引擎对外供给支撑查询支撑了。

咱们对查询做一个推演。假如我要给用户制作流量的一个月曲线图。曲线的最小粒度是小时,小时的值是取 12 个五分钟里最高的值,咱们看看需求取多少条记载完结这个查询。

咱们需求取 31 条五分钟的记载,每条记载有 288 个点,对这 288 个点分红 24 份(详细便是把分钟去掉 groupBy 一下),求出每份里的最大值(每组 SortBy 一下),这样就得到了 24 个值。

我取过两天的,整个 HTTP 呼应时刻能够操控 50ms 左右(本机测验)。

上面的全体架构中,割裂程序是为了缓解实时写入 HBase 的压力,一起咱们还使用 MR/Spark 做为康复机制,假如实时核算发生问题,咱们能够在小时内完结康复操作,比方日志的搜集程序、分拣程序、以及格式化程序。格式化程序处理完之后是 kafka,Storm 对接的是 Kafka 和 HBase。

上面便是今日同享的内容了。

感谢咱们。

转载请说明出处
知优网 » 根据HBase做Storm 实时核算目标存储

发表评论

您需要后才能发表评论