Kudu常用Java API操作

导入Maven坐标

<dependency>
    <groupId>org.apache.kudu</groupId>
    <artifactId>kudu-client</artifactId>
    <version>1.9.0</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

对表操作API

import org.apache.kudu.ColumnSchema;
import org.apache.kudu.Schema;
import org.apache.kudu.Type;
import org.apache.kudu.client.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author: xu
 * @desc: 基于Java API对Kudu表进行CRUD操作,包含创建、删除、分区的操作
 */
public class TableTest {
    // 对于Kudu操作,获取KuduClient客户端实例对象
    private KuduClient kuduClient = null;

    // 初始化KuduClient实例对象
    @Before
    public void init() {
        // 构建KuduClient实例对象,连接Kudu集群(Kudu Master)
        kuduClient = new KuduClient
                .KuduClientBuilder("node2:7051") // Master地址信息
                .defaultSocketReadTimeoutMs(10000) // 设置超时时间间隔,默认值为10s
                .defaultOperationTimeoutMs(10000) // 设置对此Kudu进行操作时超时时间,默认值为30s
                .build(); // 采用建造者模式构建实例对象
    }

    /**
     * 对Kudu中表进行修改,删除列:gender
     */
    @Test
    public void alterKuduTableDropColumn() throws KuduException {
        AlterTableOptions ato = new AlterTableOptions();
        // 删除一列:gender
        ato.dropColumn("gender");

        AlterTableResponse response = kuduClient.alterTable("users", ato);
        System.out.println("TableId: " + response.getTableId());
    }

    /**
     * 对Kudu中表进行修改,增加列:gender,String
     */
    @Test
    public void alterTableAddColumn() throws KuduException {
        AlterTableOptions ato = new AlterTableOptions();
        // 添加一列:gender
        ato.addColumn("gender", Type.STRING, "X");
        // 这种添加列,可以设置更多参数
        // ato.addColumn(new ColumnSchema.ColumnSchemaBuilder("gender", Type.STRING)
        //         .key(false).nullable(true).defaultValue("X").build());

        AlterTableResponse response = kuduClient.alterTable("users", ato);
        System.out.println("TableId: " + response.getTableId());
    }

    /**
     * 判断表是否存在,如果存在,将表删除
     */
    @Test
    public void dropKuduTable() throws KuduException {
        if (kuduClient.tableExists("users")) {
            DeleteTableResponse response = kuduClient.deleteTable("users");
            System.out.println(response.getElapsedMillis());
        }
    }

    /**
     * 创建Kudu中的表,采用多级分区策略,先按id哈希分区,再按age范围分区
     */
    @Test
    public void createTableMultiLevel() throws KuduException {
        // a. 定义Kudu表的Schema信息
        // 定义Kudu表每列Schema信息
        List<ColumnSchema> list = new ArrayList<>();
        list.add(newColumnSchema("id", Type.INT32, true));
        // TODO: age也要为主键,并且要在非主键列前面,否则报 NonRecoverableException
        list.add(newColumnSchema("age", Type.INT32, true));
        list.add(newColumnSchema("name", Type.STRING, false));
        // 定义Schema信息
        Schema schema = new Schema(list);

        // b. 定义Kudu表的属性,分区策略,分区数目和副本数
        CreateTableOptions options = new CreateTableOptions();
        // TODO: 先设置按照id进行hash分区,分区数目为5
        options.addHashPartitions(Collections.singletonList("id"), 5);
        // TODO: 在设置按照age进行range分区,分区数目为3
        options.setRangePartitionColumns(Collections.singletonList("age"));
        /*
		  age < 21
		  21 <= age < 41
		  age >= 41
		 */
        // age < 21
        PartialRow lower = new PartialRow(schema);
        PartialRow upper21 = new PartialRow(schema);
        upper21.addInt("age", 21);
        options.addRangePartition(lower, upper21);

        // 21 <= age < 41
        PartialRow lower21 = new PartialRow(schema);
        lower21.addInt("age", 21);
        PartialRow upper41 = new PartialRow(schema);
        upper41.addInt("age", 41);
        options.addRangePartition(lower21, upper41);

        // age >= 41
        PartialRow lower41 = new PartialRow(schema);
        lower41.addInt("age", 41);
        PartialRow upper = new PartialRow(schema);
        options.addRangePartition(lower41, upper);
        // 设置副本数目,奇数位
        options.setNumReplicas(1);

        // c. 在Kudu中创建表
        KuduTable kuduTable = kuduClient.createTable("users_MultiLevel", schema, options);
        System.out.println("TableId: " + kuduTable.getTableId());
    }

    /**
     * 创建Kudu中的表,采用对id进行Range范围分区
     */
    @Test
    public void createTableByRange() throws KuduException {
        // a. 定义Kudu表的Schema信息
        // 定义Kudu表每列Schema信息
        List<ColumnSchema> list = new ArrayList<>();
        list.add(newColumnSchema("id", Type.INT32, true));
        list.add(newColumnSchema("name", Type.STRING, false));
        list.add(newColumnSchema("age", Type.INT8, false));
        // 定义Schema信息
        Schema schema = new Schema(list);

        // b. 定义Kudu表的属性,分区策略,分区数目和副本数
        CreateTableOptions options = new CreateTableOptions();
        // TODO: 设置分区策略,使用Range范围分区,分区键必须是主键或主键的一部分
        options.setRangePartitionColumns(Collections.singletonList("id"));

        // TODO: 设置分区范围,类似HBase中表的Region预分区操作
        /*
		  id < 100
		  100 <= id < 500
		  id >= 500
		 */
        // id < 100
        PartialRow lower = new PartialRow(schema);
        PartialRow upper100 = new PartialRow(schema);
        upper100.addInt("id", 100);
        options.addRangePartition(lower, upper100);

        // 100 <= id < 500
        PartialRow lower100 = new PartialRow(schema);
        lower100.addInt("id", 100);
        PartialRow upper500 = new PartialRow(schema);
        upper500.addInt("id", 500);
        options.addRangePartition(lower100, upper500);

        // id >= 500
        PartialRow lower500 = new PartialRow(schema);
        lower500.addInt("id", 500);
        PartialRow upper = new PartialRow(schema);
        options.addRangePartition(lower500, upper);
        // 设置副本数目,奇数位
        options.setNumReplicas(1);

        // c. 在Kudu中创建表
        KuduTable kuduTable = kuduClient.createTable("users_range", schema, options);
        System.out.println("TableId: " + kuduTable.getTableId());
    }

    /**
     * 创建Kudu中的表,表的结构如下所示:
     * create table users(
     *     id int,
     *     name string,
     *     age byte,
     *     primary key(id)
     * )
     * paritition by hash(id) partitions 3
     * stored as kudu ;
     */
    @Test
    public void createKuduTable() throws KuduException {
        // a. 定义Kudu表的Schema信息
        // 定义Kudu表每列Schema信息
        List<ColumnSchema> list = new ArrayList<>();
        list.add(newColumnSchema("id", Type.INT32, true));
        list.add(newColumnSchema("name", Type.STRING, false));
        list.add(newColumnSchema("age", Type.INT8, false));
        // 定义Schema信息
        Schema schema = new Schema(list);

        // b. 定义Kudu表的属性,分区策略,分区数目和副本数
        CreateTableOptions options = new CreateTableOptions();
        // TODO: 设置分区策略,采用Hash分区,分区键必须是主键或主键的一部分
        options.addHashPartitions(Collections.singletonList("id"), 3);
        // 设置副本数目,奇数位
        options.setNumReplicas(1);

        // c. 在Kudu中创建表
        KuduTable kuduTable = kuduClient.createTable("users", schema, options);
        System.out.println("TableId: " + kuduTable.getTableId());
    }

    /**
     * 用于构建Kudu表中每列的字段信息Schema
     *
     * @param name 字段名称
     * @param type 字段类型
     * @param isKey 是否为Key
     * @return ColumnSchema对象
     */
    private ColumnSchema newColumnSchema(String name, Type type, boolean isKey) {
        // 创建ColumnSchemaBuilder实例对象
        ColumnSchema.ColumnSchemaBuilder column = new ColumnSchema.ColumnSchemaBuilder(name, type);
        // 设置是否为主键
        column.key(isKey);
        // 构建 ColumnSchema
        return column.build();
    }

    // 操作结束,关闭KuduClient
    @After
    public void close() throws KuduException {
        // 关闭KuduClient对象,释放资源
        if (kuduClient != null) {
            kuduClient.close();
        }
    }
}

对数据CRUD操作API

import org.apache.kudu.ColumnSchema;
import org.apache.kudu.Type;
import org.apache.kudu.client.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Random;

/**
 * @author: xu
 * @desc: 基于Java API对Kudu表内数据进行CRUD操作
 */
public class DataTest {
    // 对于Kudu操作,获取KuduClient客户端实例对象
    private KuduClient kuduClient = null;

    // 初始化KuduClient实例对象
    @Before
    public void init() {
        // 构建KuduClient实例对象,连接Kudu集群(Kudu Master)
        kuduClient = new KuduClient
                .KuduClientBuilder("node2:7051") // Master地址信息
                .defaultSocketReadTimeoutMs(10000) // 设置超时时间间隔,默认值为10s
                .defaultOperationTimeoutMs(10000) // 设置对此Kudu进行操作时超时时间,默认值为30s
                .build(); // 采用建造者模式构建实例对象
    }

    /**
     * 设置过滤加载数据:比如只查询id和age两个字段的值,id大于1050,年龄age小于25
     */
    @Test
    public void filterQueryData() throws KuduException {
        // a. 获取Kudu Table的句柄,传递表的名称
        KuduTable kuduTable = kuduClient.openTable("users");
        // b. 构建表的扫描器对象Scanner
        KuduScanner.KuduScannerBuilder builder = kuduClient.newScannerBuilder(kuduTable);
        // TODO:设置选取的字段:project(投影)
        builder.setProjectedColumnNames(Arrays.asList("id", "age"));
        // TODO: 设置过滤的条件:predicate(谓词)
        // id大于1050
        builder.addPredicate(KuduPredicate.newComparisonPredicate(
                newColumnSchema("id", Type.INT32, true),
                KuduPredicate.ComparisonOp.GREATER,
                1050
        ));
        // 年龄age小于25
        builder.addPredicate(KuduPredicate.newComparisonPredicate(
                newColumnSchema("age", Type.INT8, false),
                KuduPredicate.ComparisonOp.LESS,
                (byte) 25
        ));
        // 构建kudu Scanner对象
        KuduScanner kuduScanner = builder.build();

        // c. 迭代获取数据,分批次(每个分区查询一次,封装在一起)返回查询的数据
        int counter = 1;
        while (kuduScanner.hasMoreRows()) { // 是否还有表的Tablet数据可以获取
            System.out.println("===================" + (counter++) + "===================");
            // 获取每个tablet中的数据
            RowResultIterator rowResults = kuduScanner.nextRows();
            while (rowResults.hasNext()) {  // 遍历Tablet中每条数据,并打印
                System.out.println(rowResults.next().rowToString());
            }
        }
    }

    /**
     * 从Kudu表中扫描所有数据数据
     */
    @Test
    public void selectAllData() throws KuduException {
        // a. 获取Kudu Table的句柄,传递表的名称
        KuduTable kuduTable = kuduClient.openTable("users");
        // b. 构建表的扫描器对象Scanner,类似HBase中Scan类
        KuduScanner kuduScanner = kuduClient.newScannerBuilder(kuduTable).build();
        // c. 迭代获取数据,分批次(每个分区查询一次,封装在一起)返回查询的数据
        int counter = 1;
        while (kuduScanner.hasMoreRows()) { // 是否还有表的Tablet数据可以获取
            System.out.println("===================" + (counter++) + "===================");
            // 获取返回某批次数据,有多条数据,以迭代器形式返回
            RowResultIterator rowResults = kuduScanner.nextRows();
            // 获取每个tablet中的数据
            while (rowResults.hasNext()) { // 遍历Tablet中每条数据,并打印
                System.out.println(rowResults.next().rowToString());
            }
        }
    }

    /**
     * 删除Kudu表中数据,需要按照主键删除
     */
    @Test
    public void deleteKuduData() throws KuduException {
        // a. 获取Kudu表的句柄,传递表的名称
        KuduTable kuduTable = kuduClient.openTable("users");
        // b. 获取删除数据delete对象
        Delete delete = kuduTable.newDelete();
        // c. 获取Row对象,设置删除主键的值
        PartialRow row = delete.getRow();
        row.addInt("id", 1);

        // d. 获取KuduSession实例对象,删除数据
        KuduSession kuduSession = kuduClient.newSession();
        kuduSession.apply(delete);

        // e. 关闭
        kuduSession.close();
    }

    /**
     * 更新Kudu表中数据,当主键存在时,更新数据;不存在时,插入数据
     */
    @Test
    public void upsertData() throws KuduException {
        // a. 获取Kudu Table的句柄,依据表的名称
        KuduTable kuduTable = kuduClient.openTable("users");
        // b. 获取更新数据upsert对象
        Upsert upsert = kuduTable.newUpsert();
        // c. 获取Row对象,设置更新的值
        PartialRow row = upsert.getRow();
        row.addInt("id", 1);
        row.addString("name", "xqh");
        row.addByte("age", (byte) 22);

        // d. 获取KuduSession实例对象,更新数据
        KuduSession kuduSession = kuduClient.newSession();
        OperationResponse response = kuduSession.apply(upsert);
        System.out.println(response.getElapsedMillis());

        // e. 关闭
        kuduSession.close();
    }

    /**
     * 更新Kudu表中数据,根据主键更新
     */
    @Test
    public void updateData() throws KuduException {
        // a. 获取Kudu Table的句柄,依据表的名称
        KuduTable kuduTable = kuduClient.openTable("users");
        // b. 获取更新数据update对象
        Update update = kuduTable.newUpdate();
        // c. 获取Row对象,设置更新的值
        PartialRow row = update.getRow();
        row.addInt("id", 1);
        row.addString("name", "xqh");
        row.addByte("age", (byte) 21);

        // d. 获取KuduSession实例对象,更新数据
        KuduSession kuduSession = kuduClient.newSession();
        OperationResponse response = kuduSession.apply(update);
        System.out.println(response.getElapsedMillis());

        // e. 关闭
        kuduSession.close();
    }

    /**
     * 多条数据插入表中: INSERT INTO (id, name, age) VALUES (1001, "zhangsan", 26)
     */
    @Test
    public void insertMultipleDataTest() throws KuduException {
        // a. 获取Kudu表的句柄,传递表的名称
        KuduTable kuduTable = kuduClient.openTable("users");
        // b. 获取KuduSession会话对象
        KuduSession kuduSession = kuduClient.newSession();
        // TODO: 设置手动刷新数据到表中
        kuduSession.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH);
        // 批量插入的缓冲区条目数
        kuduSession.setMutationBufferSpace(1000);

        // for循环,遍历100次,插入100条数据
        Random random = new Random();
        for (int i = 1; i <= 100; i++) {
            // c. 构建Insert实例对象,封装插入的每条数据,类似HBase中Put实例对象
            Insert insert = kuduTable.newInsert();

            // 获取Row对象,设置插入的值
            PartialRow row = insert.getRow();
            row.addInt("id", 1000 + i);
            row.addString("name", "zhangsan-" + i);
            row.addByte("age", (byte) (random.nextInt(10) + 20));

            // d. 加入批次中
            kuduSession.apply(insert);
        }
        // TODO: 手动刷新,触发插入数据
        kuduSession.flush();

        // e. 关闭
        kuduSession.close();
    }

    /**
     * 单条数据插入表中:INSERT INTO (id, name, age) VALUES (1, "zhangsan", 26)
     */
    @Test
    public void insertSingleDataTest() throws KuduException {
        // a. 获取操作表句柄
        KuduTable kuduTable = kuduClient.openTable("users");
        // b. 插入数据,获取Insert对象
        Insert insert = kuduTable.newInsert();
        // c. 获取Row对象,设置插入的值
        PartialRow row = insert.getRow();
        row.addInt("id", 1);
        row.addString("name", "zhangsan");
        row.addByte("age", (byte) 26);

        // d. 获取KuduSession,用于对集群进行交互,比如表的CUD操作,插入数据
        KuduSession kuduSession = kuduClient.newSession();
        kuduSession.apply(insert);
        // e. 关闭连接
        kuduSession.close();
    }

    /**
     * 用于构建Kudu表中每列的字段信息Schema
     *
     * @param name 字段名称
     * @param type 字段类型
     * @param isKey 是否为Key
     * @return ColumnSchema对象
     */
    private ColumnSchema newColumnSchema(String name, Type type, boolean isKey) {
        // 创建ColumnSchemaBuilder实例对象
        ColumnSchema.ColumnSchemaBuilder column = new ColumnSchema.ColumnSchemaBuilder(name, type);
        // 设置是否为主键
        column.key(isKey);
        // 构建 ColumnSchema
        return column.build();
    }

    // 操作结束,关闭KuduClient
    @After
    public void close() throws KuduException {
        // 关闭KuduClient对象,释放资源
        if (kuduClient != null) {
            kuduClient.close();
        }
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值