1. 程式人生 > >hbase 0.98.9客戶端的兩個引數調優

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個執行緒在運行了。