背景
最近有个简单的需求,离线数据挖掘得出的标签需要支持online的查询,查询场景比较简单,支持按照单个id或者多个id批量查询,tp99需要在200ms,批量的时候id 集合的大小不会超过1000,平均下来不会超过200的样子。这种场景直接上ES相对来说比较省事,不过ES占用资源较多,想尝试用hbase来解决这种场景,下面记录下具体的过程。
为何要考虑HBase?
为何要用hbase呢?离线数据是存放在hive表里面的,虽然hbase导入hbase和es都挺方便的,不过据我们测试的情况看,hive2hbase采用bulkload 的方式会快些,而且比较简单。导入es的过程中步骤繁琐,需要设置刷新时间和副本数,设置段合并和别名之类的操作,相对来说麻烦许多。hbase按照 rowkey查询的性能还行,单次查询在10+ms左右,虽然支持索引,不过性能差强人意,暂时不准备利用其自身的索引。 只利用hbase来存储元信息,这些信息相对来说比较占空间,仅支持按照 rowkey来查找。
HBase的若干问题
- rowkey的设计,这个关系到数据是否分布均匀,一般根据业务场景强相关,我们这个就是按照id来设计的查询,前期考虑根据id的首个数字来进行划分,后来发现 region server 存在严重的热点问题,看了下数据才发现,我们的id是子增的,而且id比较大,主要都落到2,3开头的region里面了,对于自增的id可以采用id%n 的方法来划分,最终采用n=60,最后看了下分布到每个 regionserver 的数据非常均匀,基本都在410W左右。
- 预分区可以均衡读写压力,老生常谈的问题了
- 列可以动态增加,对于每行数据不一样的应用比较适合,为null的列是不会进行存储的,这一点很灵活
- 热点的问题,在均衡了rowkey的设计之后,可以使得访问请求能均衡的分布到每个region server,不过从压测的情况看,数据的rt 波动比较大, 因为blockcache 不是表级别的,全局的lru比较容易被踢出来,如果被踢出来的话,需要去读hfile了。
- 因为hbase 是按照column family存储的,其列名是会保存在keyvalue里面的,比较占用空间,可以简短一点,另外,读取数据的过程也是按照column family读取的,涉及到storeFileScanner的切换,效率会有些影响,不过这块没有具体测试过,column family不要超过3个,有时候业务字段拆分成不同的column family更为合理,不过对性能的影响需要再深入测试。
- 我们的业务场景是所有数据都要轮一遍,所以blockcache对我们没啥用,从压测的结果看200 个 id的情况下,tp99在270ms,对staging进行测试,同机房内,qps也就40多,这个结果比较惨。
- 对线上机器进行了观察,发现hbase的region server的memory 和heap使用率都挺高的,比ES的机器配置要高很多了,不符合花小钱搞事情的原则。
丢不掉的ES
在对hbase进行测试之后,id超过200之后,hbase性能直线下降,很难符合线上的要求了,只能再转回ES了。事实上,在使用hbase之前,我们设想是通过es+hbase或者es+tair来进行对比,这两种场景因为对索引和数据进行了拆分,性能很难和直接利用es进行查询相比,最后转了个圈,还是回到ES上面了,索引信息存储在es里面,由于es存储的信息极其简单,2.5亿的记录索引,经过优化存储,只占用了9G的空间,200个id查询的 rt 也就30ms左右,性能还是比较稳定的。ES的优点如下:
- es集群还是比较可靠的,性能杠杠的,之前想着节省资源的情况下用用hbase,不过hbase的blockcache 也不小,es虽然是虚机,单台只有8G,但还是比较稳定的
- es可以通过disable source, 只index而不 store,启用best compress (可以省 1/3 的空间) 等达到最大利用率
- es 的吞度量还是不错的,同样的压测,qps是hbase的4倍,rt只有hbase的一半不到。
ES的问题
- ES做简单的查询还行,不过要小心返回结果可能并不是你所想的,es 为了提升检索效率,有些地方是用的近似值,用集合查询的时候,from to 下,会受限制与window size 的大小,有时候返回的结果不稳定而且不全,这个测试的时候发现了,还是比较坑的。
- filter方式因为不计算score和存在缓存的方式,性能一般情况下是ok的,不过据压测情况看,filter的tp90虽然比query快了大概10ms,但是tp99 的曲线波动的很厉害,远不如query 的tp99平稳,说明性能是有较大的波动的
- 根据2做了些研究,es的cache是基于node级别的,有query和filter的cache,query只缓存count类型的查询,filter缓存采用lru机制,会根据filter条件做缓存,采用的是bitset,既然是lru,肯定会有换入换出,怀疑是抖动的原因,如果有大牛知道,欢迎指正。
一般做系统方案的时候,还是需要根据具体业务场景来区分,复杂不一定好,皮实耐用才是真道理,根据具体场景来做优化,有时候也能收到意想不到的效果。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。