首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

HBase Java API 完整編程實戰:從建表到多線程批量寫入

     編輯:Java 綜合教學

HBase Java 客戶端開發完整指南

Apache HBase 是 Hadoop 生態圈中的分布式、可擴展、面向列的 NoSQL 資料庫。本文提供一個基於 Maven 的完整 Java 示例項目,涵蓋表管理、CRUD 操作、掃描查詢以及高併發批量寫入等核心場景,代碼可直接用於生產環境參考。

一、專案依賴配置

核心依賴包括 hbase-client、hbase-server(測試用)、hadoop-common 及連接池相關庫。建議使用 shaded 打包避免依賴衝突。

二、核心代碼結構解析

1. 連接管理與配置初始化

// 單例模式管理 Connection 與 Admin,避免重複創建開銷
private static Configuration conf = HBaseConfiguration.create();
static {
    conf.set("hbase.zookeeper.quorum", "10.148.137.143");
    conf.set("hbase.zookeeper.property.clientPort", "2181");
}

private static Connection conn = ConnectionFactory.createConnection(conf);
private static Admin admin = conn.getAdmin();

關鍵點:Connection 是線程安全的,全應用共享單例;Table/BufferedMutator 非線程安全,每線程自行獲取。

2. 表結構設計與預分區建表

public static void createTable(String tableName, String[] families) throws IOException {
    if (admin.tableExists(TableName.valueOf(tableName))) return;
    
    HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
    for (String cf : families) {
        HColumnDescriptor cfDesc = new HColumnDescriptor(cf);
        cfDesc.setMaxVersions(3650); // 保留 10 年版本
        desc.addFamily(cfDesc);
    }
    
    // 預分區鍵:避免寫入熱點集中於單 Region
    byte[][] splitKeys = { 
        Bytes.toBytes("zkb_0_0"), Bytes.toBytes("zkb_10_0"), ..., Bytes.toBytes("zkb_100_0") 
    };
    admin.createTable(desc, splitKeys);
}

預分區策略根據 RowKey 分布預估,將數據均勻分散到多個 RegionServer,顯著提升寫入吞吐。

3. 高性能批量寫入實現

// 使用 BufferedMutator 異步批量提交,減少 RPC 開銷
BufferedMutatorParams params = new BufferedMutatorParams(TableName.valueOf(tableName));
params.writeBufferSize(4 * 1024 * 1024); // 4MB 緩衝區
BufferedMutator mutator = conn.getBufferedMutator(params);

for (int i = 0; i < 10000000; i++) {
    Put put = new Put(Bytes.toBytes(rowKey));
    put.addColumn(family, qualifier, Bytes.toBytes(value));
    mutator.mutate(put); // 非阻塞寫入
    
    if (count.incrementAndGet() % 10000 == 0) logProgress();
}
mutator.flush(); // 確保所有緩衝數據落盤
mutator.close();

對比 Table.put() 同步寫入,BufferedMutator 吞吐量可提升 5-10 倍。

4. 多線程併發寫入架構

ExecutorService pool = Executors.newFixedThreadPool(16);
for (int i = 0; i < 80; i++) {
    pool.execute(new WriteTask(i, tableName)); // 每任務寫入不同 RowKey 範圍
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);

線程池大小建議設置為 RegionServer 核心數的 2-3 倍,避免過度併發導致 OOM 或 RPC 隊列堆積。

三、常用操作封裝

  • 單行讀取: Get get = new Get(rowKey); Result rs = table.get(get);
  • 全表掃描: Scan scan = new Scan(); ResultScanner scanner = table.getScanner(scan);
  • 刪除操作: Delete del = new Delete(rowKey); table.delete(del);
  • 獲取列族信息: table.getTableDescriptor().getColumnFamilies()

四、生產環境優化清單

  1. 啟用客戶端寫入緩衝:hbase.client.write.buffer=4MB
  2. 調整 RPC 超時:hbase.rpc.timeout=60000
  3. 使用連接池複用 Connection,避免頻繁建立 ZK 會話
  4. RowKey 設計遵循「散列+業務」原則,防止熱點 Region
  5. 定期 Major Compaction 整理 StoreFile,降低讀放大
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved