修改HBase的rowkey设计把应用的QPS从5W提升到50W
UTT是Aliexpress的营销消息运营平台,运营希望促销活动时APP消息推送的QPS达到34W。
UTT刚接入APP消息推送时,QPS只能达到5W,离运营的要求有很大的距离。
通过改造,QPS达到了50W,其中最主要的改造是对Hbase的rowkey的改造。
首先介绍一下UTT大致工作流程:
1、运营人员在UTT的小二控制台配置运营任务(job),在任务中设置商品选择参数、目标人群参数和消息发送渠道;
2、UTT调用算法平台计算出要发送的消息,数据生成在阿里云飞天系统的云梯表中;
3、UTT把云梯表中的数据导入到hbase,并生成N个可以并发执行的发送任务(segment),segment的信息存储在mysql表中;
4、UTT按计划发送时间捞取segment,把存储在Hbase中的segment对应的消息读取出来调用阿里巴巴移动消息推送网关发送出去。
步骤1、2、3是提前执行的,我们要优化的是步骤4。
改造中,我们主要做了如下几件事:
1、修改了Hbase的rowkey规则和数据读取方式;
2、优化了记录发送进度的逻辑;
3、优化了消息发送到阿里巴巴移动消息推送网关的流程。
其中最主要的是对Hbase的rowkey的修改。
改造前的rowkey设计:
rowkey=segmentSalt+”_"+dataIndexInSegment+”_”+segmentId+”_”+jobTime+”_”+jobId
说明如下:
job:job对应运营在后台页面配置的任务,一个job可能多次运行,用jobId+jobTime可以唯一标识一个job的一次发送任务。
segment:一个job的一次发送任务拆分为多个segment,每个segment对应10万条消息。多个segment的消息可以并行发送。
segmentSalt:4位的随机字母,每个segment有一个salt,用于把数据均匀分散到Hbase的不同region中;
dataIndexInSegment:每条消息在segment中的序号,从0到99999;
改造前UTT按计划发送时间捞出要发送的segment后,从按0到99999的顺序从Hbase中读取消息,然后发送出去。为了提高效率使用了hbase的批量get方法。
这个设计存在一个很大的问题,同一个segment里的相邻消息的rowkey不是连续的,之间可能隔的非常远。
如下图所示,10000号消息rowkey和10000
1号消息rowkey之间可能隔了很多rowkey。
这会带来啥问题?这就需要了解Hbase的存储机制。
Hbase的存储是以storeFile为单位,以LSM树(Log-structured merge tree)方式存储。
此结构优化写性能,牺牲读性能。写数据的时候先按rowkey计算出region和store,顺序写入到store的memeStoreFile中,memoStoreFile达到指定大小后flush到磁盘的storeFile中。因此同一个store里,多个storeFile的rowkey的范围是会有重叠的。
按rowkey读取数据时,计算该rowkey可能存储的storeFile,把这些storeFile全部读取到内存中,最后把多个storeFile里查询到的结果合并后输出。
为了提高读性能,Hbase会在后台把多个storeFile进行merge,形成rowkey范围互不重叠的storeFile。
另外Hbase采用按列值KV方式存储数据,也就是说每个列的值都是独立存储的。每个列值KV对里的key包括了rowkey和列名,key里的大部分数据是重复的,storeFile采用压缩算法减小空间。
改造前同一个segment里的消息的rowkey很分散,读取一个segment的消息时要从磁盘上装载大量的storeFile,消耗大量的cpu进行解压缩,这也会导致storeFile 的cache命中率不高。并且读出来的大部分storeFile是没有包含所需数据的。
分析UTT的场景,多个segment是并发读写的,每个segment有segmentSalt,保证了读写均匀分布到Hbase的不同region。如果读取一个segment的消息时能从尽量少的storeFile读取数据,就能够减少磁盘IO,减少解压缩及数据查找的CPU,还能提高storeFile cache的命中率。
改造后的rowkey设计:
rowkey=segmentSalt+”_”+jobTime+”_”+jobId+”_”+segmentId+”_”+dataIndexInSegment(前补零到定长5位)
这样多个segment并发读写均匀分散到不同region,同一个segment的消息顺序写到相同的storeFile中,读取的时候不再使用get方法而是使用scan方法。最后qps提升了一个数量级。
附一个hbase的知识脑图,不知道作者是谁,挺好的。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
HBase详细说明
HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统。 适合于存储大表数据(表的规模可以达到数十亿行以及数百万列),并且对大表数据的读、写访问可以达到实时级别; 利用Hadoop HDFS(Hadoop Distributed File System)作为其文件存储系统,提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统; 利用ZooKeeper作为协同服务。 与RMDB比较: HBase 分布式存储,面向列。 动态扩展列。 普通商用硬件支持,扩容成本低。 RMDB 数据结构固定。 需要预先定义好数据结构。 需要大量IO,扩展成本大。 HBase适合具有如下需求的应用: 海量数据(TB、PB) 高吞吐量 需要在海量数据中实现高效的随机读取 需要很好的性能伸缩能力 能够同时处理结构化和非结构化的数据 不需要完全拥有传统关系型数据库所具备的ACID特性 数据结构介绍: 结构化数据 具有固定的结构,属性划分,以及类型等信息。我们通常所理解的关系型数据库中所存储的数据信息,大多是结构化数据, 如职工信息表,拥有ID、Name、Phone、Addr...
- 下一篇
分布式系统学习共性总结:
1.归纳法: 对标与参考 适配与裁剪 2..术法道,深入源码体系 先分析该系统是数据存储还是计算系统。 如果是数据存储系统,从数据分布和副本策略开始入手 哈希:ElasticSearch 范围:HBase 数据量:HDFS 一致性:Cassan 副本读取 副本更新 副本切换 如果是数据处理问题,从数据投递策略入手。 离线 实时 微批 at most once at least once exactly once 2 .读对应系统架构图,对应着常用的架构模型,每个组件和已有的系统进行类比,想一下这个组件类似于hdfs的namenode等等,最后在脑海里梳理下数据流的整个流程。 3.在了解了系统的大概,着重看下文档中fault tolerence章节,看系统如何容错,或者自己可以预先问些问题,比如如果一个节点挂了、一个任务挂了系统是如何处理这些异常的,带着问题看文档。 4.文档详细读了一遍,就可以按照官方文档写些hello world的例子了,详细查看下系统配置项,随着工作的深入就可以看些系统的细节和关键源码了。 转自:https://blog.csdn.net/tg229dvt5i93m...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS关闭SELinux安全模块
- Linux系统CentOS6、CentOS7手动修改IP地址
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Red5直播服务器,属于Java语言的直播服务器