背景

hbase主集群在生产环境已稳定运行有1年半时间,最大的单表region数已达7200多个,每天新增入库量就有百亿条,对hbase的认识经历了懵懂到熟的过程。为了应对业务数据的压力,hbase入库也由最初的单机多线程升级为有容灾机制的分布式入库,为及早发现集群中的问题,还开发了一套对hbase集群服务和应用全面监控的报警系统。总结下hbase优化(针对0.94版本)方面的一些经验也算对这两年hbase工作的一个描述。

服务端

1.hbase.regionserver.handler.count:rpc请求的线程数量,默认值是10,生产环境建议使用100,也不是越大越好,特别是当请求内容很大的时候,比如scan/put几M的数据,会占用过多的内存,有可能导致频繁的GC,甚至出现内存溢出。


2.hbase.master.distributed.log.splitting:默认值为true,建议设为false。关闭hbase的分布式日志切割,在log需要replay时,由master来负责重放


3.hbase.regionserver.hlog.splitlog.writer.threads:默认值是3,建议设为10,日志切割所用的线程数


4.hbase.snapshot.enabled:快照功能,默认是false(不开启),建议设为true,特别是对某些关键的表,定时用快照做备份是一个不错的选择。


5.hbase.hregion.max.filesize:默认是10G, 如果任何一个column familiy里的StoreFile超过这个值, 那么这个Region会一分为二,因为region分裂会有短暂的region下线时间(通常在5s以内),为减少对业务端的影响,建议手动定时分裂,可以设置为60G。


6.hbase.hregion.majorcompaction:hbase的region主合并的间隔时间,默认为1天,建议设置为0,禁止自动的major主合并,major合并会把一个store下所有的storefile重写为一个storefile文件,在合并过程中还会把有删除标识的数据删除,在生产集群中,主合并能持续数小时之久,为减少对业务的影响,建议在业务低峰期进行手动或者通过脚本或者api定期进行major合并。


7.hbase.hregion.memstore.flush.size:默认值128M,单位字节,一旦有memstore超过该值将被flush,如果regionserver的jvm内存比较充足(16G以上),可以调整为256M。


8.hbase.hregion.memstore.block.multiplier:默认值2,如果一个memstore的内存大小已经超过hbase.hregion.memstore.flush.size *  hbase.hregion.memstore.block.multiplier,则会阻塞该memstore的写操作,为避免阻塞,建议设置为5,如果太大,则会有OOM的风险。如果在regionserver日志中出现"Blocking updates for '<threadName>' on region <regionName> : memstore size <多少M> is >= than blocking <多少M> size"的信息时,说明这个值该调整了。


9.hbase.hstore.compaction.min:默认值为3,如果任何一个store里的storefile总数超过该值,会触发默认的合并操作,可以设置5~8,在手动的定期major compact中进行storefile文件的合并,减少合并的次数,不过这会延长合并的时间,以前的对应参数为hbase.hstore.compactionThreshold。


10.hbase.hstore.compaction.max:默认值为10,一次最多合并多少个storefile,避免OOM。


11.hbase.hstore.blockingStoreFiles:默认为7,如果任何一个store(非.META.表里的store)的storefile的文件数大于该值,则在flush memstore前先进行split或者compact,同时把该region添加到flushQueue,延时刷新,这期间会阻塞写操作直到compact完成或者超过hbase.hstore.blockingWaitTime(默认90s)配置的时间,可以设置为30,避免memstore不及时flush。当regionserver运行日志中出现大量的“Region <regionName> has too many store files; delaying flush up to 90000ms"时,说明这个值需要调整了


12.hbase.regionserver.global.memstore.upperLimit:默认值0.4,regionserver所有memstore占用内存在总内存中的upper比例,当达到该值,则会从整个regionserver中找出最需要flush的region进行flush,直到总内存比例降到该数以下,采用默认值即可。


13.hbase.regionserver.global.memstore.lowerLimit:默认值0.35,采用默认值即可。


14.hbase.regionserver.thread.compaction.small:默认值为1,regionserver做Minor Compaction时线程池里线程数目,可以设置为5。


15.hbase.regionserver.thread.compaction.large:默认值为1,regionserver做Major Compaction时线程池里线程数目,可以设置为8。


16.hbase.regionserver.lease.period:默认值60000(60s),客户端连接regionserver的租约超时时间,客户端必须在这个时间内汇报,否则则认为客户端已死掉。这个最好根据实际业务情况进行调整


17.hfile.block.cache.size:默认值0.25,regionserver的block cache的内存大小限制,在偏向读的业务中,可以适当调大该值,需要注意的是hbase.regionserver.global.memstore.upperLimit的值和hfile.block.cache.size的值之和必须小于0.8。


18.dfs.socket.timeout:默认值60000(60s),建议根据实际regionserver的日志监控发现了异常进行合理的设置,比如我们设为900000,这个参数的修改需要同时更改hdfs-site.xml


19.dfs.datanode.socket.write.timeout:默认480000(480s),有时regionserver做合并时,可能会出现datanode写超时的情况,480000 millis timeout while waiting for channel to be ready for write,这个参数的修改需要同时更改hdfs-site.xml

jvm和垃圾收集参数:

export HBASE_REGIONSERVER_OPTS="-Xms36g -Xmx36g -Xmn1g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=15 -XX:CMSInitiatingOccupancyFraction=70 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/data/logs/gc-$(hostname)-hbase.log"

由于我们服务器内存较大(96G),我们给一部分regionserver的jvm内存开到64G,到现在为止,还没有发生过一次full gc,hbase在内存使用控制方面确实下了不少功夫,比如各种blockcache的实现,细心的同学可以看源码。

Client端

1.hbase.client.write.buffer:默认为2M,写缓存大小,推荐设置为5M,单位是字节,当然越大占用的内存越多,此外测试过设为10M下的入库性能,反而没有5M好

2.hbase.client.pause:默认是1000(1s),如果你希望低延时的读或者写,建议设为200,这个值通常用于失败重试,region寻找等

3.hbase.client.retries.number:默认值是10,客户端最多重试次数,可以设为11,结合上面的参数,共重试时间71s

4.hbase.ipc.client.tcpnodelay:默认是false,建议设为true,关闭消息缓冲

5.hbase.client.scanner.caching:scan缓存,默认为1,避免占用过多的client和rs的内存,一般1000以内合理,如果一条数据太大,则应该设置一个较小的值,通常是设置业务需求的一次查询的数据条数

如果是扫描数据对下次查询没有帮助,则可以设置scan的setCacheBlocks为false,避免使用缓存;

6.table用完需关闭,关闭scanner

7.限定扫描范围:指定列簇或者指定要查询的列,指定startRow和endRow

8.使用Filter可大量减少网络消耗

9.通过java多线程入库和查询,并控制超时时间。后面会共享下我的hbase单机多线程入库的代码

10.建表注意事项:

开启压缩

合理的设计rowkey

进行预分区

开启bloomfilter

zookeeper调优

1.zookeeper.session.timeout:默认值3分钟,不可配置太短,避免session超时,hbase停止服务,线上生产环境由于配置为1分钟,如果太长,当regionserver挂掉,zk还得等待这个超时时间(已有patch修复),从而导致master不能及时对region进行迁移。

2.zookeeper数量:建议5个或者7个节点。给每个zookeeper 4G左右的内存,最好有独立的磁盘。

3.hbase.zookeeper.property.maxClientCnxns:zk的最大连接数,默认为300,无需调整。

4.设置操作系统的swappiness为0,则在物理内存不够的情况下才会使用交换分区,避免GC回收时会花费更多的时间,当超过zk的session超时时间则会出现regionserver宕机的误报

hdfs调优

1.dfs.name.dir:namenode的数据存放地址,可以配置多个,位于不同的磁盘并配置一个nfs远程文件系统,这样namenode的数据可以有多个备份

2.dfs.namenode.handler.count:namenode节点RPC的处理线程数,默认为10,可以设置为60

3.dfs.datanode.handler.count:datanode节点RPC的处理线程数,默认为3,可以设置为30

4.dfs.datanode.max.xcievers:datanode同时处理文件的上限,默认为256,可以设置为8192

其它

列族名、column名、rowkey均会存储到hfile中,因此这几项在设计表结构时都尽量短些

regionserver的region数量不要过1000,过多的region会导致产生很多memstore,可能会导致内存溢出,也会增加major compact的耗时

转载请注明原文链接:http://blog.csdn.net/odailidong/article/details/41794403

Hbase万亿级存储性能优化总结的更多相关文章

  1. 【HBase调优】Hbase万亿级存储性能优化总结

    背景:HBase主集群在生产环境已稳定运行有1年半时间,最大的单表region数已达7200多个,每天新增入库量就有百亿条,对HBase的认识经历了懵懂到熟的过程.为了应对业务数据的压力,HBase入 ...

  2. 亿级 Elasticsearch 性能优化

    前言 最近一年使用 Elasticsearch 完成亿级别日志搜索平台「ELK」,亿级别的分布式跟踪系统.在设计这些系统的过程中,底层都是采用 Elasticsearch 来做数据的存储,并且数据量都 ...

  3. 杂文笔记《Redis在万亿级日访问量下的中断优化》

    杂文笔记<Redis在万亿级日访问量下的中断优化> Redis在万亿级日访问量下的中断优化 https://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA= ...

  4. Kafka万亿级消息实战

    一.Kafka应用 本文主要总结当Kafka集群流量达到 万亿级记录/天或者十万亿级记录/天  甚至更高后,我们需要具备哪些能力才能保障集群高可用.高可靠.高性能.高吞吐.安全的运行. 这里总结内容主 ...

  5. 腾讯自研万亿级消息中间件TubeMQ为什么要捐赠给Apache?

    导语 | 近日,云+社区技术沙龙“腾讯开源技术”圆满落幕.本次沙龙邀请了多位腾讯技术专家围绕腾讯开源与各位开发者进行探讨,深度揭秘了腾讯开源项目TencentOS tiny.TubeMQ.Kona J ...

  6. 如何基于MindSpore实现万亿级参数模型算法?

    摘要:近来,增大模型规模成为了提升模型性能的主要手段.特别是NLP领域的自监督预训练语言模型,规模越来越大,从GPT3的1750亿参数,到Switch Transformer的16000亿参数,又是一 ...

  7. HBase最佳实践-写性能优化策略

    本篇文章来说道说道如何诊断HBase写数据的异常问题以及优化写性能.和读相比,HBase写数据流程倒是显得很简单:数据先顺序写入HLog,再写入对应的缓存Memstore,当Memstore中数据大小 ...

  8. SQL Server 2016 查询存储性能优化小结

    SQL Server 2016已经发布了有半年多,相信还有很多小伙伴还没有开始使用,今天我们来谈谈SQL Server 2016 查询存储性能优化,希望大家能够喜欢 作为一个DBA,排除SQL Ser ...

  9. 万亿级KV存储架构与实践

    一.KV 存储发展历程 我们第一代的分布式 KV 存储如下图左侧的架构所示,相信很多公司都经历过这个阶段.在客户端内做一致性哈希,在后端部署很多的 Memcached 实例,这样就实现了最基本的 KV ...

随机推荐

  1. Python3 标准库:calendar,time

    1.calendar import calendar print(calendar.month(2008,8)) #某个月 print(calendar.calendar(2008)) #某年 pri ...

  2. Python3 数据类型-字典

    字典是一种可变数据类型,且可存储任意类型对象. 字典使用大括号"{}"括起来,由键(key)和值(values)组成,键只能使用不可变类型定义,值可以使用可变类型{'键':'值'} ...

  3. 微信小程序如何获取openid

    微信小程序如何获取openid wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId // ...

  4. js经典试题之w3规范系列

    js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...

  5. NFC学习总结二

    移动支付这事情热了总归还是会回归理性,就如同之前的10几年间的几次轮回一样.字面上看,移动支付比支付大也不大可能,有相同,有扩展,有交集有不通才是. NFC这事情也是说了快十年了,真心希望它能回归到其 ...

  6. 第一章 Windows编程基础(1~4课)

    第一课:从main到WinMain 第二课:窗口和消息 第三课:MFC编程 第四课:MFC应用程序框架 概括: Win32的两种编程框架:SDK方式.MFC方式 1. SDK方式:使用WinMain入 ...

  7. 你代码写得这么丑,一定是因为你长得不好看----panboo第一篇博客

    一.个人介绍 我叫潘博,软嵌162,学号1613072055. 以“panboo”名称混迹于各大开源IT论坛与博客. 除了编程,我的最大爱好是篮球与健身,热衷于各种IT技术与运动. 我做过的软件项目有 ...

  8. HTTP 请求头 & 响应头

    HTTP请求头概述 HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者POST).如有必要,客户程序还可以选择发送其他的请求头.大多数请求头并不是必需的, 但Co ...

  9. Java中ArrayList与数组间相互转换

    在实际的 Java 开发中,如何选择数据结构是一个非常重要的问题. 衡量标准化(读的效率与改的效率) : ① Array: 读快改慢 ② Linked :改快读慢 ③ Hash:介于两者之间 实现Li ...

  10. Python的7种性能测试工具:timeit、profile、cProfile、line_profiler、memory_profiler、PyCharm图形化性能测试工具、objgraph

    1.timeit: >>> import timeit >>> def fun(): ): a = i * i >>> timeit.timeit ...