当前位置: 首页 > 科技观察

HBase性能优化四点

时间:2023-03-12 04:30:21 科技观察

1hbase.hregion.max.filesize应该设置多少默认值:256M说明:最大HStoreFile大小。如果任何一个列族的HStoreFiles增长到超过这个值,则托管HRegion的最大值被分成两个HStoreFile。如果任何一个ColumnFamily(或HStore)的HStoreFiles的大小超过了这个值,那么它所属的HRegion就会被一分为二。调优:hbase中hfile(hbase.hregion.max.filesize)默认最大值为256MB,Google的bigtable论文中tablet的最大值也推荐为100-200MB。这个尺寸的秘密是什么??  众所周知,hbase中的数据一开始会写入memstore,当memstore写满64MB时,就会刷入磁盘,成为storefile。当storefile的数量超过3个时,将开始压缩过程,将它们合并为一个storefile。在这个过程中,一些时间戳过期的数据会被删除,比如更新数据。而当合并后的storefile的大小大于hfile默认的最大值时,就会触发split动作,将其拆分成两个region。  lz进行了连续插入压力测试,设置了不同的hbase.hregion.max.filesize。根据结果??得出以下结论:该值越小,平均吞吐量越大,但吞吐量越不稳定;值越大,平均吞吐量越小,吞吐量不稳定的时间越少。  为什么会这样?推论如下:a.当hbase.hregion.max.filesize比较小时,触发split的概率较大,split过程中region会离线,所以在split结束前,访问region的请求会被阻塞,而client端自阻塞时间默认为1s。当大量区域同时拆分时,系统整体接入服务将受到较大影响。因此容易出现吞吐量和响应时间的不稳定b当hbase.hregion.max.filesize比较大时,单个region触发split的概率较小,大量region触发split的概率同时也很小,所以吞吐量比较低。hfile越小越稳定。但是,由于长时间得不到split,导致同一region发生多次compaction的几率增加。compaction的原理是读取原始数据重写到hdfs,然后删除原始数据。毫无疑问,这种行为会拖慢以io为瓶颈的系统,因此平均吞吐量会下降并产生一定影响。综合以上两种情况,hbase.hregion.max.filesize不宜过大或过小,256MB可能是比较理想的经验参数。对于离线应用,调整为128MB比较合适,而对于在线应用,除非修改拆分机制,否则不应低于256MB2autoflush=false的影响  官方和很多博客都提倡提高hbase写入速度的性能,在应用代码中设置autoflush=false,然后lz觉得这个设置在在线应用中要慎重。原因如下:  aautoflush=false原理是当客户端提交delete或put请求时,请求缓存在客户端,直到数据超过2M(由hbase.client.write.buffer决定)或者用户执行hbase请求时,只有在调用.flushcommits()时才会提交到regionserver。因此,即使htable.put()执行成功返回,也不代表请求真的成功了。如果客户端没有到达缓存就崩溃了,这部分数据就会丢失,因为它没有发送到regionserver。这对于零容忍的在线服务来说是不可接受的。  bautoflush=true会降低写入速度2-3倍,但是很多线上应用必须开启,这也是hbase为什么让默认值为true的原因。当值为true时,每次请求都会发送到regionserver,regionserver收到请求后第一件事就是写入hlog,所以对io的要求很高,为了提高hbase的写入速度,应该尝试yourbest可以增加io吞吐量,比如加磁盘,使用raid卡,减少replicationfactor的个数等。3.从性能的角度,说说表中family和qualifier的设置当在hbase上建模,如何从性能角度设置family和qualifier?  是最极端的,①每一列都设置一个family,②一张表只有一个family,所有列都是限定符之一,那么有什么区别呢?  从阅读的角度看:  家族越多,获取每个cell的数据优势越明显,因为io和network都减少了。  如果只有一家,那么每次读取都会读取当前rowkey的所有数据,在network和io上会有一些损失。  当然,如果要获取固定列数的数据,最好将这些列写成一个族,而不是单独设置族,因为一次请求就可以检索到所有数据。  从写法上看:  首先在内存方面,对于一个Region,每个表中的每个Family都会分配一个Store,每个Store都会分配一个MemStore,所以family越多,内存消耗越大.  其次,在flush和compaction方面,当前版本的hbase都是以region为单位进行flush和compaction的,也就是说,当一个family达到flush条件时,该region中所有family的memstores会被flush一次,即使memstore中只有少量数据,也会触发flush,生成小文件。这样就增加了compaction的概率,而且compaction也是基于region的,所以很容易出现compaction风暴,降低系统的整体吞吐量。  第三,从split的角度来看,由于hfile是以family为单位的,对于多个family,将数据分散到更多的hfile中,降低了split的概率。这是一把双刃剑。更少的分裂将导致更大的区域体积。由于平衡是根据区域的数量而不是大小来进行的,因此可能会导致平衡失败。从好的方面来说,更少的拆分将使系统能够提供更稳定的在线服务。并且可以通过在请求的低谷时间手动拆分和平衡来避免这些缺点。所以,对于一个写的比较多的系统,如果是离线应用,我们应该尽量只用一个家庭,但是如果是在线应用,就应该根据应用情况合理分配。4hbase.regionserver.handler.countRegionServer端开启的RPC监听器实例数,即RegionServer可以处理的IO请求线程数。默认为10。该参数与内存密切相关。设置此值时,以监控内存为主要参考。对于单次请求内存消耗大的BigPUT场景(设置了大容量的单次PUT或者设置了大缓存的扫描,都属于BigPUT)或者ReigonServer内存比较紧张,可以设置它比较小。对于单次请求内存消耗较低,对TPS(TransactionPerSecond,每秒事务处理量)要求很高的场景,可以设置的相对大一些。原文链接:https://img.ydisp.cn/news/20220804/uzsshqwtgw5.html【编辑推荐】HBase设计:看起来很漂亮Impala能否取代HiveIDC分析师对中国大数据市场的10大预测