HBase rowkey設計-熱點問題
阿新 • • 發佈:2019-01-08
當處理由連續事件得到的資料時,即時間上連續的資料。這些資料可能來自於某個感測器網路、證券交易或者一個監控系統。它們顯著的特點就是rowkey中含有事件發生時間。帶來的一個問題便是HBase對於row的不均衡分佈,它們被儲存在一個唯一的rowkey區間中,被稱為region,區間的範圍被稱為Start Key和End Key。
如果將單調遞增的時間型別資料作為rowkey,value很容易被雜湊到同一個Region中,這樣它們會被儲存在同一個伺服器上,從而所有的訪問和更新操作都會集中到這一臺伺服器上,從而在叢集中形成一個hot spot,從而不能將叢集的整體效能發揮出來。
如果將單調遞增的時間型別資料作為rowkey,value很容易被雜湊到同一個Region中,這樣它們會被儲存在同一個伺服器上,從而所有的訪問和更新操作都會集中到這一臺伺服器上,從而在叢集中形成一個hot spot,從而不能將叢集的整體效能發揮出來。
要解決這個問題是非常容易的,只需要將所有的資料雜湊到全部的Region上即可。這是可以做到的,在rowkey前面加上一個非線性字首,或者翻轉rowkey,或者將rowkey hash化。
資料分散到不同的Region上儲存,可以利用HBase的並行特點,可以利用MapReduce和spark計算框架並行處理資料。
下列程式碼是參考(在rowkey前面加上一個非線性字首)
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.hbase.HBaseConfiguration;
- import org.apache.hadoop.hbase.HColumnDescriptor;
-
import org.apache.hadoop.hbase.HTableDescriptor;
- import org.apache.hadoop.hbase.KeyValue;
- import org.apache.hadoop.hbase.MasterNotRunningException;
- import org.apache.hadoop.hbase.TableName;
- import org.apache.hadoop.hbase.ZooKeeperConnectionException;
- import org.apache.hadoop.hbase.client.Get;
-
import org.apache.hadoop.hbase.client.HBaseAdmin;
- import org.apache.hadoop.hbase.client.HTable;
- import org.apache.hadoop.hbase.client.HTablePool;
- import org.apache.hadoop.hbase.client.Put;
- import org.apache.hadoop.hbase.client.Result;
- import org.apache.hadoop.hbase.client.ResultScanner;
- import org.apache.hadoop.hbase.client.Scan;
- import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
- import org.apache.hadoop.hbase.filter.Filter;
- import org.apache.hadoop.hbase.filter.FilterList;
- import org.apache.hadoop.hbase.filter.PrefixFilter;
- import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
- import org.apache.hadoop.hbase.util.Bytes;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.kktest.hbase.HashChoreWoker;
- import com.kktest.hbase.HashRowKeyGenerator;
- import com.kktest.hbase.RowKeyGenerator;
- import com.kktest.hbase.BitUtils;
- /**
- * hbase 客戶端
- *
- * @author kuang hj
- *
- */
- @SuppressWarnings("all")
- publicclass HBaseClient {
- privatestatic Logger logger = LoggerFactory.getLogger(HBaseClient.class);
- privatestatic Configuration config;
- static {
- config = HBaseConfiguration.create();
- config.set("hbase.zookeeper.quorum",
- "192.168.1.100:2181,192.168.1.101:2181,192.168.1.103:2181");
- }
- /**
- * 根據隨機雜湊(hash)建立分割槽表
- *
- * @throws Exception
- * hash_split_table
- */
- publicstaticvoid testHashAndCreateTable(String tableNameTmp,
- String columnFamily) throws Exception { // 取隨機雜湊 10 代表 10個分割槽
- HashChoreWoker worker = new HashChoreWoker(1000000, 10);
- byte[][] splitKeys = worker.calcSplitKeys();
- HBaseAdmin admin = new HBaseAdmin(config);
- TableName tableName = TableName.valueOf(tableNameTmp);
- if (admin.tableExists(tableName)) {
- try {
- admin.disableTable(tableName);
- } catch (Exception e) {
- }
- admin.deleteTable(tableName);
- }
- HTableDescriptor tableDesc = new HTableDescriptor(tableName);
- HColumnDescriptor columnDesc = new HColumnDescriptor(
- Bytes.toBytes(columnFamily));
- columnDesc.setMaxVersions(1);
- tableDesc.addFamily(columnDesc);
- admin.createTable(tableDesc, splitKeys);
- admin.close();
- }
- /**
- * @Title: queryData
- * @Description: 從HBase查詢出資料
- * @author kuang hj
- * @param tableName
- * 表名
- * @param rowkey
- * rowkey
- * @return 返回使用者資訊的list
- * @throws Exception
- */
- @SuppressWarnings("all")
- publicstatic ArrayList<String> queryData(String tableName, String rowkey)
- throws Exception {
- ArrayList<String> list = new ArrayList<String>();
- logger.info("開始時間");
- //在高併發的情況下,最好不要使用HTable/HTablePool,用asynchbase
- HTable table = new HTable(config, tableName);
- Get get = new Get(rowkey.getBytes()); // 根據rowkey查詢,該操作會比較費時
- Result r = table.get(get);
- logger.info("結束時間");
- KeyValue[] kv = r.raw();
- for (int i = 0; i < kv.length; i++) {
- // 迴圈每一列
- String key = kv[i].getKeyString();
- String value = kv[i].getValueArray().toString();
- // 將查詢到的結果寫入List中
- list.add(key + ":"+ value);
- }// end of 遍歷每一列
- return list;
- }