Apache HBase 是 Hadoop 生態圈中的分布式、可擴展、面向列的 NoSQL 資料庫。本文提供一個基於 Maven 的完整 Java 示例項目,涵蓋表管理、CRUD 操作、掃描查詢以及高併發批量寫入等核心場景,代碼可直接用於生產環境參考。
核心依賴包括 hbase-client、hbase-server(測試用)、hadoop-common 及連接池相關庫。建議使用 shaded 打包避免依賴衝突。
// 單例模式管理 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 非線程安全,每線程自行獲取。
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,顯著提升寫入吞吐。
// 使用 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 倍。
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()hbase.client.write.buffer=4MBhbase.rpc.timeout=60000