HBase数据写入测试
测试环境
测试硬件:4核i5处理器,8G内存,1T硬盘,千兆网络
测试软件:Ubuntu 12.10 64位,Hadoop版本:0.20.205,hbase版本:0.90.5
测试设置:一个master(namenode)和三台resigonServer(datanode),向HBase集群写入1千万个数据(一个数据15K左右)
测试结果
上图第一列和最后一列分别是插入相同数据再HBase中和HDFS中,可以看见差距很大,HBase上数据的插入时间是HDFS的10倍左右
向HBase中插入数据比HDFS性能差这么多,笔者就研究一下是什么原因让HBase写性能这么不好。向HBase中插入数据的过程大致是这样:client插入数据时先向master请求,master回复哪个resigionserver的哪个region可以给插入数据,然后client直接和resigionserver通信插入数据,resigionserver判断该数据插入到哪个datablock里(resigion是由datablock组成的),然后以HFile的形式存储在HDFS中(数据不一定在resigionserver本地)。
影响HBase写入性能的一个因素就是用put类插入数据的缓存区问题。用put类插入数据时,默认的情况是写入一次数据由clinet和resigionserver进行一次RPC来插入数据。由于是1千万个数据,多次进行进程间通信势必会影响时间。HBase给客户端提供了写缓冲区,当缓冲区填满之后才执行写入操作,这样就减少了写入的测次数。
首先取消自动写入,setAutoFlush(false)
然后设置写缓冲区大小(默认是2MB)setWriteBufferSize()或者更改hbase-site.xml的hbase.client.write.buffer的属性
上面列表可以看出把缓冲区设为20M还是对写入时间有改进,但是改成200M写入时间更长(为什么?)
另一个因素就是WAL(write ahead log),因为每一个resigion都有一个memstore用内存来暂时存放数据,进行排序,最后再吸入HFile里面去,这样做为了减少磁盘寻道而节省时间,但是为了灾难恢复,所以会把内存中的数据进行记录。所以笔者把WAL关闭之后,又测了下性能,还是有一点帮助的,但是帮助不是太大,可见WAL不是写入的瓶颈。(setWriteToWal(false))
因为HBase对查询方便,能够快速的读取数据,写入时必然会采取一些措施进行排序,这就是HBase的合并和分裂机制。HBase官方为了提升写入性能,给出一种方案就是预分配resigion,也就是池的概念,你先分配一些resigion,用的时候直接用就行了。本来这1千万个数据要存储900个resigion,所以笔者预先分配了150个resigion(分配900个resigion,建表时间太长,出现异常,还没有解决),结果写入时间提升了很多,基本是原来的一半,如果能预先分配900个resigion,应该更能节省时间。