kudu 使用杂记

Kudu 是一个基于 Raft 的分布式存储系统,它致力于融合低延迟写入和高性能分析这两种场景

  1. Kudu 提供了 table 的概念。用户可以建立多个 table,每个 table 都有一个预先定义好的 schema。Schema 里面定义了这个 table 多个 column,每个 column 都有名字,类型,是否允许 null 等。一些 columns 组成了 primary key。
  2. 分区 Kudu 支持对数据按照 Range 以及 Hash 的方式进行分区。 每个大的 table 都可以通过这种方式将数据分不到不同的 Tablet 上面。
  3. 三种Fulsh Mode
    • AUTO_FLUSH_SYNC 默认,自动flush,同步方法,调用 kuduSession.apply() 时立即写入,在写入完成后才会返回一个 OperationResponse 对象,也只有模式下才会返回该对象,其他的都是返回 null,调用kuduSession.flush() 不会有任何操作。
    • AUTO_FLUSH_BACKGROUND 自动后台写入,在apply后会立即返回null,但是写入会在后再自动运行,可能会多条操作用同一个session批量写入,如果缓存条数满了,则会阻塞一会,直至缓冲区有可用的空间在返回。因为可能多条并发写入,所以写入顺序可能是无序的,(猜测当一条数据先插再删、变成先删再插可能就有问题,并没有测试过)。因为后台写入,多以error信息会存储在 session-local buffer 中,通过 kuduSession.countPendingErrors() 访问等待的error数量,kudu.getPendingErrors() 得到error的操作进行重试。调用kuduSession.fulsh()时会阻塞,直至缓冲区为空。
    • MANUAL_FLUSH 手动flush,在此状态下调用 apply() 会立即返回null,只有用户调用 kuduSession.fulsh() 的时候才会发送写入操作。如果超过了缓冲区配置的大小,在 apply() 的时候会返回一个error。

      kuduSession.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH);
  4. kudu 原生对impala 做了很好的兼容,用impala可以很方便的使用sql对kudu进行操作,我们在项目中是使用了 impala 和原生 kuduClient 相结合的方式进行。
  5. impala 和 kuduClient 的选择
    • 就查询来说,在我的使用过程中 impala 的查询速度要快于 kuduClient 的 scan。建议使用impala
    • insert 的速度都很快 upsert/update/delete 如果用主键的话也都很快,但impala的并发性能比较差,所以这种操作尽量用 kuduClient 的原生 api 进行操作
    • 原生 api update、delete、upsert 只能根据主键操作,如果需要其他条件则需要查询一下,拿到主键再进行操作,所以不如impala写sql方便,看具体情况吧,只要 impala 吼得住并发,或做好资源隔离。
    • 原生 api 在操作上有些不方便,我们自己封装了一个简单的 spring starter ,还在完善,当然也可以把核心代码拿出来自己封装。链接:https://gitee.com/git-of-Jason/kudu-spring-boot-starter

下面是使用impala和原生api操作kudu中遇到的一点问题

  1. impala用sql操作 set version = version + 1 ,version 必须是 bigint,因为 version(int)+1 结果是bigint
  2. json中的 ” 会被转义为 \” 而当作为sql存入的时候 \” 又会被反译 为 ” 所以,再取出来就不是规范的json格式了。。不过这个问题是所有拼接 sql 提交查询的共性问题
    //所以把其中的 \ 替换为 \\ , " 替换为 \"
    str = str.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"");
    // ps : replaceAll 的参数是正则,所以 \\\\ = 正则 \\ = 真正的 \ 
  1. kudu 支持最大300列,每个字段不超过64K(包括String类型和二进制类型)。一般每列不建议超过1k,每行不建议超过100K。
  2. impala 大小写不敏感,kudu 大小写敏感,Impala建表时的大小写除了表名其他的所有字段都会变成小写进入kudu

    impala 会保存 kudu 的 schema,所以使用impala查询全程大小写混搭无所谓的,但用 kudu 原生api,要注意,表名区分大小写,列名全程小写。

  3. impala 建一个数据库 wx ,建一个表 test,在kudu中没有 数据库的概念,impala会把它声明为, impala::db.tableName -> impala::wx.test

  4. 使用原生kudu api upsert 时,除了传入主键的几个字段外,not null的字段也必须传入,否则更新不了,如果用 impala 写sql 就会报错的,但用原生 api 正常返回 OperationResponse 里面有错误信息,如果不主动检查是发现不了更新失败的。
  5. 用原生 api 进行删除操作,只能set 主键作为条件,其他的字段都不能设置,会失败,在 OperationResponse 可以看到错误信息。但如果用 impala 的话,where 条件就无所谓了,更正常 sql 一样, impala 会处理的

使用过程中对默认参数的调整

  1. impala 文件操作符数量(ulimit) 32,768 -> 50000 观察中
  2. kudu
Kudu Tablet Server Block Cache Capacity
block_cache_capacity_mb 512M -> 1G


Kudu Tablet Server Hard Memory Limit
memory_limit_hard_bytes 默认 4G -> 30 G  这个参数尽量大,机器 80% 左右

pom.xml

额,正常不用这么复杂,只是我们用的 cloudera 公司的版本所以需要引,cloudera 公司的私有库

  <properties>
    <cdh.hive.version>1.1.0-cdh5.10.0cdh.hive.version>
    <cdh.hadoop.version>2.6.0-cdh5.10.0cdh.hadoop.version>
  properties>

  
  <repositories>
    <repository>
      <id>cdh.repoid>
      <url>https://repository.cloudera.com/artifactory/cloudera-reposurl>
      <name>Cloudera Repositoriesname>
      <snapshots>
        <enabled>falseenabled>
      snapshots>
    repository>
    <repository>
      <id>cdh.snapshots.repoid>
      <url>https://repository.cloudera.com/artifactory/libs-snapshot-localurl>
      <name>Cloudera Snapshots Repositoryname>
      <snapshots>
        <enabled>trueenabled>
      snapshots>
      <releases>
        <enabled>falseenabled>
      releases>
    repository>
  repositories>

  <dependencies>
        <dependency>
            <groupId>org.apache.hivegroupId>
            <artifactId>hive-jdbcartifactId>
            <version>${cdh.hive.version}version>
            
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jetty.aggregategroupId>
                    <artifactId>jetty-allartifactId>
                exclusion>
                <exclusion>
                    <groupId>org.apache.hivegroupId>
                    <artifactId>hive-shimsartifactId>
                exclusion>
            exclusions>
        dependency>

        <dependency>
          <groupId>org.apache.hadoopgroupId>
          <artifactId>hadoop-commonartifactId>
          <version>${cdh.hadoop.version}version>
        dependency>
    dependencies>

你可能感兴趣的:(kudu,impala)