Kudu——Java操作Kudu

1、构建maven 工程、导入依赖

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

2、初始化方法

public class TestKudu {
    //声明全局变量 KuduClient 后期通过它来操作 kudu 表
    private KuduClient kuduClient;
    //指定 kuduMaster 地址
    private String kuduMaster;
    //指定表名
    private String tableName;
    @Before
    public void init(){
        //初始化操作
        kuduMaster="node1:7051,node2:7051,node3:7051";
        //指定表名
        tableName="student";
        KuduClient.KuduClientBuilder kuduClientBuilder = new
        KuduClient.KuduClientBuilder(kuduMaster);
        kuduClientBuilder.defaultSocketReadTimeoutMs(10000);
        kuduClient=kuduClientBuilder.build();
    }
}

3、创建表

/**
 * 创建表
 */
@Test
public void createTable() throws KuduException {
    //判断表是否存在,不存在就构建
    if(!kuduClient.tableExists(tableName)){
        //构建创建表的 schema 信息-----就是表的字段和类型
        ArrayList<ColumnSchema> columnSchemas = new ArrayList<ColumnSchema>();
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("id",
            Type.INT32).key(true).build());
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("name",
            Type.STRING).build());
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("age",
            Type.INT32).build());
        columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("sex",
            Type.INT32).build());
        Schema schema = new Schema(columnSchemas);
        //指定创建表的相关属性
        CreateTableOptions options = new CreateTableOptions();
        ArrayList<String> partitionList = new ArrayList<String>();
        //指定 kudu 表的分区字段是什么
        partitionList.add("id"); // 按照 id.hashcode % 分区数 = 分区号
        options.addHashPartitions(partitionList,6);
        kuduClient.createTable(tableName,schema,options);
    }
}

4、插入数据

/**
 * 向表加载数据
 */
@Test
public void insertTable() throws KuduException {
    //向表加载数据需要一个 kuduSession 对象
    KuduSession kuduSession = kuduClient.newSession();
    kuduSession.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
    //需要使用 kuduTable 来构建 Operation 的子类实例对象
    KuduTable kuduTable = kuduClient.openTable(tableName);
    for(int i=1;i<=10;i++){
        Insert insert = kuduTable.newInsert();
        PartialRow row = insert.getRow();
        row.addInt("id",i);
        row.addString("name","zhangsan-"+i);
        row.addInt("age",20+i);
        row.addInt("sex",i%2);
        kuduSession.apply(insert);//最后实现执行数据的加载操作
    }
}

5、查询数据

/**
 * 查询表的数据结果
 */
@Test
public void queryData() throws KuduException {
    //构建一个查询的扫描器
    KuduScanner.KuduScannerBuilder kuduScannerBuilder =
        kuduClient.newScannerBuilder(kuduClient.openTable(tableName));
    ArrayList<String> columnsList = new ArrayList<String>();
    columnsList.add("id");
    columnsList.add("name");
    columnsList.add("age");
    columnsList.add("sex");
    kuduScannerBuilder.setProjectedColumnNames(columnsList);
    //返回结果集
    KuduScanner kuduScanner = kuduScannerBuilder.build();
    //遍历
    while (kuduScanner.hasMoreRows()){
        RowResultIterator rowResults = kuduScanner.nextRows();
        while (rowResults.hasNext()){
            RowResult row = rowResults.next();
            int id = row.getInt("id");
            String name = row.getString("name");
            int age = row.getInt("age");
            int sex = row.getInt("sex");
            System.out.println("id=" + id + " name=" + name + " age=" + age + "sex=" + sex);
        }
    }
}

6、修改数据

/**
 * 修改表的数据
 */
@Test
public void updateData() throws KuduException {
    //修改表的数据需要一个 kuduSession 对象
    KuduSession kuduSession = kuduClient.newSession();
    kuduSession.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
    //需要使用 kuduTable 来构建 Operation 的子类实例对象
    KuduTable kuduTable = kuduClient.openTable(tableName);
    //Update update = kuduTable.newUpdate();
    Upsert upsert = kuduTable.newUpsert(); //如果 id 存在就表示修改,不存在就新增
    PartialRow row = upsert.getRow();
    row.addInt("id",100);
    row.addString("name","zhangsan-100");
    row.addInt("age",100);
    row.addInt("sex",0);
    kuduSession.apply(upsert);//最后实现执行数据的修改操作
}

7、删除数据

/**
 * 删除数据
 */
@Test
public void deleteData() throws KuduException {
    //删除表的数据需要一个 kuduSession 对象
    KuduSession kuduSession = kuduClient.newSession();
    kuduSession.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
    //需要使用 kuduTable 来构建 Operation 的子类实例对象
    KuduTable kuduTable = kuduClient.openTable(tableName);
    Delete delete = kuduTable.newDelete();
    PartialRow row = delete.getRow();
    row.addInt("id",100);
    kuduSession.apply(delete);//最后实现执行数据的删除操作
}

8、删除表

@Test
public void dropTable() throws KuduException {
    if(kuduClient.tableExists(tableName)){
        kuduClient.deleteTable(tableName);
    }
}

9、Kudu分区方式

为了提供可扩展性,Kudu 表被划分为称为 tablet 的单元,并分布在许多tablet servers 上。行总是属于单个 tablet 。将行分配给 tablet的方法由在表创建期间设置的表的分区决定。 Kudu提供了 3 种分区方式。

9.1、Range Partitioning ( 范围分区 )

范围分区可以根据存入数据的数据量,均衡的存储到各个机器上,防止机器出现负载不均衡现象。

/**
* 测试分区:
* RangePartition
*/
@Test
public void testRangePartition() throws KuduException {
    //设置表的 schema
    LinkedList<ColumnSchema> columnSchemas = new
    LinkedList<ColumnSchema>();
    columnSchemas.add(newColumn("CompanyId", Type.INT32,true));
    columnSchemas.add(newColumn("WorkId", Type.INT32,false));
    columnSchemas.add(newColumn("Name", Type.STRING,false));
    columnSchemas.add(newColumn("Gender", Type.STRING,false));
    columnSchemas.add(newColumn("Photo", Type.STRING,false));
    //创建 schema
    Schema schema = new Schema(columnSchemas);
    //创建表时提供的所有选项
    CreateTableOptions tableOptions = new
    CreateTableOptions();
    //设置副本数
    tableOptions.setNumReplicas(1);
    //设置范围分区的规则
    LinkedList<String> parcols = new LinkedList<String>();
    parcols.add("CompanyId");
    //设置按照那个字段进行 range 分区
    tableOptions.setRangePartitionColumns(parcols);
    /**
     * range
     * 0 < value < 10
     * 10 <= value < 20
     * 20 <= value < 30
     * ........
     * 80 <= value < 90
     **/
    int count=0;
    for(int i =0;i<10;i++){
        //范围开始
        PartialRow lower = schema.newPartialRow();
        lower.addInt("CompanyId",count);
        //范围结束
        PartialRow upper = schema.newPartialRow();
        count += 10;
        upper.addInt("CompanyId",count);
        //设置每一个分区的范围
        tableOptions.addRangePartition(lower,upper);
    }
    try {
        kuduClient.createTable("student",schema,tableOptions);
    } catch (KuduException e) {
        e.printStackTrace();
    }
    kuduClient.close();
}

9.2、Hash Partitioning ( 哈希分区 )

哈希分区通过哈希值将行分配到许多 buckets ( 存储桶 )之一; 哈希分区是一种有效的策略,当不需要对表进行有序访问时。哈希分区对于在 tablet之间随机散布这些功能是有效的,这有助于减轻热点和 tablet 大小不均匀。

/**
 * 测试分区:
 * hash 分区
 */
@Test
public void testHashPartition() throws KuduException {
    //设置表的 schema
    LinkedList<ColumnSchema> columnSchemas = new
    LinkedList<ColumnSchema>();
    columnSchemas.add(newColumn("CompanyId", Type.INT32,true));
    columnSchemas.add(newColumn("WorkId", Type.INT32,false));
    columnSchemas.add(newColumn("Name", Type.STRING,false));
    columnSchemas.add(newColumn("Gender", Type.STRING,false));
    columnSchemas.add(newColumn("Photo", Type.STRING,false));
    //创建 schema
    Schema schema = new Schema(columnSchemas);
    //创建表时提供的所有选项
    CreateTableOptions tableOptions = new
    CreateTableOptions();
    //设置副本数
    tableOptions.setNumReplicas(1);
    //设置范围分区的规则
    LinkedList<String> parcols = new LinkedList<String>();
    parcols.add("CompanyId");
    //设置按照那个字段进行 range 分区
    tableOptions.addHashPartitions(parcols,6);
    try {
        kuduClient.createTable("dog",schema,tableOptions);
    } catch (KuduException e) {
        e.printStackTrace();
    }
    kuduClient.close();
}

9.3、Multilevel Partitioning ( 多级分区 )

Kudu 允许一个表在单个表上组合多级分区。 当正确使用时,多级分区可以保留各个分区类型的优点,同时减少每个分区的缺点需求。

/**
 * 测试分区:
 * 多级分区
 * Multilevel Partition
 * 混合使用 hash 分区和 range 分区
 *
 * 哈希分区有利于提高写入数据的吞吐量,而范围分区可以避免tablet 无限增长问题,
 * hash 分区和 range 分区结合,可以极大的提升 kudu 的性能
 */
@Test
public void testMultilevelPartition() throws KuduException {
    //设置表的 schema
    LinkedList<ColumnSchema> columnSchemas = new
    LinkedList<ColumnSchema>();
    columnSchemas.add(newColumn("CompanyId", Type.INT32,true));
    columnSchemas.add(newColumn("WorkId", Type.INT32,false));
    columnSchemas.add(newColumn("Name", Type.STRING,false));
    columnSchemas.add(newColumn("Gender", Type.STRING,false));
    columnSchemas.add(newColumn("Photo", Type.STRING,false));
    //创建 schema
    Schema schema = new Schema(columnSchemas);
    //创建表时提供的所有选项
    CreateTableOptions tableOptions = new
    CreateTableOptions();
    //设置副本数
    tableOptions.setNumReplicas(1);
    //设置范围分区的规则
    LinkedList<String> parcols = new LinkedList<String>();
    parcols.add("CompanyId");
    //hash 分区
    tableOptions.addHashPartitions(parcols,5);
    
    //range 分区
    int count=0;
    for(int i=0;i<10;i++){
        PartialRow lower = schema.newPartialRow();
        lower.addInt("CompanyId",count);
        count+=10;
        PartialRow upper = schema.newPartialRow();
        upper.addInt("CompanyId",count);
        tableOptions.addRangePartition(lower,upper);
    }
    try {
        kuduClient.createTable("cat",schema,tableOptions);
    } catch (KuduException e) {
        e.printStackTrace();
    }
    kuduClient.close();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值