《Hbae权威指南》读书笔记
书为2013年9月的第一版。
列式数据库
- 基于假设:“对于特定的查询不是所有的值都是必须的”。这个假设不仅说明了一般的适用场景,而且Hbase中很多的优化都是基于列的优化,使用的时候要先考虑是否用到了此特性,发挥了Hbase的特长。
- 如果有了以上假设,那么列式存储的优点是什么呢?——减少IO。而且列相似性很高,便于压缩,对于列式存储而言,压缩是很重的技术。压缩了,从磁盘的IO会减少,虽然会有一定的CPU的浪费,但是总性能是提高的。优点类似于CPU或IO,ES中也很多类似的设计,如文档同步后再进行索引重建,还有ES的FST结构。
RDBMS的等待和死锁与事务和并发的关系
RDBMS的等待和死锁的出现频率,与事务和并发的增加并不是线性关系,准确地说,与并发数目的平方以及事务规模的3次方甚至5次方相关。
与MapReduce存在的一个在一起的两个理由
- Hbase并不是CPU密集型的,很多时候是在顺序的读磁盘。而Hbae+Spark或MapReduce能够利用机器上的CPU资源,更加充分的利用硬件。
- 部署在一起,从本地读取,IO效率高,而且节省了网络的IO资源。
行键在HFile中的定位作用
把HFile打开并加载到内存中时,索引信息会优先加载到内存中,每个块的大小默认是64KB。
每一个HFile都有一个块索引,通过一个磁盘查找就可以实现查询。首先,在内存的快索引中进行二分查找,确定可能包含给定键的块,然后读取磁盘块找到实际要找的键。
master节点的工作
主服务器不是实际数据存储或者检索路径的组成部分,它仅提供了负载均衡和集群管理,不为region服务器或者客户端提供任何的数据服务,因此是轻量级的服务器。此外,主服务器还提供了元数据的管理操作,如建表和创建列族
路由信息,由Zk和root表和mete表提供,master并不提供。在ES中可以有专门做路由的transport节点,有类似也的单独的master节点,配置node.master为true的时候,有可能被选举为主节点。
而且,ES也可以配置一个节点为专门的“路由节点”,node.master和node.data都设置为false的时候,该节点可以作为客户端节点,可以响应用户的情况,把相关操作发送到其他节点。另外,不同的时,ES还有一种tribe节点,能够连接其他的集群进行查询操作。
此外,ES还有一种节点,只做协调作用:
收到用户请求的节点被称为协调节点,请求的处理可以分为两个阶段:
- scatter 阶段。协调节点将请求转发给持有数据的节点。每个节点在本地执行请求,并将结果返回给协调节点。
- gather 阶段。协调节点将收到的结果归并,然后返回给用户。
每个节点都是隐式的协调节点,node.master, node.data 和 node.ingest 都为 false的节点是纯粹的协调节点。
单台服务器的region大小和数目
按照现在的硬件能力,每台服务器的最佳加载数量差不多还是10~1000,但每个region的最佳大小是1GB~2GB
region的数量和每个region的最佳存储大小取决于单台服务器的有效处理能力。
上面的“现在”指的是2013年。后面一句的“有效处理能力”也太抽象了。
管理较少的region可以让集群运行的更平稳。一个region变为热点后,用户可以手动拆分大的region并将负载分散到集群中。
在默认的情况下,region的大小是256MB。用户可以配置1GB或者更大的region。注意该参数的大小要仔细评估,大的region意味着在高负载的情况下合并的停顿时间更长。
如果实际应用中,数据没有修改,只是insert,也没有delete,合并的速度是不是会更快,这种情况下是不是大一点的region更加合适呢?
直接参考官网配置Bigger Regions中的一些文字具体原因可以参考原文:
Consider going to larger regions to cut down on the total number of regions on your cluster. Generally less Regions to manage makes for a smoother running cluster (You can always later manually split the big Regions should one prove hot and you want to spread the request load over the cluster). A lower number of regions is preferred, generally in the range of 20 to low-hundreds per RegionServer. Adjust the regionsize as appropriate to achieve this number.
Typically you want to keep your region count low on HBase for numerous reasons. Usually right around 100 regions per RegionServer has yielded the best results.
磁盘
通常情况下,用户应该保证每个磁盘上至少有一个核,所以在8核心的机器上增加6块磁盘是较优的,更多的磁盘可能不会带来显著的性能提升。
对于slave节点来说(Region Server、DataNode、TaskTracker)不推荐使用RAID模式,而是使用JBOD模式。
对master节点(NameNode、SecondNameNode、Hbase Master、JobTracker),通常的配置是RAID1+0或RAID0+1。
一般更推荐使用SATA驱动器,因为SATA比SAS更节省成本,虽然SAS安全新高于SATA。
京东查了下,7200的盘,1T的SATA盘只要300块,而SAS的要将近1000块。
操作系统配置
禁用文件的访问时间可以大幅度提高磁盘的读取性能。
集群中节点时间必须是一致的,仅仅一分钟的偏差就有可能产生莫名其妙的行为。
MongoDB禁用这最后访问时间不知道性能是否有提升。
批操作
一般情况下,在LAN网络中大约要花费1毫秒的时间,这意味着1秒钟内只能完成1000次RPC的往返响应。
与Kafka类似,producer会有自己的缓存,而不是立刻就提交到broker。Hbase中有类似的方法:
table.setAutoFlush(false)
启用客户端的缓冲机制,数据会保存在客户端的进程中,并按照要put的RegionServer对put操作分组合并,最后批量的提交到RegionServer中。
同样的,与kafka类似,服务器也有对client的缓存,而且客户端缓存大,服务端对应的缓存也会相应变大。如果单元格的数据较大,如是图片数据,那么传输的速度是瓶颈,而不是缓存的大小,这个时候,设置大的缓存意义并不大。
另外,有put参数为list的操作和类似cas的操作,MongoDB也有类似操作。批量的list的操作是基于batch方式的,在batch方式下,不会再缓存,而是执行的时候直接发送到服务器。
scan特性
扫描的区间是左闭右开的,[startRow, stopRow)。
用户提供的参数不必精确匹配这两行。扫描会匹配相等或大于给定的起始行的键。如果没有显示地指定起始行,它会从表的起始位置开始获取数据。
扫描器的next()方法调用都会生成一个单独的RPC请求,默认情况下是关闭的。
用户需要为少量的RPC请求次数和客户端以及服务器端的内存消耗找到平衡点。很多时候,将扫描器设的比较高能提高扫描的性能,不过设得太高就会产生不良影响:每次next()调用会占用更长时间,因为要获取更多的文件并传输到客户端。
这个值可能需要根据业务针对表,内存的使用情况,是否为大量读取,综合考虑。
压缩算法
2011年之前,一般使用LZO,而11年后,Google的Snappy算法有更快的压缩速度。Snappy的压缩率为22.2%。相当于原来数据的五分之一。