本文是大数据系列第 37 篇,通过完整的 Java 代码演示如何使用 HBase Client API 进行表管理与 CRUD 操作。

完整图文版(含截图):CSDN 原文 | 掘金

Maven 依赖

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>1.3.1</version>
</dependency>

连接配置

所有操作都需要先建立 Connection,建议全局复用(Connection 是线程安全的,Table 不是):

Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "h121.wzk.icu,h122.wzk.icu");
configuration.set("hbase.zookeeper.property.clientPort", "2181");
Connection connection = ConnectionFactory.createConnection(configuration);

建表

public class Test01 {
    public static void main(String[] args) throws IOException {
        Configuration configuration = HBaseConfiguration.create();
        configuration.set("hbase.zookeeper.quorum", "h121.wzk.icu,h122.wzk.icu");
        configuration.set("hbase.zookeeper.property.clientPort", "2181");
        Connection connection = ConnectionFactory.createConnection(configuration);
        HBaseAdmin admin = (HBaseAdmin) connection.getAdmin();

        HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf("test01"));
        descriptor.addFamily(new HColumnDescriptor("base_info"));

        admin.createTable(descriptor);
        System.out.println("test01 表创建成功");

        admin.close();
        connection.close();
    }
}

插入数据

public class Test02 {
    public static void main(String[] args) throws IOException {
        Configuration configuration = HBaseConfiguration.create();
        configuration.set("hbase.zookeeper.quorum", "h121.wzk.icu,h122.wzk.icu");
        Connection connection = ConnectionFactory.createConnection(configuration);

        Table table = connection.getTable(TableName.valueOf("test01"));
        Put put = new Put(Bytes.toBytes("rk1"));
        put.addColumn(
            Bytes.toBytes("base_info"),
            Bytes.toBytes("name"),
            Bytes.toBytes("wuzikang")
        );
        table.put(put);
        table.close();

        System.out.println("数据插入成功");
        connection.close();
    }
}

删除数据

public class Test03 {
    public static void main(String[] args) throws IOException {
        // ... 建立 connection(同上)
        Table table = connection.getTable(TableName.valueOf("test01"));
        Delete delete = new Delete(Bytes.toBytes("rk1"));
        table.delete(delete);
        table.close();

        System.out.println("行删除成功");
        connection.close();
    }
}

Get 查询(按列族)

public class Test04 {
    public static void main(String[] args) throws IOException {
        HTable table = (HTable) connection.getTable(TableName.valueOf("test01"));
        Get get = new Get(Bytes.toBytes("rk1"));
        get.addFamily(Bytes.toBytes("base_info"));

        Result result = table.get(get);
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            String cf     = Bytes.toString(CellUtil.cloneFamily(cell));
            String column = Bytes.toString(CellUtil.cloneQualifier(cell));
            String value  = Bytes.toString(CellUtil.cloneValue(cell));
            System.out.println(cf + ":" + column + " => " + value);
        }
        table.close();
    }
}

全表扫描

public class Test05 {
    public static void main(String[] args) throws IOException {
        HTable table = (HTable) connection.getTable(TableName.valueOf("test01"));
        Scan scan = new Scan();
        ResultScanner scanner = table.getScanner(scan);

        for (Result result : scanner) {
            Cell[] cells = result.rawCells();
            for (Cell cell : cells) {
                String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
                System.out.println("rowKey: " + rowkey);
            }
        }
        table.close();
    }
}

范围扫描

public class Test06 {
    public static void main(String[] args) throws IOException {
        HTable table = (HTable) connection.getTable(TableName.valueOf("test01"));
        Scan scan = new Scan();
        scan.setStartRow("rk1".getBytes());
        scan.setStopRow("rk3".getBytes());  // 左闭右开

        ResultScanner scanner = table.getScanner(scan);
        for (Result result : scanner) {
            // 处理每行数据
        }
        table.close();
    }
}

setStartRow / setStopRow 是左闭右开区间,rk3 本身不会被返回。

关键注意事项

注意点说明
Connection 复用线程安全,应用级单例,避免频繁创建销毁
Table 非线程安全每次操作后调用 table.close()
Bytes.toBytes()HBase 所有值以字节数组存储,读取时需对应解码
批量写入大批量插入用 BufferedMutator,减少 RPC 次数
范围扫描性能始终设置 startRow/stopRow,避免全表扫描