深入探讨为什么HBase Scan性能低下

栏目: 数据库 · 发布时间: 5年前

内容简介:原文:https://blog.51cto.com/12445535/2359652与写流程对比起来,HBase读数据是一个更加复杂的操作流程,这主要基于两个方面的原因:其一是因为整个HBase存储引擎基于LSM-Tree实现,因此一次范围查询可能会涉及多个分片、多块缓存甚至多个数据存储文件;

原文:https://blog.51cto.com/12445535/2359652

与写流程对比起来,HBase读数据是一个更加复杂的操作流程,这主要基于两个方面的原因:

其一是因为整个HBase存储引擎基于LSM-Tree实现,因此一次范围查询可能会涉及多个分片、多块缓存甚至多个数据存储文件;

其二是因为HBase中更新操作以及删除操作实现都很简单,更新操作并没有更新原有数据,而是使用时间戳属性实现了多版本。删除操作也并没有真正删除原有数据,只是插入了一条打上"deleted"标签的数据,而真正的数据删除发生在系统异步执行Major_Compact的时候。

很显然,这种实现套路大大简化了数据更新、删除流程,但是对于数据读取来说却意味着套上了层层枷锁,读取过程需要根据版本进行过滤,同时对已经标记删除的数据也要进行过滤。

Scan流程

1、一次scan请求,先在客户端缓存中找,如果找到了后,就直接返回给客户端。

2、如果没有找到再在 BlockCache、HFile以及memcache 中一行一行进行扫描,扫到100行之后,就返回给客户端。

3、客户端将这100行数据缓存到内存中并返回给一条给上层业务。

这里是每次都会调用100行数据,客户端拿到之后,再扫描100条数据,直到数 据被全部拿到。

上层业务不断一条一条获取扫描数据,在数据量大的情况下实际上HBase客户端会不断发送next请求到HBase服务器。有的朋友可能会问为什么scan需要设计为多次next请求的模式?个人认为这是基于多个层面的考虑:

1、HBase本身存储了海量数据,所以很多场景下一次scan请求的数据量都会比较大。如果不限制每次请求的数据集大小,很可能会导致系统带宽吃紧从而造成整个集群的不稳定。

2、如果不限制每次请求的数据集大小,很多情况下可能会造成客户端缓存OOM掉。

3、如果不限制每次请求的数据集大小,很可能服务器端扫描大量数据会花费大量时间,客户端和服务器端的连接就会timeout。

get的批处理操作是按照目标region进行分组,不同分组的get请求会并发执行读取。然而scan并没有这样实现。 

也就是说,scan不是并行操作。

所以从客户端角度来看整个扫描时间=客户端处理数据时间+服务器端扫描数据时间,这能不能优化?

根据上面的分析,scan API的效率很大程度上取决于扫描的数据量。通常建议OL TP业务中少量数据量扫描的scan可以使用scan API。大量数据的扫描使用scan API,扫描性能有时候并不能够得到有效保证。

引出问题

HBase作为列式存储,为什么它的scan性能这么低呢,列式存储不是更有利于scan操作么?Parquet格式也是列式,但它的scan这么优秀,他们的性能差异并不是因为数据组织方式造成的么?Kudu也是采用的类LSM数据结构,但是却能达到Parquet的扫描速度(Kudu是纯列式的),Kudu的一个列也会形成很多文件,但是好像并没影响它的性能。

小结

1、HBase不完全是列式存储,确切的说是列族式存储,HBase中可以定义一个列族,列族下可以有都个列,这些列的数据是存在一起的。而且通常情况下我们建议列族个数不大于2个,这样的话每个列族下面必然会有很多列。因此HBase并不是列式存储,更有点像行式存储。

2、HBase扫描本质上是一个一个的随即读,不能做到像HDFS(Parquet)这样的顺序扫描。试想,1000w数据一条一条get出来,性能必然不会很好。

那么问题就来了,HBase为什么不支持顺序扫描?

这是因为HBase支持更新操作以及多版本的概念,这个很重要。可以说如果支持更新操作以及多版本的话,扫描性能就不会太好。原理是这样的,我们知道HBase是一个类LSM数据结构,数据写入之后先写入内存,内存达到一定程度就会形成一个文件,因此HBase的一个列族会有很多文件存在。因为更新以及多版本的原因,一个数据就可能存在于多个文件,所以需要一个文件一个文件 查找才能定位出具体数据。

所以HBase架构本身个人认为并不适合做大规模scan,很大规模的scan建议还是用Parquet,可以把HBase定期导出到Parquet来scan。

3、Kudu性能并没有达到Parquet的扫描速度,可以说介于HBase和Parquet之间:

  • Kudu比HBase扫描性能好,是因为Kudu是纯列存,扫描不会出现跳跃读的情况,而HBase可能会跳跃seek。这是本质的区别。

  • 但Kudu扫描性能又没有Parquet好,就是因为Kudu是LSM结构,它扫描的时候还是会同时顺序扫描多个文件,并比较key值大小。而Parquet只需要顺序对一个block块中的数据进行扫描即可。这个是两者的区别。

所以说HBase相比Parquet,这两个方面都是scan的劣势。

参考链接:

H Base原理-数据读取流程解析

http://hbasefly.com/2016/12/21/hbase-getorscan/

HBase最佳实践 – Scan用法大观园 

http://hbasefly.com/2017/10/29/hbase-scan-3/


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

全景探秘游戏设计艺术

全景探秘游戏设计艺术

Jesse Schell / 吕阳、蒋韬、唐文 / 电子工业出版社 / 2010-6 / 69.00元

撬开你脑子里的那些困惑,让你重新认识游戏设计的真谛,人人都可以成为成功的游戏设计者!从更多的角度去审视你的游戏,从不完美的想法中跳脱出来,从枯燥的游戏设计理论中发现理论也可以这样好玩。本书主要内容包括:游戏的体验、构成游戏的元素、元素支撑的主题、游戏的改进、游戏机制、游戏中的角色、游戏设计团队、如何开发好的游戏、如何推销游戏、设计者的责任等。 本书适合任何游戏设计平台的游戏设计从业人员或即将......一起来看看 《全景探秘游戏设计艺术》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试