HBase (2) Java operating HBase Tutorial

I. Introduction

In the previous article entry HBase basis , we have introduced some basic concepts of HBase, and methods of how to install and use.
Then, as a Javaer, naturally we wish to have a dialogue with the Java way HBase.
Fortunately, HBase itself is written in Java, Java comes naturally native API. We can achieve operating HBase database through hbase-client.
So, this introduces the basic usage of the component.

Before using hbase-client, there are several important points to note:

  • The client needs to be able to access Zoopkeeper, then get HMaster, RegionServer instance operation
  • The client needs to run in the HBase / Hadoop clusters, HBase will use the hostname to locate the node, thus requiring the client to access the corresponding host name (or subdomain)
    If you need to configure the remote client's local hosts file.

The following chart helps to understand the interaction with HBase cluster architecture Client:

The following began to introduce the use of client.

Two, hbase-client introduced

In Maven's pom.xml add-dependent:

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>2.1.5</version>
    <exclusions>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
        <exclusion>
            <artifactId>slf4j-log4j12</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase</artifactId>
    <version>2.1.5</version>
</dependency>

It should be noted that the client version and the version of HBase need to be consistent, otherwise you may experience incompatibility issues.

Third, the connection operation

Sample code:

/**
 * 建立连接
 *
 * @return
 */
public static Connection getConnection() {
    try {
        //获取配置
        Configuration configuration = getConfiguration();
        //检查配置
        HBaseAdmin.checkHBaseAvailable(configuration);
        return ConnectionFactory.createConnection(configuration);
    } catch (IOException | ServiceException e) {
        throw new RuntimeException(e);
    }
}

/**
 * 获取配置
 *
 * @return
 */
private static Configuration getConfiguration() {
    try {
        Properties props = PropertiesLoaderUtils.loadAllProperties("hbase.properties");
        String clientPort = props.getProperty("hbase.zookeeper.property.clientPort");
        String quorum = props.getProperty("hbase.zookeeper.quorum");

        logger.info("connect to zookeeper {}:{}", quorum, clientPort);

        Configuration config = HBaseConfiguration.create();
        config.set("hbase.zookeeper.property.clientPort", clientPort);
        config.set("hbase.zookeeper.quorum", quorum);
        return config;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Fourth, the operating table

CRUD method of packaging as follows:

/**
 * 创建表
 * @param connection
 * @param tableName
 * @param columnFamilies
 * @throws IOException
 */
public static void createTable(Connection connection, TableName tableName, String... columnFamilies) throws IOException {
    Admin admin = null;
    try {
        admin = connection.getAdmin();
        if (admin.tableExists(tableName)) {
            logger.warn("table:{} exists!", tableName.getName());
        } else {
            TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName);
            for (String columnFamily : columnFamilies) {
                builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(columnFamily));
            }
            admin.createTable(builder.build());
            logger.info("create table:{} success!", tableName.getName());
        }
    } finally {
        if (admin != null) {
            admin.close();
        }
    }
}


/**
 * 插入数据
 *
 * @param connection
 * @param tableName
 * @param rowKey
 * @param columnFamily
 * @param column
 * @param data
 * @throws IOException
 */
public static void put(Connection connection, TableName tableName,
                       String rowKey, String columnFamily, String column, String data) throws IOException {

    Table table = null;
    try {
        table = connection.getTable(tableName);
        Put put = new Put(Bytes.toBytes(rowKey));
        put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column), Bytes.toBytes(data));
        table.put(put);
    } finally {
        if (table != null) {
            table.close();
        }
    }
}

/**
 * 根据row key、column 读取
 *
 * @param connection
 * @param tableName
 * @param rowKey
 * @param columnFamily
 * @param column
 * @throws IOException
 */
public static String getCell(Connection connection, TableName tableName, String rowKey, String columnFamily, String column) throws IOException {
    Table table = null;
    try {
        table = connection.getTable(tableName);
        Get get = new Get(Bytes.toBytes(rowKey));
        get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column));

        Result result = table.get(get);
        List<Cell> cells = result.listCells();

        if (CollectionUtils.isEmpty(cells)) {
            return null;
        }
        String value = new String(CellUtil.cloneValue(cells.get(0)), "UTF-8");
        return value;
    } finally {
        if (table != null) {
            table.close();
        }
    }
}

/**
 * 根据rowkey 获取一行
 *
 * @param connection
 * @param tableName
 * @param rowKey
 * @return
 * @throws IOException
 */
public static Map<String, String> getRow(Connection connection, TableName tableName, String rowKey) throws IOException {
    Table table = null;
    try {
        table = connection.getTable(tableName);
        Get get = new Get(Bytes.toBytes(rowKey));

        Result result = table.get(get);
        List<Cell> cells = result.listCells();

        if (CollectionUtils.isEmpty(cells)) {
            return Collections.emptyMap();
        }
        Map<String, String> objectMap = new HashMap<>();
        for (Cell cell : cells) {
            String qualifier = new String(CellUtil.cloneQualifier(cell));
            String value = new String(CellUtil.cloneValue(cell), "UTF-8");
            objectMap.put(qualifier, value);
        }
        return objectMap;
    } finally {
        if (table != null) {
            table.close();
        }
    }
}

/**
 * 扫描权标的内容
 *
 * @param connection
 * @param tableName
 * @param rowkeyStart
 * @param rowkeyEnd
 * @throws IOException
 */
public static List<Map<String, String>> scan(Connection connection, TableName tableName, String rowkeyStart, String rowkeyEnd) throws IOException {
    Table table = null;
    try {
        table = connection.getTable(tableName);
        ResultScanner rs = null;
        try {
            Scan scan = new Scan();
            if (!StringUtils.isEmpty(rowkeyStart)) {
                scan.withStartRow(Bytes.toBytes(rowkeyStart));
            }
            if (!StringUtils.isEmpty(rowkeyEnd)) {
                scan.withStopRow(Bytes.toBytes(rowkeyEnd));
            }
            rs = table.getScanner(scan);

            List<Map<String, String>> dataList = new ArrayList<>();
            for (Result r : rs) {
                Map<String, String> objectMap = new HashMap<>();
                for (Cell cell : r.listCells()) {
                    String qualifier = new String(CellUtil.cloneQualifier(cell));
                    String value = new String(CellUtil.cloneValue(cell), "UTF-8");
                    objectMap.put(qualifier, value);
                }
                dataList.add(objectMap);
            }
            return dataList;
        } finally {
            if (rs != null) {
                rs.close();
            }
        }
    } finally {
        if (table != null) {
            table.close();
        }
    }
}

/**
 * 删除表
 *
 * @param connection
 * @param tableName
 * @throws IOException
 */
public static void deleteTable(Connection connection, TableName tableName) throws IOException {
    Admin admin = null;
    try {
        admin = connection.getAdmin();
        if (admin.tableExists(tableName)) {
            //现执行disable
            admin.disableTable(tableName);
            admin.deleteTable(tableName);
        }
    } finally {
        if (admin != null) {
            admin.close();
        }
    }
}

Fifth, run the test

Finally, the device data we still above article as an example:

  1. Establish DeviceState table;
  2. Defined name / state column two clusters;
  3. Data write column;
  4. Read column, row, the reading range;
  5. Deletion

Ultimately codes as follows:

private static final Logger logger = LoggerFactory.getLogger(HBaseTest.class);

public static void main(String[] args) {

    Connection connection = null;
    try {
        connection = getConnection();
        TableName tableName = TableName.valueOf("DeviceState");

        //创建DeviceState表
        createTable(connection, tableName, "name", "state");

        logger.info("创建表 {}", tableName.getNameAsString());

        //写入数据
        put(connection, tableName, "row1", "name", "c1", "空调");
        put(connection, tableName, "row1", "state", "c2", "打开");
        put(connection, tableName, "row2", "name", "c1", "电视机");
        put(connection, tableName, "row2", "state", "c2", "关闭");

        logger.info("写入数据.");

        String value = getCell(connection, tableName, "row1", "state", "c2");
        logger.info("读取单元格-row1.state:{}", value);

        Map<String, String> row = getRow(connection, tableName, "row2");
        logger.info("读取单元格-row2:{}", JsonUtil.toJson(row));

        List<Map<String, String>> dataList = scan(connection, tableName, null, null);
        logger.info("扫描表结果-:\n{}", JsonUtil.toPrettyJson(dataList));

        //删除DeviceState表
        deleteTable(connection, tableName);
        logger.info("删除表 {}", tableName.getNameAsString());

        logger.info("操作完成.");
    } catch (Exception e) {
        logger.error("操作出错", e);
    } finally {
        if (connection != null) {
            try {
                connection.close();
            } catch (IOException e) {
                logger.error("error occurs", e);
            }
        }
    }

}

Executing code, the console output:

INFO -createTable(HBaseTest.java:89) - create table:[68, 101, 118, 105, 99, 101, 83, 116, 97, 116, 101] success!
INFO -main(HBaseTest.java:32) - 创建表 DeviceState
INFO -main(HBaseTest.java:40) - 写入数据.
INFO -main(HBaseTest.java:43) - 读取单元格-row1.state:打开
INFO -main(HBaseTest.java:46) - 读取单元格-row2:{"c1":"电视机","c2":"关闭"}
INFO -main(HBaseTest.java:49) - 扫描表结果-:
[ {
  "c1" : "空调",
  "c2" : "打开"
}, {
  "c1" : "电视机",
  "c2" : "关闭"
} ]
INFO -HBaseAdmin$9.call(HBaseAdmin.java:1380) - Started disable of DeviceState
INFO -HBaseAdmin$DisableTableFuture.postOperationResult(HBaseAdmin.java:1409) - Disabled DeviceState
INFO -HBaseAdmin$DeleteTableFuture.postOperationResult(HBaseAdmin.java:965) - Deleted DeviceState
INFO -main(HBaseTest.java:53) - 删除表 DeviceState
INFO -main(HBaseTest.java:55) - 操作完成.

At this point Java Client has been completed production.

FAQ

  • Tip error can not find winutils program

Failed to locate the winutils binary in the hadoop binary path
原因是在Windows下依赖一个winutils.exe程序,该程序通过${HADOOP_HOME}/bin 来查找。
该报错不影响程序执行,但如果要规避问题,需要下载hadoop-commons-master,再配置变量HADOOP_HOME
可参考地址:https://blog.csdn.net/ycf921244819/article/details/81706119

  • 提示报错,UnknownHostException,无法找到节点..
    原因是客户端无法解析HMaster实例节点的主机名
    需要编辑 C:\Windows\System32\drivers\etc\hosts 文件,添加对应的映射,如下:
47.xx.8x.xx izwz925kr63w5jitjys6dtt

参考文档

官方文档
https://hbase.apache.org/book.html#quickstart
Java HBase客户端API
https://www.baeldung.com/hbase

Guess you like

Origin www.cnblogs.com/littleatp/p/12013982.html