Mysql&Hbase面对结构化数据存储的大长尾问题

前言:

有幸接触着大数据结构化式存储的实际问题,海量数据通过我们熟知的社交网络衍生而爆发式的增长,数据的长尾越来越大,今天分析下熟知的分布式数据库(Hbase)和RDMS(Mysql)如何解决我们“大长尾”问题。

正文:

长尾(The Long Tail):

长尾英语:The Long Tail),或译长尾效应,最初由《连线》的总编辑克里斯·安德森(Chris Anderson)于2004年发表于自家的杂志中[1],用来描述诸如亚马逊公司NetflixReal.com/Rhapsody之类的网站之商业和经济模式。是指那些原来不受到重视的销量小但种类多的产品或服务由于总量巨大,累积起来的总收益超过主流产品的现象。在互联网领域,长尾效应尤为显著。长尾这一术语也在统计学中被使用,通常应用在财产的分布和词汇的使用。 — http://zh.wikipedia.org/wiki/%E9%95%BF%E5%B0%BE

https://i1.wp.com/upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Long_tail.svg/320px-Long_tail.svg.png

图中黄色部分即为我们本次讨论的重点。

数据库存储长尾问题

我们知道一般对于互联网应用来说最新更新的数据是最热的,最近一个星期发出的请求可能占总数据请求量的80%,最近一个月数据的请求量可能占总请求量的90%,这一部分我们采用一致性hash等内存扩容方就可以很好地解决,而一个月以前甚至数年以前的总请求量只会占用10%。但我们要清楚的是,我们访问量较小的数据容量是不断增长的!如果你每天将产生1亿条数据,传统解决方案使用Memcache+Mysql的方案很好的解决了这最近的一个星期的问题,访问量大的请求被缓存在内存当中。但是对于不断增长的历史数据,尤其当整体数据量都很大的情况(你需要几十台server的CPU、内存、网卡、磁盘IO及容量才能够应对),这个问题将非常明显,面对这个问题我们如何处理呢?

为什么对比Mysql和Hbase?

Mysql&Hbase是互联网解决数据从内存平滑(这两个字很重要向磁盘过度的重要利器。不像Redis及Memcache,Couchbase尽量回避磁盘的读写,这里没有选择PostgreSQL,Mongodb,Cassandra的原因也是Mysql及Hbase的社区相较活跃,使用人群相对广泛,当然最重要的原因是对Mysql及Hbase相对比较熟悉。

Mysql解决方案

1.数据归档 之前我们采用mysql自身replication进行历史数据的归档和压缩的方式,将历时数据降级至低配置设备上,也很好的解决了这个问题。replication过滤规则可参看http://www.xdata.me/?p=14

2.Enough sharding+Flashcache 我们按照我们的读写需求(通常为磁盘性能及容量)进行sharding,分散至不同Mysql Master-Slave集群中去,当然由于大量历史数据的存在,Flashcache是必须要尝试的。推荐@NinGoo 同学的flashcache深入浅出系列 http://www.ningoo.net/html/tag/flashcache

3.压缩&其他

… (未完待续)

Mysql数据如何从内存过度到磁盘:

…未完待续

总而言之就是将最新的数据尽量存储在内存和Flash设备上,老数据逐渐淘汰至SAS,SATA盘上,但是可以想象这其中还有很多人工干预及产品方面的影响,还是很多成本,但是值得肯定得是在每天读写请求量没有明显变化,数据容量可以支撑的情况下,Mysql将是相当稳定的。

Hbase解决方案

Hbase有很好的扩展性,但是缺点也是不言而喻的,只是一个分布式的kv系统,很多现有的系统需要重新schema design及重洗数据,或者很多查询需求就是满足不了的,很多数据库方面的验证、事务等方面还是很薄弱,但是仅仅是由于第一点我们还是很值得尝试的。

说说Hbase的数据如何从内存过度到磁盘:

Hbase regionserver主要占用内存可配置memstore (写入buffer)及blockcache(读取cache)的大小(Ted Yu曾表示未来将同mysql一样不需要人工配置比例,只需要一开始指定类似regionserver的大小,buffer及cache比则是自动调整,很期待)

export HBASE_REGIONSERVER_OPTS=”-Xms20g -Xmx20g …”

  <property>
<name>hfile.block.cache.size</name>
<value>0.5</value>
</property>
<property>
<name>hbase.regionserver.global.memstore.upperLimit</name>
<value>0.3</value>
</property>
<property>
<name>hbase.regionserver.global.memstore.lowerLimit</name>
<value>0.25</value>
</property>

这样我们就很好规划出我们Hbase大致有多少内存资源用来cache block,比如你regionserver如果有20G内存,在一个10 regionserver服务器的情况下,的那么你将有10*10=100G的内存来cache你的block。

“当MemStore满了以后会Flush成一个StoreFile(底层实现是HFile),当StoreFile文件数量增长到一定阈值,会触发Compact合并操作,将多个StoreFiles合并成一个StoreFile,合并过程中会进行版本合并和数据删除 ” 引自 http://www.searchtb.com/2011/01/understanding-hbase.html

Hbase的数据是保存在hdfs上的,也就上免得Flush和compact操作,这个读写的速度会受到hdfs dfsclient 及datanode 交互这一层的限制,但是这点我们无需过多担心,hdfs已经成为现有的最好分布式文件系统之一,针对hbase的读写优化的提案非常多,更重要的是从此之后分工明确,hdfs管理磁盘数据,压缩和磁盘读写优化只要改动hdfs代码就可以,hbase只用关心真正数据库需要解决的get/set,事务、数据一致性等等。

确定下你的数据容量:

假设这个hdfs集群只有hbase应用,我们粗略的预估约有11.32T的数据,在计算了hbase压缩比约为38%,的情况下,我们认为我们的数据容量越有11.32T/3 replicate /38%=9.92T,那么我们的内存和磁盘的比例约为100GB:10168.32GB 约为1:100。而更为振奋的是这个比例我们可进行较为方便的调整。

随着淘宝对Hbase的贡献,Hbase二级缓存的功能也已经merge入主干,为我们利用SSD等flash设备,和更大内存提供了更广阔的的思考空间。

Hbase的二级缓存详解:

http://zjushch.iteye.com/blog/1751387  Hbase Commiter出品,将提高单机性能,此篇必读。

说说Hbase先天的扩展优势:

Hbase对有一张meta表来存储数据路由信息,即rowkey范围及regionserver的对应关系,而meta表存储格式也是hbase的一个普通表,他所在的reigonserver地址被直接记入了zookeeper当中,这样客户端想确定我的数据在哪儿时,就首先获取下meta表位置,然后查询下我得table及rowkey在那个regionserver上,然后直接同regionserver交互。当然客户端不会每次请求都和zookeeper做一次交互,每次交互的结果都会缓存在客户端,指到请求失败才会清掉本地cache,再次去zookeeper中请求新的数据。这样zk的压力就小了很多。

https://i0.wp.com/blog.cloudera.com/wp-content/uploads/2013/04/fig3.png

https://i1.wp.com/blog.cloudera.com/wp-content/uploads/2013/04/fig2.png

而regions则会被hmaster balance入各个regionserver,后随着单region的记录数增加,触发splite条件一般为hbase.hregion.max.filesize,会对其进行splite,找到region的middlekey,之后一分为二成为两个region,当然这是一个完整事务,之后会随着balance入不同的regionserver进行负载方面的均衡:

https://i2.wp.com/blog.cloudera.com/wp-content/uploads/2013/04/fig1.png

假想两个非常大的Mysql Cluster和Hbase Cluster随着业务的增长,在12个月内非别对Mysql Cluster做了两次扩容,对Hbase Cluster根据利用率进行线性扩展:

说明:横轴我们可以理解为时间增长或者业务量整张,纵轴可以理解为服务器比值及利用率比值。

RDMS由于横向扩展能力较差,在不影响线上服务的情况下,在扩容上可能会有额外的成本开销,比如周转临时服务器、拆分后短时间利用率较低的情况。而对分布式数据库则能尽量能利用率和cluster node的平缓增长,尤其当集群服务器个数较大之后,这对于成本来说将是一次巨大的优化。

Hbase是不是足够好?

答案是否定的!列举几个Hbase仍然将要面对的问题

0.Hbase还仅是一个设计很好的kv系统

对于各种各样的读取需要还没有很好的应对方法,另外对于常用的客户单php python C客户端还是有很多问题有待解决。

1.大内存JVM的GC问题

JVM的通病

2.读写响应时间不够稳定

之前使用ycsb做的简单单表put压测,可以看到还是有性能毛刺,这说明splite,flush,compaction都有很大的优化空间。

3.成熟的备份和安全机制

只能期待0.96早点release了,当然解决大多数备份和安全问题还是个长远目标。

4.多机房部署及数据的同步

Hbase目前还是不支持多点写入的,replication还没有大规模的应用,需要一段时间的验证。

5.Regionserver宕机影响

单台Regionserver的宕机也会对业务读写造成短时间的影响。

…等等

总结

解决大长尾问题其实是一个很复杂的问题,我们需要的不仅仅是一个解决方案,而且是一个考虑成本、可靠性、易维护性等等因素的方案。这将是一个数据库不倦的一个追求。在数据膨胀时代,从长远成本考虑,大型公司都应该着手调研或者开发适合自己场景的分布式数据库。而从短期成本考虑,中小型公司从付出的时间和回报率上来看,使用成熟的RDMS方案还是非常推荐的。

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s