HBase Java API 批量操作

之前我們是這樣獲取數(shù)據(jù)的:

Get get = new Get(Bytes.toBytes("row1"));//定義get對象
Result result = table.get(get);//通過table對象獲取數(shù)據(jù)

那么問題來了,我們想要獲取多條數(shù)據(jù),比如說查詢1萬條數(shù)據(jù)怎么辦呢屉符?

可能我們第一時間就會想到循環(huán),例如:

String tableName = "test";
Table table = connection.getTable( TableName.valueOf(tableName));// 獲取表
for (String rowkey : rowkeyList){
Get get = new Get(Bytes.toBytes(rowkey));
Result result = table.get(get);
    for (Cell kv : result.rawCells()) {
        String value = Bytes.toString(CellUtil.cloneValue(kv));
        list.add(value);
    }
}

這樣做是非常低效的,如果有10000條數(shù)據(jù)那我們需要發(fā)送10000次請求矗钟,這樣非常耗時唆香,如果在自己本機(jī)上嘗試,查詢時間可能在5分鐘左右吨艇。

這樣肯定不行袋马,我們在HBase的Table對象和子類的源碼中找找看有沒有解決辦法,忽然眼前一亮:

public Result[] get(List<Get> gets) throws IOException {
    if (gets.size() == 1) {
      return new Result[]{get(gets.get(0))};
    }
    try {
      Object[] r1 = new Object[gets.size()];
      batch((List<? extends Row>)gets, r1, readRpcTimeoutMs);
      // Translate.
      Result [] results = new Result[r1.length];
      int i = 0;
      for (Object obj: r1) {
        // Batch ensures if there is a failure we get an exception instead
        results[i++] = (Result)obj;
      }
      return results;
    } catch (InterruptedException e) {
      throw (InterruptedIOException)new InterruptedIOException().initCause(e);
    }
}
使用get函數(shù)批量獲取數(shù)據(jù)

查看HBase的API秸应,我們可以發(fā)現(xiàn)Table對象的get()函數(shù)不僅可以接收Get對象,也同樣可以接收Get集合碑宴,現(xiàn)在我們試試get(List<Get> gets)函數(shù)的效果如何软啼。

public List<String> getData(Table table, List<String> rows) throws Exception {
    List<Get> gets = new ArrayList<>();
    for (String str : rows) {
        Get get = new Get(Bytes.toBytes(str));
        gets.add(get);
    }
    List<String> values = new ArrayList<>();
    Result[] results = table.get(gets);
    for (Result result : results) {
        System.out.println("Row:" + Bytes.toString(result.getRow()));
        for (Cell kv : result.rawCells()) {
            String family = Bytes.toString(CellUtil.cloneFamily(kv));
            String qualifire = Bytes.toString(CellUtil.cloneQualifier(kv));
            String value = Bytes.toString(CellUtil.cloneValue(kv));
            values.add(value);
            System.out.println(family + ":" + qualifire + "\t" + value);
        }
    }
    return values;
}

根據(jù)這種批量的方法,10000row進(jìn)行查詢延柠,時間穩(wěn)定在4s之內(nèi)祸挪,

使用上述代碼查詢下表:

image.png

輸出結(jié)果:

Row:20001
data:1 value1
data:2 value2
data:3 value3
data:4 value4
Row:20002
data:1 name1
data:2 name2
data:3 name3
data:4 name4

代碼解釋:

  • table.get(gets)會返回一個Result[]結(jié)果數(shù)組,里面存放了本次查詢的所有數(shù)據(jù)贞间,我們可以通過這個數(shù)組來遍歷我們需要的數(shù)據(jù)贿条;
  • result.rawCells()result是單個結(jié)果增热,這里存放的是一行的所有數(shù)據(jù)整以,resultrowCells()方法會返回這一行所有的列(Cell)的集合;
  • Cell對象是單個的列峻仇,要獲取列中的值可以通過CellUtil.cloneXXX()方法公黑,如cloneValue(cell)就會返回該列的值。
刪除單行數(shù)據(jù)

刪除一行數(shù)據(jù)很簡單摄咆,我們來看個示例:

Table table = conn.getTable(tableName); //獲取表   
byte[] row = Bytes.toBytes("row1");//定義行
Delete delete = new Delete(row);//創(chuàng)建delete對象
table.delete(delete);//刪除

這段代碼就可以刪除行鍵為row1的行凡蚜。

刪除多行數(shù)據(jù)

如何刪除多行數(shù)據(jù)呢?

相信你已經(jīng)猜到了吭从,既然get()方法有重載方法朝蜘,那應(yīng)該delete()方法也有,確實:

Table table = conn.getTable(tableName);
List<Delete> deletes = new ArrayList<>();
for(int i = 1 ; i < 5;i++){
    byte[] row = Bytes.toBytes("row" + i);
    Delete delete = new Delete(row);
    deletes.add(delete);
}
table.delete(deletes);

這樣就可以刪除多行數(shù)據(jù)啦涩金。

每一次只添加一個數(shù)據(jù)顯然不像是大數(shù)據(jù)開發(fā)谱醇,在開發(fā)項目的時候也肯定會涉及到大量的數(shù)據(jù)操作。

使用Java進(jìn)行批量數(shù)據(jù)操作步做,其實就是循環(huán)的在Put對象中添加數(shù)據(jù)最后在通過Table對象提交枣抱。

如何進(jìn)行批量操作呢,講到批量操作辆床,相信大家肯定第一時間會想到循環(huán)佳晶?

沒錯,使用循環(huán)確實就可以添加多個數(shù)據(jù)了讼载,示例:

Table tableStep3 = connection.getTable(tableStep3Name);
// 循環(huán)添加數(shù)據(jù)
byte[] row = Bytes.toBytes("20001");
Put put = new Put(row);
for (int i = 1; i <= 4; i++) {
    byte[] columnFamily = Bytes.toBytes("data");
    byte[] qualifier = Bytes.toBytes(String.valueOf(i));
    byte[] value = Bytes.toBytes("value" + i);
    put.addColumn(columnFamily, qualifier, value);
}

tableStep3.put(put);

代碼執(zhí)行結(jié)果:

image.png

可以發(fā)現(xiàn)轿秧,這一段代碼向同一個行中添加了四列數(shù)據(jù)中跌。

我們要添加多行數(shù)據(jù)應(yīng)該如何處理呢,我猜你肯定想到了:使用集合菇篡!

List<Put> puts = new ArrayList<>();
// 循環(huán)添加數(shù)據(jù)
for (int i = 1; i <= 4; i++) {
    byte[] row = Bytes.toBytes("row" + i);
    Put put = new Put(row);
    byte[] columnFamily = Bytes.toBytes("data");
    byte[] qualifier = Bytes.toBytes(String.valueOf(i));
    byte[] value = Bytes.toBytes("value" + i);
    put.addColumn(columnFamily, qualifier, value);
    puts.add(put);
}
Table table = connection.getTable(tableName);
table.put(puts);

上述代碼向HBase中添加了四行數(shù)據(jù)漩符,結(jié)合上次,可以發(fā)現(xiàn)table對象的put()方法是一個重載方法既可以接收Put對象也可以接收Put集合驱还。

添加完數(shù)據(jù)的表結(jié)構(gòu):

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嗜暴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子议蟆,更是在濱河造成了極大的恐慌闷沥,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咐容,死亡現(xiàn)場離奇詭異舆逃,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)戳粒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門路狮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔚约,你說我怎么就攤上這事奄妨。” “怎么了苹祟?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵展蒂,是天一觀的道長。 經(jīng)常有香客問我苔咪,道長锰悼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任团赏,我火速辦了婚禮箕般,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舔清。我一直安慰自己丝里,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布体谒。 她就那樣靜靜地躺著杯聚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抒痒。 梳的紋絲不亂的頭發(fā)上幌绍,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼傀广。 笑死颁独,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的伪冰。 我是一名探鬼主播誓酒,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贮聂!你這毒婦竟也來了靠柑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤吓懈,失蹤者是張志新(化名)和其女友劉穎歼冰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骄瓣,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年耍攘,在試婚紗的時候發(fā)現(xiàn)自己被綠了榕栏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蕾各,死狀恐怖扒磁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情式曲,我是刑警寧澤妨托,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站吝羞,受9級特大地震影響兰伤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钧排,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一敦腔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恨溜,春花似錦符衔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至项戴,卻和暖如春形帮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工沃缘, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留躯枢,地道東北人。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓槐臀,卻偏偏與公主長得像锄蹂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子水慨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容