hbase 0.98.9客戶端的兩個引數調優
公司的專案有用到hbase資料庫,而我正好負責hbase客戶端的介面程式碼編寫工作;實際就是為hbase中的各個表,提供增,刪,改,查的功能。
前段時間,同事對介面進行測試時,跟我反饋:在使用visualVM在檢視執行緒執行狀態時,發現hbase客戶端的執行緒很多,具體幹什麼不清楚,但其中很多執行緒處於等待狀態。起初,沒時間就沒在意。這段時間,功能差不多了,就也用visualvm來檢視執行緒狀態。
一,使用visualvm來檢視執行緒狀態
從圖片可以看到,有256個名稱為“hconnection-0x14ba9a2-shared-pool12-tX”的執行緒;其中很多執行緒是處於等待狀態,只有位為數不多的執行緒在執行客戶端對hbase資料庫的操作。這裡應該是可以進行優化的。
先說一下,我們專案大概是如何使用hbase客戶端的。程式碼類似如下:
//表名
String tableName = "TableName";
//建立配置物件
Configuration c = new Configuration();
Configuration hbaseConfiguration = HBaseConfiguration.create(c);
//建立連線
HConnection hbaseConnection = HConnectionManager.createConnection(hbaseConfiguration);
//獲取某個表的HTableInterface
HTableInterface table = hbaseConnection.getTable(tableName);
//do something here
table.close();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
從程式碼中,可以看到並沒有涉及到以上的執行緒數配置。只好從原始碼上,檢視有沒有相關的配置。
關鍵的程式碼在類HConnectionImplementation:
//HConnectionImplementation獲取單個表的HTableInterface
public HTableInterface getTable(String tableName) throws IOException {
return getTable(TableName.valueOf(tableName));
}
//實際呼叫了
public HTableInterface getTable(TableName tableName) throws IOException {
return getTable(tableName, getBatchPool());
}
//在方法getBatchPool()中會建立一個執行緒池
private ExecutorService getBatchPool() {
if (batchPool == null) {
// shared HTable thread executor not yet initialized
synchronized (this) {
if (batchPool == null) {
int maxThreads = conf.getInt("hbase.hconnection.threads.max", 256);
int coreThreads = conf.getInt("hbase.hconnection.threads.core", 256);
if (maxThreads == 0) {
maxThreads = Runtime.getRuntime().availableProcessors() * 8;
}
if (coreThreads == 0) {
coreThreads = Runtime.getRuntime().availableProcessors() * 8;
}
long keepAliveTime = conf.getLong("hbase.hconnection.threads.keepalivetime", 60);
LinkedBlockingQueue<Runnable> workQueue =
new LinkedBlockingQueue<Runnable>(maxThreads *
conf.getInt(HConstants.HBASE_CLIENT_MAX_TOTAL_TASKS,
HConstants.DEFAULT_HBASE_CLIENT_MAX_TOTAL_TASKS));
ThreadPoolExecutor tpe = new ThreadPoolExecutor(
coreThreads,
maxThreads,
keepAliveTime,
TimeUnit.SECONDS,
workQueue,
Threads.newDaemonThreadFactory(toString() + "-shared-"));
tpe.allowCoreThreadTimeOut(true);
this.batchPool = tpe;
}
this.cleanupPool = true;
}
}
return this.batchPool;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
從以上程式碼可以看到,在建立一個執行緒池時,用到了三個關鍵配置項,分別是:
1.hbase.hconnection.threads.max 執行緒池維護執行緒的最大數量
2.hbase.hconnection.threads.core 執行緒池維護執行緒的最少數量
3.hbase.hconnection.threads.keepalivetime 執行緒池維護執行緒所允許的空閒時間
因此,我們就可以按照需要來配置了。修改後的程式碼如下:
“`
String tableName = “TableName”;
Configuration c = new Configuration();
Configuration hbaseConfiguration = HBaseConfiguration.create(c);
//在這裡,我們重新hbase客戶端的執行緒池變數
hbaseConfiguration.setInt(“hbase.hconnection.threads.max”, 512);
//最大數量改為512
hbaseConfiguration.setInt(“hbase.hconnection.threads.core”, 32);
//最少數量改為32
hbaseConfiguration.setLong(“hbase.hconnection.threads.keepalivetime”, 300);
//空閒時間改為300秒
hbaseConnection = HConnectionManager.createConnection(hbaseConfiguration);
HTableInterface table = hbaseConnection.getTable(tableName);
//do something here
table.close(); `前面兩個
通過調節以上引數後,再次執行測試用例,結果如下:
可以看,確實只有32個執行緒在運行了。