Hbase1.3 生产优化,源码分析

简介: Hbase1.3 生产优化,源码分析

问题分析

  • 思路:分离读写scan请求,各种处理各自的 源码内部 WriteQueues; Queues; ScanQueues;
  • 优化参数
hbase.regionserver.handler.count:默认为30,服务器端用来处理用户请求的线程数。生产线上通常需要将该值调到100~200。线上:128
hbase.ipc.server.callqueue.handler.factor : 默认为0,服务器端设置队列个数,假如该值为0.1,那么服务器就会设置handler.count * 0.1 = 30 * 0.1 = 3个队列。线上:0.2
hbase.ipc.server.callqueue.read.ratio : 默认为0,服务器端设置读写业务分别占用的队列百分比以及handler百分比。假如该值为0.5,表示读写各占一半队列,同时各占一半handler。线上:0.6
hbase.ipc.server.call.queue.scan.ratio:默认为0,服务器端为了将get和scan隔离设置了该参数。线上:0.1

hbase.ipc.server.call.queue.scan.ratio 默认0

scan请求直接打入read队列长时间不释放,导致正常read超时告警

  • 源码理解

HRegionServer类构造函数入口

1. rpcServices = createRpcServices();
2. rpcSchedulerFactory = getRpcSchedulerFactoryClass().asSubclass(RpcSchedulerFactory.class).getDeclaredConstructor().newInstance();
3. SimpleRpcSchedulerFactory.create 创建SimpleRpcScheduler
4. SimpleRpcScheduler构造函数中创建RWQueueRpcExecutor
5. if (callqReadShare > 0) {
6.       // at least 1 read handler and 1 write handler
7.       callExecutor = new RWQueueRpcExecutor("default.RWQ", Math.max(2, handlerCount),
8.         maxQueueLength, priority, conf, server);
9.     }

   5. RWQueueRpcExecutor构造函数中初始化相关参数


public RWQueueRpcExecutor(final String name, final int handlerCount, final int maxQueueLength,
      final PriorityFunction priority, final Configuration conf, final Abortable abortable) {
    super(name, handlerCount, maxQueueLength, priority, conf, abortable);
    //默认为0,服务器端设置读写业务分别占用的队列百分比以及handler百分比。
    //假如该值为0.5,表示读写各占一半队列,同时各占一半handler
    float callqReadShare = getReadShare(conf);
    // hbase.ipc.server.callqueue.scan.ratio=0.2
    float callqScanShare = getScanShare(conf);
    //写队列 10*0.5=5对列数
    numWriteQueues = calcNumWriters(this.numCallQueues, callqReadShare);
    //线程数 100*0.5=50
    writeHandlersCount = Math.max(numWriteQueues, calcNumWriters(handlerCount, callqReadShare));
    //numCallQueues减去写队列数 10-5=5
    int readQueues = calcNumReaders(this.numCallQueues, callqReadShare);
    //线程数 50
    int readHandlers = Math.max(readQueues, calcNumReaders(handlerCount, callqReadShare));
    //scanQueues = 5*0.2=1
    int scanQueues = Math.max(0, (int)Math.floor(readQueues * callqScanShare));
    //scanQueues = 50*0.2=10
    int scanHandlers = Math.max(0, (int)Math.floor(readHandlers * callqScanShare));
    if ((readQueues - scanQueues) > 0) {
      //readQueues=5-1=4 因为scan也属于读的一部分,所以scan要从read中扣取一部分资源
      readQueues -= scanQueues;
      //readQueues=50-10=40
      readHandlers -= scanHandlers;
    } else {
      scanQueues = 0;
      scanHandlers = 0;
    }
    numReadQueues = readQueues;
    readHandlersCount = readHandlers;
    numScanQueues = scanQueues;
    scanHandlersCount = scanHandlers;
    //队列分负载均衡,策咯是随机打入一个相关队列
    this.writeBalancer = getBalancer(numWriteQueues);
    this.readBalancer = getBalancer(numReadQueues);
    this.scanBalancer = numScanQueues > 0 ? getBalancer(numScanQueues) : null;
    initializeQueues(numWriteQueues);
    initializeQueues(numReadQueues);
    initializeQueues(numScanQueues);

总结

regionserver服务端使用的ReadQueues,WriteQueues,ScanQueues来代替传统线程池处理客户端读写请求,每个对列都有对等比例的线程hbase.regionserver.handler.count消费队列,负载均衡策咯比如ReadQueues使用的随机策咯getNextQueue.ThreadLocalRandom.current().nextInt(queueSize)

问题复现:

可以使用阿里的arthas进行regionserver的线程状态分析

  • 队列计算

handler.count 是100,就是regionserver总处理读写请求线程数100个 队列个数是hbase.regionserver.handler.count100 x 0.1(hbase.ipc.server.callqueue.handler.factor) = 10,读写请求队列总个数 写队列个数 10 x 0.5hbase.ipc.server.callqueue.read.ratio = 5 读队列个数 10 x 0.5 = 5,请注意,这里读请求,包含get和scan,所以有这个scan.ratio参数是占用read的比例 get 队列 5 - 5 x 0.2hbase.ipc.server.call.queue.scan.ratio = 4 scan队列 5 x 0.2 = 1

  • 队列消费线程数计算

线程比例和队列比例相同 比如 write消费线程数:100乘以0.5=50 get消费线程数:100乘以0.4=40 scan消费线程数:100乘以0.1=10


相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
|
机器学习/深度学习 分布式计算 Hadoop
一种HBase表数据迁移方法的优化
一种HBase表数据迁移方法的优化
96 0
|
存储 缓存 算法
HBase优化之路-合理的使用编码压缩
为什么要讨论HBase编码压缩 编码+压缩能够成倍的减少数据的磁盘占用空间,节省可观的存储费用 编码+压缩通常情况下可以提高系统吞吐率,让系统可以做更多的功 默认建表不启用编码或者压缩,对初学者不友好 了解HBase编码 举个栗子,我们有一张物流表叫"express",记录物流订单的流转详情。
4442 0
|
4月前
|
缓存 监控 Java
"Java垃圾回收太耗时?阿里HBase GC优化秘籍大公开,让你的应用性能飙升90%!"
【8月更文挑战第17天】阿里巴巴在HBase实践中成功将Java垃圾回收(GC)时间降低90%。通过选用G1垃圾回收器、精细调整JVM参数(如设置堆大小、目标停顿时间等)、优化代码减少内存分配(如使用对象池和缓存),并利用监控工具分析GC行为,有效缓解了高并发大数据场景下的性能瓶颈,极大提升了系统运行效率。
107 4
|
存储 SQL 消息中间件
Kylin 在贝壳的性能挑战和 HBase 优化实践(2)
Kylin 在贝壳的性能挑战和 HBase 优化实践
139 0
Kylin 在贝壳的性能挑战和 HBase 优化实践(2)
|
SQL 分布式计算 监控
Kylin 在贝壳的性能挑战和 HBase 优化实践(1)
Kylin 在贝壳的性能挑战和 HBase 优化实践
132 0
Kylin 在贝壳的性能挑战和 HBase 优化实践(1)
|
缓存 安全 Java
HBase 优化_3 | 学习笔记
快速学习 HBase 优化_3
164 0
|
存储 缓存 分布式数据库
HBase 优化_2 | 学习笔记
快速学习 HBase 优化_2
122 0
|
存储 负载均衡 分布式数据库
HBase 优化_1 | 学习笔记
快速学习 HBase 优化_1
134 0
|
存储 监控 物联网
解密 云HBase时序引擎OpenTSDB 优化技术
逝者如斯夫,不舍昼夜。                                                       —— 孔子 时间如流水,一去不复返。自古不乏对时间流逝的感慨,而现代已经有很多技术记录流逝的过去。
2459 0
解密 云HBase时序引擎OpenTSDB 优化技术