Kudu-Java-api操作表(DDL)

目录

  • 背景
  • 创建表结构
    • 单主键设置
    • 联合主键设置
    • 删除表,添加删除字段

背景

如前面几篇文章所述,kudu的环境已经搭建好了,剩下就是对kudu-api的上手操作了。
本次主要是创建表,添加,删除字段。

创建表结构

    private static final String KUDU_MASTERS = "192.168.220.145";
    private static final Logger logger = LoggerFactory.getLogger(TableDDL.class);
    public static void main(String[] args) throws KuduException {
        KuduClient kuduClient = new KuduClient.KuduClientBuilder(KUDU_MASTERS).build();
        createExampleTable(kuduClient, "kudu_test");
        createExample2Table(kuduClient, "kudu_test2");
        alterTableAddColumn(kuduClient, "kudu_test2", "domain_id_default", Type.INT32);
        alterTableDeleteColumn(kuduClient, "kudu_test2", "domain_id_default");
        kuduClient.close();
    }

单主键设置

单column主键设置,与app一一对应的关系,也是我们常见的结构,然后根据ID进行hash分区。
需要注意以下几点:
必需指定一个或多个字段为主键,多个即为联合主键,如果不设置为报异常

org.apache.kudu.client.NonRecoverableException: must specify at least one key column

buckets数值也就是cto.addHashPartitions(hashKeys, 2);第二个参数必须是>=2, 否则会报异常

org.apache.kudu.client.NonRecoverableException: must have at least two hash buckets

因为我搭建的是单机模式(kudu-master与kudu-tserver均安装在一台机器上),副本数一定要设置为1
否则会报如下异常

org.apache.kudu.client.NonRecoverableException: Not enough live tablet servers to create a table
with the requested replication factor 3. 1 tablet servers are alive.

并且副本数一定要设置成奇数,否则会报异常

org.apache.kudu.client.NonRecoverableException: illegal replication factor 2 (replication factor must be odd)

    /**
     * 背景:
     * 单column主键设置,与app一一对应的关系
     * 根据Id hash分了两个区。
     *
     * @param client
     * @param tableName
     * @throws KuduException
     */
    static void createExampleTable(KuduClient client, String tableName) throws KuduException {
        List<ColumnSchema> columnSchemas = Lists.newArrayList();
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("id", Type.STRING).key(true).build());
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("app", Type.INT8).build());
        Schema schema = new Schema(columnSchemas);
        ImmutableList<String> hashKeys = ImmutableList.of("id");
        CreateTableOptions cto = new CreateTableOptions();
        cto.addHashPartitions(hashKeys, 2);
        cto.setNumReplicas(1);
        client.createTable(tableName, schema, cto);
        System.out.println("Create table " + tableName);
    }

创建好后,可以在界面查看到,我们可以看到,即使没有装impala-kudu组件,但页面一样显示了impala create table的语法。这点很友好。
Kudu-Java-api操作表(DDL)_第1张图片

联合主键设置

由于需求原因,一个device_id,可能会有多个app的情况,所以仅使用device_id做为主键是不够用的。
这时就需要有联合主键了。此处根据业务场景,应使用device_idapp_id做为联合主键, 此外对于多个主键,
可以对不同的主键进行不同的分区策略。而Kudu共有两种分区策略,一个是hash,另一个是range
在创建联合主键的表是时,还需要注意以下几点:
联合主键是有序的,这就意味着,你的主键在进行代码添加(也就是通过columnSchemas.add()方法)时,
必须要严格按照你的业务来进行,比如你不能把action_time放在非主键app_name之后,否则会报异常

org.apache.kudu.client.NonRecoverableException: Got out-of-order key column: name: “action_time” type: INT64 is_key: true is_nullable: false cfile_block_size: 0
设备action_time为range分区时,那么action_time必须要设置为主键, 否则会报异常
org.apache.kudu.client.NonRecoverableException: must specify only primary key columns for range partition component

    /**
     * range分区数
     */
    private static final int RANGE_PARTITION_NUMS = 10;
    /**
     *
     * @param client
     * @param tableName
     */
    static void createExample2Table (KuduClient client, String tableName) throws KuduException {
        List<ColumnSchema> columnSchemas = Lists.newArrayList();
        //org.apache.kudu.client.NonRecoverableException: must specify at least one key column
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("device_id", Type.STRING).key(true).build());
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("app_id", Type.INT32).key(true).build());
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("action_time", Type.INT64).key(true).build());
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("app_name", Type.STRING).nullable(true).build());
        Schema schema = new Schema(columnSchemas);
        //设置hash分区
        CreateTableOptions cto = new CreateTableOptions();
        cto.addHashPartitions(ImmutableList.of("device_id", "app_id"), 2);
        cto.setNumReplicas(1);
        //设置action_time的range分区
        cto.setRangePartitionColumns(ImmutableList.of("action_time"));
        int count = 0;
        for (long i = 0; i < RANGE_PARTITION_NUMS; i++) {
            PartialRow lower = schema.newPartialRow();
            lower.addLong("action_time", count);
            PartialRow upper = schema.newPartialRow();
            count += 10;
            upper.addLong("action_time", count);
            cto.addRangePartition(lower, upper);
        }
        // 创建table, 并设置partition
        client.createTable(tableName, schema, cto);
        System.out.println("Create table " + tableName);
    }

查看页面:
Kudu-Java-api操作表(DDL)_第2张图片

删除表,添加删除字段

需要注意以下两点就行
给表添加字段,但要注意的是添加的字段不能再设置成主键。(kudu-version: 1.10.0),也就是主键必须要在创建表之前就要根据业务实际情况想好,因为后续是不能进行更改的,否则会报如下异常

java.lang.IllegalArgumentException: Key columns cannot be added

添加的字段nullabel参数默认为false,所以要设置defaultValue的值,或者将nullable设置为true, 否则会异常:

java.lang.IllegalArgumentException: A new non-null column must have a default value

    static void dropExampleTable(KuduClient client, String tableName) throws KuduException {
        client.deleteTable(tableName);
    }

    static void alterTableAddColumn(KuduClient client, String tableName, String column, Type type) {
        AlterTableOptions alterTableOptions = new AlterTableOptions();
        alterTableOptions.addColumn(new ColumnSchema.ColumnSchemaBuilder(column, type).nullable(true).build());
        try {
            client.alterTable(tableName, alterTableOptions);
        } catch (KuduException e) {
            e.printStackTrace();
            logger.debug("给表{}添加字段失败, 失败信息: cause -> {}, message -> {}", tableName, e.getCause(), e.getMessage());
        }
    }

    static void alterTableDeleteColumn(KuduClient client, String tableName, String column){
        AlterTableOptions alterTableOptions = new AlterTableOptions().dropColumn(column);
        try {
            client.alterTable(tableName, alterTableOptions);
        } catch (KuduException e) {
            e.printStackTrace();
            logger.error("删除表{}字段失败, 失败信息: cause -> {}, message -> {}", tableName, e.getCause(), e.getMessage());
        }
    }

你可能感兴趣的:(Kudu)