提高HBase写性能
以下为使用hbase一段时间的三个思考,由于在内存充足的情况下hbase能提供比较满意的读性能,因此写性能是思考的重点。希望读者提出不同意见讨论
1 autoflush=false的影响
无论是官方还是很多blog都提倡为了提高hbase的写入速度而在应用代码中设置autoflush=false,然后lz认为在在线应用中应该谨慎进行该设置。原因如下:
a autoflush=false的原理是当客户端提交delete或put请求时,将该请求在客户端缓存,直到数据超过2M(hbase.client.write.buffer决定)或用户执行了hbase.flushcommits()时才向regionserver提交请求。因此即使htable.put()执行返回成功,也并非说明请求真的成功了。假如还没有达到该缓存而client崩溃,该部分数据将由于未发送到regionserver而丢失。这对于零容忍的在线服务是不可接受的。
b autoflush=true虽然会让写入速度下降2-3倍,但是对于很多在线应用来说这都是必须打开的,也正是hbase为什么让它默认值为true的原因。当该值为true时,每次请求都会发往regionserver,而regionserver接收到请求后第一件事就是写hlog,因此对io的要求是非常高的,为了提高hbase的写入速度,应该尽可能高地提高io吞吐量,比如增加磁盘、使用raid卡、减少replication因子数等
2 hbase.hregion.max.filesize应该设置多少合适
hbase中hfile的默认最大值(hbase.hregion.max.filesize)是256MB,而google的bigtable论文中对tablet的最大值也推荐为100-200MB,这个大小有什么秘密呢?
众所周知hbase中数据一开始会写入memstore,当memstore满64MB以后,会flush到disk上而成为storefile。当storefile数量超过3时,会启动compaction过程将它们合并为一个storefile。这个过程中会删除一些timestamp过期的数据,比如update的数据。而当合并后的storefile大小大于hfile默认最大值时,会触发split动作,将它切分成两个region。
lz进行了持续insert压力测试,并设置了不同的hbase.hregion.max.filesize,根据结果得到如下结论:值越小,平均吞吐量越大,但吞吐量越不稳定;值越大,平均吞吐量越小,吞吐量不稳定的时间相对更小。
为什么会这样呢?推论如下:
a 当hbase.hregion.max.filesize比较小时,触发split的机率更大,而split的时候会将region offline,因此在split结束的时间前,访问该region的请求将被block住,客户端自我block的时间默认为1s。当大量的region同时发生split时,系统的整体访问服务将大受影响。因此容易出现吞吐量及响应时间的不稳定现象
b 当hbase.hregion.max.filesize比较大时,单个region中触发split的机率较小,大量region同时触发split的机率也较小,因此吞吐量较之小hfile尺寸更加稳定些。但是由于长期得不到split,因此同一个region内发生多次compaction的机会增加了。compaction的原理是将原有数据读一遍并重写一遍到hdfs上,然后再删除原有数据。无疑这种行为会降低以io为瓶颈的系统的速度,因此平均吞吐量会受到一些影响而下降。
综合以上两种情况,hbase.hregion.max.filesize不宜过大或过小,256MB或许是一个更理想的经验参数。对于离线型的应用,调整为128MB会更加合适一些,而在线应用除非对split机制进行改造,否则不应该低于256MB
3 从性能的角度谈table中family和qualifier的设置
对于传统关系型数据库中的一张table,在业务转换到hbase上建模时,从性能的角度应该如何设置family和qualifier呢?
最极端的,可以每一列都设置成一个family,也可以只有一个family,但所有列都是其中的一个qualifier,那么有什么区别呢?
family越多,那么获取每一个cell数据的优势越明显,因为io和网络都减少了,而如果只有一个family,那么每一次读都会读取当前rowkey的所有数据,网络和io上会有一些损失。
当然如果要获取的是固定的几列数据,那么把这几列写到一个family中比分别设置family要更好,因为只需一次请求就能拿回所有数据。
以上是从读的方面来考虑的,那么写呢?可以参考一下这篇文章:
http://hbase.apache.org/book/number.of.cfs.html
首先,不同的family是在同一个region下面。而每一个family都会分配一个memstore,所以更多的family会消耗更多的内存。
其次,目前版本的hbase,在flush和compaction都是以region为单位的,也就是说当一个family达到flush条件时,该region的所有family所属的memstore都会flush一次,即使memstore中只有很少的数据也会触发flush而生成小文件。这样就增加了compaction发生的机率,而compaction也是以region为单位的,这样就很容易发生compaction风暴从而降低系统的整体吞吐量。
第三,由于hfile是以family为单位的,因此对于多个family来说,数据被分散到了更多的hfile中,减小了split发生的机率。这是把双刃剑。更少的split会导致该region的体积比较大,由于balance是以region的数目而不是大小为单位来进行的,因此可能会导致balance失效。而从好的方面来说,更少的split会让系统提供更加稳定的在线服务。
上述第三点的好处对于在线应用来说是明显的,而坏处我们可以通过在请求的低谷时间进行人工的split和balance来避免掉。
因此对于写比较多的系统,如果是离线应该,我们尽量只用一个family好了,但如果是在线应用,那还是应该根据应用的情况合理地分配family
提高HBase写性能的更多相关文章
- HBase配置性能调优(转)
因官方Book Performance Tuning部分章节没有按配置项进行索引,不能达到快速查阅的效果.所以我以配置项驱动,重新整理了原文,并补充一些自己的理解,如有错误,欢迎指正. 配置优化 zo ...
- HBase配置性能调优
因官方Book Performance Tuning部分章节没有按配置项进行索引,不能达到快速查阅的效果.所以我以配置项驱动,重新整理了原文,并补充一些自己的理解,如有错误,欢迎指正. 配置优化 zo ...
- HBase最佳实践-写性能优化策略
本篇文章来说道说道如何诊断HBase写数据的异常问题以及优化写性能.和读相比,HBase写数据流程倒是显得很简单:数据先顺序写入HLog,再写入对应的缓存Memstore,当Memstore中数据大小 ...
- 怎样写SQL语句可以提高数据库的性能
1.首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录 ...
- 在程序开发中怎样写SQL语句可以提高数据库的性能
以下内容是公司dba总结. 1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来 ...
- 怎样提高hbase的入库性能
hbase写数据首先先写入memstore.当memstore满64MB以后,会flush到disk上而成为storefile.当storefile数量超过3时,会启动compaction过程将它们合 ...
- Hbase写数据,存数据,读数据的详细过程
Client写入 -> 存入MemStore,一直到MemStore满 -> Flush成一个StoreFile,直至增长到一定阈值 -> 出发Compact合并操作 -> 多 ...
- HBase写入性能改造(续)--MemStore、flush、compact参数调优及压缩卡的使用【转】
首先续上篇测试: 经过上一篇文章中对代码及参数的修改,Hbase的写入性能在不开Hlog的情况下从3~4万提高到了11万左右. 本篇主要介绍参数调整的方法,在HDFS上加上压缩卡,最后能达到的写入 ...
- HBase写请求分析
HBase作为分布式NoSQL数据库系统,不单支持宽列表.而且对于随机读写来说也具有较高的性能.在高性能的随机读写事务的同一时候.HBase也能保持事务的一致性. 眼下HBase仅仅支持行级别的事务一 ...
随机推荐
- x264源代码简单分析:编码器主干部分-1
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- Android必知必会-Android Studio修改包名
如果移动端访问不佳,请尝试–> Github版 背景 公司做相似产品较多,一般都是以某个产品为基础修改,逐步替换设计图的切图.这个就会导致需要经常为Copy的项目修改包名. 这里是参考一些网上的 ...
- JAVA之旅(二十六)——装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片
JAVA之旅(二十六)--装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片 一.装饰设计模式 其实我们自定义re ...
- UNIX网络编程——内网与外网间通信
QQ是一个基于TCP/UDP协议的通讯软件 发送消息的时候是UDP打洞,登陆的时候使用HTTP~因为登陆服务器其实就是一个HTTP服务器,只不过不是常用的那些,那个服务器是腾讯自行开发的!!! 一.登 ...
- Maven项目中获取classpath和资源文件的路径
假设资源文件放在maven工程的 src/main/resources 资源文件夹下,源码文件放在 src/main/java/下, 那么java文件夹和resources文件夹在运行时就是cl ...
- Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite
Android数据库框架--GreenDao轻量级的对象关系映射框架,永久告别sqlite 前不久,我在写了ORMLite这个框架的博文 Android数据库框架--ORMLite轻量级的对象关系映射 ...
- Swing——鼠标(Action)
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41346969 看完这篇文章,你可能会学到到知识如下: (1 ...
- 设计模式之——工厂模式(B)
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41142929 工厂方法模式定义了一个创建对象的接口,但由子 ...
- postman使用—chrome版
如果大家不知道怎么安装,请下载个FQ软件(蓝灯,shadowsocks)都是可以的,安装完成之后,你可以在chrome看到posman的插件程序. 使用说明: 安装完成之后,使用chrome://ap ...
- 学习tornado:异步
why asynchronous tornado是一个异步web framework,说是异步,是因为tornado server与client的网络交互是异步的,底层基于io event loop. ...