表设计的优化
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,以加大缓存的命中率。