HBase优化 表设计的优化 写表的优化 读表的操作

1.预分区

建表时,预先创建一些空的Region,这样当数据写入HBase时,会按照Region分区情况,在集群内数据的负载均衡。

默认情况建表自动创建一个Region分区,导入数据的时候所有的HBase客户端都向这一个Region写数据,直到这个Region足够大了才进行切分。

2.rowkey的设计

RowKey规则:

1.越小越好(能满足业务需求的情况下)。

2.根据实际业务来。

3.散列性。

3.column Family

不要在一张表里定义太多的column family。目前HBase并不能很好的处理超过2~3个column family的表。因为某个column family在flush的时候,它的邻近的column family也会因关联效应引发flush,最终导致系统产生更多的IO。

4.In Memory

HColumnDescriptor.setInMemory(true) 

创建表的时候,可以将表放到RegionServer的缓存中,保证在读取的时候可以被缓存击中。

5.Max Version

HColumnDescriptor.setMaxVersions(int maxVersions) 

创建表的时候,可以设置表中数据的最大版本,如果只需保存最新版本的数据,那么设置为1,减少历史版本数据的存储空间。

6.Time To Live

HColumnDescriptor.setTimeToLive(int timeToLive) 

创建表的时候,可以设置表中数据的存储存活时间,过期数据自动被删除。

7.Compact&Split

实际应用中,可以手动进行Compact操作,将小的storefile合成相对大的storefile。HBase中有两种compaction。minjor compaction和major compaction.

可以将storefile设置的大些,减少split的发生。

写表的优化

1.多HTable并发写,提高写数据的吞吐量。

2.Auto Flush

HTable.setAutoFlush(false) 

关闭客户端的自动flush,这样批量写入数据到HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存时,才实际向HBase服务端发起写请求。

3.Write Buffer

HTable.setWriteBufferSize(writeBufferSize) 

可以设置客户端写buffer大小,如果当前写buffer中的数据大小达到设置的buffer值时,buffer就会被flush到服务端。

4.WAL LOG

Put.setWriteToWAL(false) Delete.setWriteToWAL(false) 

一些相对不是很重要的数据,允许少量丢失的情况下,管理WAL日志,可以提高数据写入的性能。会存在数据丢失的风险。

5.批量写

HTable.put(List<Put>) 

批量写入多行数据,只需一次网络I/O开销,对于对数据实时性要求高的情景下可能带来明显的性能提升。

6.多线程并发写

在客户端开启多个HTable写线程,每一个写线程负责一个HTable对象的flush操作,结合定时flush和写buffer。

数据量小时候:短时间内被flush。

数据量大时候:写buffer一满就及时flush。

读表的操作

1.多HTable并发读

创建多个HTable客户端用于读操作,提高读数据的吞吐量

static final Configuration conf = HBaseConfiguration.create(); 
static final String table_log_name = “user_log”; 
rTableLog = new HTable[tableN]; 
for (int i = 0; i < tableN; i++) {
	rTableLog[i] = new HTable(conf, table_log_name);   
	rTableLog[i].setScannerCaching(50); 
} 

2.多线程并发读

在客户端开启多个HTable读线程,每个读线程负责通过HTable对象进行get操作。

3.批量读

HTable.get(List<Get>) 

根据一个指定row key列表,批量获取多行记录。批量执行,只需一次网路IO开销,对于对数据实时性要求不高而且网络传输RTT高的情景下可能带来明显的性能提升。

4.Scanner Cacheing

从服务端抓取数据,默认是一次一条。通过设置成一个合理的值,可以减少scan过程中next()的时间开销,代价是Scanner需要通过客户端的内存来维持这些被缓存的行记录。

1)在HBase的conf配置文件中进行配置;

2)通过调用HTable.setScannerCaching(int scannerCaching)进行配置;

3)通过调用Scan.setCaching(int caching)进行配置。 三者的优先级越来越高。

5.Scan Attribute Selection

scan时指定需要的Column family,可以减少网络传输数量量。默认scan操作会返回所有Column family的数据。

6.Close ResultScanner

通过Scanner取完数据后,要关闭ResultScanner,否则对应的RegionServer资源无法释放。

7.缓存查询结果

对于频繁查询HBase的应用场景,可以考虑在应用程序中做缓存(如redis),当有新的查询请求时,先去缓存中查找,找不到再去HBase中找,并写到缓存中。

8.Blockcache

HBase上的RegionServer的内存分为两个部分。一部分作为Memstore,只要用来写;另外一部分作为Blockcache,主要用于读。

一个Regionserver上有一个BlockCache和N个Memstore,它们的大小之和不能大于 等于heapsize * 0.8,否则HBase不能启动。默认BlockCache为0.2,而Memstore 为0.4。对于注重读响应时间的系统,可以将 BlockCache设大些,比如设置 BlockCache=0.4,Memstore=0.39,以加大缓存的命中率。