HBase性能优化方法总结Word格式文档下载.docx
- 文档编号:1282475
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:17
- 大小:24.20KB
HBase性能优化方法总结Word格式文档下载.docx
《HBase性能优化方法总结Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《HBase性能优化方法总结Word格式文档下载.docx(17页珍藏版)》请在冰点文库上搜索。
table
"
+
table.getNameAsString()
already
exists"
);
8.
//
the
exists...
9.
false;
10.
11.}
12.
13.public
getHexSplits(String
startKey,
String
endKey,
int
numRegions)
14.
splits
=
new
byte[numRegions-1][];
15.
BigInteger
lowestKey
BigInteger(startKey,
16);
16.
highestKey
BigInteger(endKey,
17.
range
highestKey.subtract(lowestKey);
18.
regionIncrement
range.divide(BigInteger.valueOf(numRegions));
19.
lowestKey.add(regionIncrement);
20.
for(int
i=0;
i
<
numRegions-1;
i++)
21.
key
lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i)));
22.
byte[]
b
String.format("
%016x"
key).getBytes();
23.
splits[i]
b;
24.
25.
splits;
26.}
1.2RowKey
HBase中rowkey用来检索表中的记录,支持以下三种方式:
∙通过单个rowkey访问:
即按照某个rowkey键值进行get操作;
∙通过rowkey的range进行scan:
即通过设置startRowKey和endRowKey,在这个范围内进行扫描;
∙全表扫描:
即直接扫描整张表中所有行记录。
在HBase中,rowkey可以是任意字符串,最大长度64KB,实际应用中一般为10~100bytes,存为byte[]字节数组,一般设计成定长的。
rowkey是按照字典序存储,因此,设计rowkey时,要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。
举个例子:
如果最近写入HBase表中的数据是最可能被访问的,可以考虑将时间戳作为rowkey的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE–timestamp作为rowkey,这样能保证新写入的数据在读取时可以被快速命中。
1.3ColumnFamily
不要在一张表里定义太多的columnfamily。
目前Hbase并不能很好的处理超过2~3个columnfamily的表。
因为某个columnfamily在flush的时候,它邻近的columnfamily也会因关联效应被触发flush,最终导致系统产生更多的I/O。
感兴趣的同学可以对自己的HBase集群进行实际测试,从得到的测试结果数据验证一下。
1.4InMemory
创建表的时候,可以通过HColumnDescriptor.setInMemory(true)将表放到RegionServer的缓存中,保证在读取的时候被cache命中。
1.5MaxVersion
创建表的时候,可以通过HColumnDescriptor.setMaxVersions(int
maxVersions)设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置setMaxVersions
(1)。
1.6TimeToLive
创建表的时候,可以通过HColumnDescriptor.setTimeToLive(inttimeToLive)设置表中数据的存储生命期,过期数据将自动被删除,例如如果只需要存储最近两天的数据,那么可以设置setTimeToLive(2*24*60*60)。
1.7Compact&
Split
在HBase中,数据在更新时首先写入WAL日志(HLog)和内存(MemStore)中,MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并且将老的MemStore添加到flush队列,由单独的线程flush到磁盘上,成为一个StoreFile。
于此同时,系统会在zookeeper中记录一个redopoint,表示这个时刻之前的变更已经持久化了(minorcompact)。
StoreFile是只读的,一旦创建后就不可以再修改。
因此Hbase的更新其实是不断追加的操作。
当一个Store中的StoreFile达到一定的阈值后,就会进行一次合并(majorcompact),将对同一个key的修改合并到一起,形成一个大的StoreFile,当StoreFile的大小达到一定阈值后,又会对StoreFile进行分割(split),等分为两个StoreFile。
由于对表的更新是不断追加的,处理读请求时,需要访问Store中全部的StoreFile和MemStore,将它们按照rowkey进行合并,由于StoreFile和MemStore都是经过排序的,并且StoreFile带有内存中索引,通常合并过程还是比较快的。
实际应用中,可以考虑必要时手动进行majorcompact,将同一个rowkey的修改进行合并形成一个大的StoreFile。
同时,可以将StoreFile设置大些,减少split的发生。
2.写表操作
2.1多HTable并发写
创建多个HTable客户端用于写操作,提高写数据的吞吐量,一个例子:
1.static
final
Configuration
conf
HBaseConfiguration.create();
2.static
table_log_name
“user_log”;
3.wTableLog
HTable[tableN];
4.for
(int
0;
tableN;
wTableLog[i]
HTable(conf,
table_log_name);
wTableLog[i].setWriteBufferSize(5
*
1024
1024);
//5MB
wTableLog[i].setAutoFlush(false);
8.}
2.2HTable参数设置
2.2.1AutoFlush
通过调用HTable.setAutoFlush(false)方法可以将HTable写客户端的自动flush关闭,这样可以批量写入数据到HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存时,才实际向HBase服务端发起写请求。
默认情况下autoflush是开启的。
2.2.2WriteBuffer
通过调用HTable.setWriteBufferSize(writeBufferSize)方法可以设置HTable客户端的写buffer大小,如果新设置的buffer小于当前写buffer中的数据时,buffer将会被flush到服务端。
其中,writeBufferSize的单位是byte字节数,可以根据实际写入数据量的多少来设置该值。
2.2.3WALFlag
在HBae中,客户端向集群中的RegionServer提交数据时(Put/Delete操作),首先会先写WAL(WriteAheadLog)日志(即HLog,一个RegionServer上的所有Region共享一个HLog),只有当WAL日志写成功后,再接着写MemStore,然后客户端被通知提交数据成功;
如果写WAL日志失败,客户端则被通知提交失败。
这样做的好处是可以做到RegionServer宕机后的数据恢复。
因此,对于相对不太重要的数据,可以在Put/Delete操作时,通过调用Put.setWriteToWAL(false)或Delete.setWriteToWAL(false)函数,放弃写WAL日志,从而提高数据写入的性能。
值得注意的是:
谨慎选择关闭WAL日志,因为这样的话,一旦RegionServer宕机,Put/Delete的数据将会无法根据WAL日志进行恢复。
2.3批量写
通过调用HTable.put(Put)方法可以将一个指定的rowkey记录写入HBase,同样HBase提供了另一个方法:
通过调用HTable.put(List<
Put>
)方法可以将指定的rowkey列表,批量写入多行记录,这样做的好处是批量执行,只需要一次网络I/O开销,这对于对数据实时性要求高,网络传输RTT高的情景下可能带来明显的性能提升。
2.4多线程并发写
在客户端开启多个HTable写线程,每个写线程负责一个HTable对象的flush操作,这样结合定时flush和写buffer(writeBufferSize),可以既保证在数据量小的时候,数据可以在较短时间内被flush(如1秒内),同时又保证在数据量大的时候,写buffer一满就及时进行flush。
下面给个具体的例子:
1.for
threadN;
2.
Thread
th
Thread()
public
void
run()
while
(true)
sleep(1000);
//1
second
(InterruptedException
e.printStackTrace();
synchronized
(wTableLog[i])
11.
wTableLog[i].flushCommits();
13.
(IOException
};
th.setDaemon(true);
th.start();
22.}
3.读表操作
3.1多HTable并发读
创建多个HTable客户端用于读操作,提高读数据的吞吐量,一个例子:
3.rTableLog
rTableLog[i]
rTableLog[i].setScannerCaching(50);
7.}
3.2HTable参数设置
3.2.1ScannerCaching
通过调用HTable.setScannerCaching(intscannerCaching)可以设置HBasescanner一次从服务端抓取的数据条数,默认情况下一次一条。
通过将此值设置成一个合理的值,可以减少scan过程中next()的时间开销,代价是scanner需要通过客户端的内存来维持这些被cache的行记录。
3.2.2ScanAttributeSelection
scan时指定需要的ColumnFamily,可以减少网络传输数据量,否则默认scan操作会返回整行所有ColumnFamily的数据。
3.2.3CloseResultScanner
通过scan取完数据后,记得要关闭ResultScanner,否则RegionServer可能会出现问题(对应的Server资源无法释放)。
3.3批量读
通过调用HTable.get(Get)方法可以根据一个指定的rowkey获取一行记录,同样HBase提供了另一个方法:
通过调用HTable.get(List)方法可以根据一个指定的rowkey列表,批量获取多行记录,这样做的好处是批量执行,只需要一次网络I/O开销,这对于对数据实时性要求高而且网络传输RTT高的情景下可能带来明显的性能提升。
3.4多线程并发读
在客户端开启多个HTable读线程,每个读线程负责通过HTable对象进行get操作。
下面是一个多线程并发读取HBase,获取店铺一天内各分钟PV值的例子:
class
DataReaderServer
//获取店铺一天内各分钟PV值的入口函数
ConcurrentHashMap
getUnitMinutePV(long
uid,
long
startStamp,
endStamp){
min
startStamp;
count
(int)((endStamp
-
startStamp)
/
(60*1000));
List
lst
ArrayList();
for
count;
startStamp
60
1000;
lst.add(uid
_"
min);
parallelBatchMinutePV(lst);
//多线程并发查询,获取分钟PV值
14.private
parallelBatchMinutePV(List
lstKeys){
hashRet
ConcurrentHashMap();
parallel
3;
List<
String>
>
lstBatchKeys
null;
if
(lstKeys.size()
){
ArrayList<
(1);
lstBatchKeys.add(lstKeys);
else{
(parallel);
parallel;
i++
26.
lstBatchKeys.add(lst);
27.
28.
29.
0
;
lstKeys.size()
++
30.
lstBatchKeys.get(i%parallel).add(lstKeys.get(i));
31.
32.
33.
34.
futures
ArrayList
(5);
35.
36.
ThreadFactoryBuilder
builder
ThreadFactoryBuilder();
37.
builder.setNameFormat("
ParallelBatchQuery"
38.
ThreadFactory
factory
builder.build();
39.
ThreadPoolExecutor
executor
(ThreadPoolExecutor)
Executors.newFixedThreadPool(lstBatchKeys.size(),
factory);
40.
41.
for(List
keys
:
lstBatchKeys){
42.
Callable<
callable
BatchMinutePVCallable(keys);
43.
FutureTask<
future
(FutureTask<
)
executor.submit(callable);
44.
futures.add(future);
45.
46.
executor.shutdown();
47.
48.
Wait
all
tasks
to
finish
49.
50.
stillRunning
!
executor.awaitTermination(
51.
5000000,
TimeUnit.MILLISECONDS);
52.
(stillRunning)
53.
54.
executor.shutdownNow();
55.
(Exception
56.
TODO
Auto-generated
block
57.
58.
59.
60.
61.
62.
Thread.currentThread().interrupt();
63.
e1)
64.
65.
e1.printStackTrace();
66.
67.
68.
69.
Look
any
exception
70.
(Future
f
futures)
71.
72.
if(f.get()
null)
73.
74.
hashRet.putAll((ConcurrentHashMap)f.get());
75.
76.
77.
78.
Thread
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- HBase 性能 优化 方法 总结