【hbase】Hbase最佳实践

编程

1. 存储

1.1. 压缩

hbase默认不使用压缩进行存储,一般情况下,hbase是以大表的方式存在,如果不进行压缩的话,势必会造成空间的浪费。而且由于hbase是对随机访问进行优化的,所以需要采用压缩解压效率较高的算法。

压缩比大的算法但速度慢的算法,比如gzip,不太适合。推荐使用LZO和SNAPY压缩,以损失部分空间换取较高的响应速度。

1.2. 块大小

hbase块大小指定。默认值为64M,这个值和hadoop的块大小不太一样,hadoop的块大小是在文件存储时生效,hbase的块大小是指memstore一次性写入filestore的大小或者由filestore一次性读入memstore的大小。

对于数据读写比较频繁的表,需要适当调大hbase blocksize,可以减少大量的磁盘IO操作,同时提高读写效率。<-此项没有经过实际的测试,是否正确需要探讨

1.3 布隆过滤器(bloomfilter)

指定布隆过滤器理论上可以提高读写速度,但会损失一定的存储空间用来保存索引。

2. 参数配置

2.1. 正确设置Scan Caching的行数

  • 含义:Caching是Server端一次返回数据的行数,默认值是100,意即一次RPC请求中,Server端获取到100行数据后一次性返回;
  • 影响:

    • 若Caching值设置过大,RegionServer需要在内存中存储所有需要返回的结果,可能导致OutOfMemory;
    • 若Caching值设置过大,Server获取这些数据需要很长时间(尤其是设置了过滤器),可能导致OutOfOrderScannerNextException;
    • 若Caching值设置过小,则获取N行数据需要N/Caching次RPC请求,速度慢;

  • 设置:通过scan.setCaching()进行设置,接受的配置是行数,不是Byte,建议根据返回的总数据量进行估算,总额是10MB;若一行是10KB,cache设置为1000;若一行是2MB,cache设置为5。

2.2. 正确设置WriteBuffer大小

大量的Put请求,请关闭autoFlush(),避免每一个Put请求都向Server端发送RPC请求

  • 含义:客户端会累积Put请求,当数据累积到Buffer大小时,触发一次RPC请求。
  • 风险:若客户端程序崩溃,则Buffer之中的Put请求会丢失!
  • 影响:

    • 若设置太大,则会导致OutOfMemory
    • 若设置太小,则触发多次RPC请求;

  • 设置:

    • htable.setAutoFlush(false) # 启用Write Buffer,默认不启用
    • htable.setWriteBufferSize(long writeBufferSize) #参数是Byte,建议2MB~5MB,一般不允许超过10MB。若设置为5MB,则是htable.setBufferSize(510241024)。

2.3. 正确设置Batch大小

  • 含义:当行很大的时候,Batch设置每次next()返回的列数。例如一个表有10000行,设置Caching=10,Batch=100,则每100列被当做一个Result,每次RPC返回10 个Result即1000列;
  • 影响:对于很大的行,需要设置合理的Batch大小,以免发生OOME。
  • 设置:scan.setBatch()进行设置,接受的是batch的列数。

2.4. 客户端配置项

部分参数客户端的配置会覆盖服务器端的配置,入口机的配置由服务云统一维护,非入口机的配置则需要用户自己维护;

请非入口机用户检查自己hbase-site.xml中的配置是否为最新的值,可以从入口机下载最新的配置。

<property> <name>hbase.client.pause</name> <value>100</value> </property> <property> <name>hbase.client.retries.number</name> <value>31</value> </property>

3. 批量导入使用Bulkload

当大批量导入数据的时候,推荐使用HFileOutFormat(Bulkload),使用单个Client导数据瓶颈在Client,无法充分利用HBase的扩展性。

4. 避免跨集群访问

跨集群访问,速度可能慢20倍。例如相同的代码,在入口机(同机房)只要12-20s,在跨机房机器执行需要400-800s。

5. 使用Append

一种常见的需求是,需要append一个Cell的值,而不是创建新的Cell。例如,某一列存储了用户访问的URL列表,有一个程序自动记录。一种做法是Get,Modify,Put;而使用Append能方便地原子添加新值。

# Append example, table is "user-table", row is "usser", column name is "c:url" hbase shell> append "user-table", "user1", "c:url", "firstUrl" # value is "firstUrl" hbase shell> append "user-table", "user1", "c:url", "anotherUrl" # value is "firstUrlanotherUrl"

注意:该操作对于读不是原子的。Append会拿行锁,保证写操作是同步的。但是读操作不获取该写锁,因此Get和Scan可能会看到一个部分完成的状态。

例子:RowA有两列 C1=V1,C2=V2,现在对RowA执行Append操作,C1=Vx,C2=Vy,则Get可能看到如下中间状态C1=V1+Vx, C2=V2。

以上是 【hbase】Hbase最佳实践 的全部内容, 来源链接: utcz.com/z/516816.html

回到顶部