HBase如何合理设置客户端Write Buffer

 HBase客户端API提供了Write Buffer的方式,即批量提交一批Put对象到HBase服务端。

1. 什么时候需要Write Buffer?

默认情况下,一次Put操作即要与Region Server执行一次RPC操作,其执行过程可以被拆分为以下三个部分:

T1:RTT(Round-Trip Time),即网络往返时延,它指从客户端发送数据开始,到客户端收到来自服务端的确认,总共经历的时延,不包括数据传输的时间;

T2:数据传输时间,即Put所操作的数据在客户端与服务端之间传输所消耗的时间开销,当数据量大的时候,T2的时间开销不容忽略;

T3:服务端处理时间,对于Put操作,即写入WAL日志(如果设置了WAL标识为true)、更新MemStore等。

其中,T2和T3都是不可避免的时间开销,那么能不能减少T1呢?假设我们将多次Put操作打包起来一次性提交到服务端,则可以将T1部分的总时间从T1 * N降低为T1,其中T1指的是单次RTT时间,N为Put的记录条数。

正是出于上述考虑,HBase为用户提供了客户端缓存批量提交的方式(即Write Buffer)。假设RTT的时间较长,如1ms,则该种方式能够显著提高整个集群的写入性能。

那么,什么场景下适用于该种模式呢?下面简单分析一下:

如果Put提交的是小数据(如KB级别甚至更小)记录,那么T2很小,因此,通过该种模式减少T1的开销,能够明显提高写入性能。

如果Put提交的是大数据(如MB级别)记录,那么T2可能已经远大于T1,此时T1与T2相比可以被忽略,因此,使用该种模式并不能得到很好的性能提升,不建议通过增大Write Buffer大小来使用该种模式。

2. 如何配置使用Write Buffer?

如果要启动Write Buffer模式,则调用HTable的以下API将auto flush设置为false:

  1. void setAutoFlush(boolean autoFlush) 

默认配置下,Write Buffer大小为2MB,可以根据应用实际情况,通过以下任意方式进行自定义:

1)  调用HTable接口设置,仅对该HTable对象起作用:

  1. void setWriteBufferSize(long writeBufferSize) throws IOException 

2)  在hbase-site.xml中配置,所有HTable都生效(下面设置为5MB):

  1. <property> 
  2. <name>hbase.client.write.buffer</name> 
  3. <value>5242880</value> 
  4. </property> 

该种模式下向服务端提交的时机分为显式和隐式两种情况:

1)  显式提交:用户调用flushCommits()进行提交;

2)  隐式提交:当Write Buffer满了,客户端会自动执行提交;或者调用了HTable的close()方法时无条件执行提交操作。

3. 如何确定每次flushCommits()时实际的RPC次数?

客户端提交后,所有的Put操作可能涉及不同的行,然后客户端负责将这些Put对象根据row key按照 region server分组,再按region server打包后提交到region server,每个region server做一次RPC请求。如下图所示:

4. 如何确定每次flushCommits()时提交的记录条数?

下面我们先从HBase存储原理层面“粗略”分析下HBase中的一条Put记录格式:

HBase中Put对象的大小主要由若干个KeyValue对的大小决定(Put继承自org/apache/hadoop/hbase/client/Mutation.java,具体见Mutation的代码所示),而KeyValue类中自带的字段占用约50~60 bytes(参考源码:org/apache/hadoop/hbase/KeyValue.java),那么客户端Put一行数据时,假设column qualifier个数为N,row key长度为L1 bytes,value总长度为L2 bytes,则该Put对象占用大小可按以下公式预估:

Put Size = ((50~60) + L1) * N + L2) bytes

下面我们通过对HBase的源码分析来进一步验证以上理论估算值:

HBase客户端执行put操作后,会调用put.heapSize()累加当前客户端buffer中的数据,满足以下条件则调用flushCommits()将客户端数据提交到服务端:

1)每次put方法调用时可能传入的是一个List<Put>,此时每隔DOPUT_WB_CHECK条(默认为10条),检查当前缓存数据是否超过writeBufferSize,超过则强制执行刷新;

2)autoFlush被设置为true,此次put方法调用后执行一次刷新;

3)autoFlush被设置为false,但当前缓存数据已超过设定的writeBufferSize,则执行刷新。

  1. private void doPut(final List<Put> puts) throws IOException { 
  2.        int n = 0; 
  3.        for (Put put : puts) { 
  4.            validatePut(put); 
  5.            writeBuffer.add(put); 
  6.            currentWriteBufferSize += put.heapSize(); 
  7.            // we need to periodically see if the writebuffer is full instead  
  8.            // of waiting until the end of the List 
  9.            n++; 
  10.            if (n % DOPUT_WB_CHECK == 0 
  11.                    && currentWriteBufferSize > writeBufferSize) { 
  12.                flushCommits(); 
  13.            } 
  14.        } 
  15.        if (autoFlush || currentWriteBufferSize > writeBufferSize) { 
  16.            flushCommits(); 
  17.        } 
  18.    } 

由上述代码可见,通过put.heapSize()累加客户端的缓存数据,作为判断的依据;那么,我们可以编写一个简单的程序生成Put对象,调用其heapSize()方法,就能得到一行数据实际占用的客户端缓存大小(该程序需要传递上述三个变量:N,L1,L2作为参数):

  1. import org.apache.hadoop.hbase.client.Put; 
  2. import org.apache.hadoop.hbase.util.Bytes; 
  3.  
  4. public class PutHeapSize { 
  5.     /** 
  6.      * @param args 
  7.      */ 
  8.     public static void main(String[] args) { 
  9.         if (args.length != 3) { 
  10.             System.out.println("Invalid number of parameters: 3 parameters!"); 
  11.             System.exit(1); 
  12.         } 
  13.         int N = Integer.parseInt(args[0]); 
  14.         int L1 = Integer.parseInt(args[1]); 
  15.         int L2 = Integer.parseInt(args[2]); 
  16.         byte[] rowKey = new byte[L1]; 
  17.         byte[] value = null
  18.         Put put = new Put(rowKey); 
  19.         for (int i = 0; i < N; i++) { 
  20.             put.add(Bytes.toBytes("cf"), Bytes.toBytes("c" + i), value); 
  21.         } 
  22.         System.out.println("Put Size: " + (put.heapSize() + L2) + " bytes"); 
  23.     } 

该程序可以用来预估当前设置的write buffer可以一次性批量提交的记录数:

  1. Puts Per Commit = Write Buffer Size / Put Size 

更进一步地,如果知道业务中的每秒产生的数据量,就可知道客户端大概多长时间会隐式调用flushCommits()向服务端提交一次;同时也可反过来根据数据实时刷新频率调整Write Buffer大小。

5. Write Buffer有什么潜在的问题?

首先,Write Buffer存在于客户端的本地内存中,那么当客户端运行出现问题时,会导致在Write Buffer中未提交的数据丢失;由于HBase服务端还未收到这些数据,因此也无法通过WAL日志等方式进行数据恢复。

其次,Write Buffer方式本身会占用客户端和HBase服务端的内存开销,具体见下节的详细分析。

6. 如何预估Write Buffer占用的内存?

客户端通过Write Buffer方式提交的话,会导致客户端和服务端均有一定的额外内存开销,Write Buffer Size越大,则占用的内存越大。客户端占用的内存开销可以粗略使用以下公式预估:

  1. hbase.client.write.buffer * number of HTable object for writing 

而对于服务端来说,可以使用以下公式预估占用的Region Server总内存开销:

  1. hbase.client.write.buffer * hbase.regionserver.handler.count * number of region server 

其中,hbase.regionserver.handler.count为每个Region Server上配置的RPC Handler线程数。

原文链接:http://www.cnblogs.com/panfeng412/archive/2012/10/16/how-to-use-hbase-client-write-buffer.html

【编辑推荐】

  1. 让数据库变快的10个建议
  2. 利用Java进行MySql数据库的导入和导出
  3. 20个数据库设计最佳实践
  4. 超越MySQL 对流行数据库进行分支
  5. 迎接大数据时代,高手较量数据库迁移实战方案

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/259444.html<

(0)
管理的头像管理
上一篇2025-05-02 17:03
下一篇 2025-05-02 17:04

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注