kudu Java API setMutationBufferSpace

往kudu写数据一般有两种方式:impala+kudu,kudu api

  1. impala+kudu: 更删改查很方便,但是效率不高
  2. kudu api: 相对来说会快很多,官方推荐使用 Java API和Python API完成数据写入工作

kudu API 有三种FlushMode:

  1. AUTO_FLUSH_SYNC(默认):所有的写入都只有在自动刷新到服务器后才会返回。不会发生批处理,在这种模式下,Flush()函数不会产生任何效果,因为每个应用程序在返回之前已经刷新了缓冲区
  2. AUTO_FLUSH_BACKGROUND:每一个应用的KuduSession.apply()函数都会返回的非常快,但是写操作会被发送到后台进程,可能与来自同一会话的其他写入一起进行批处理。如果没有足够的缓冲空间,KuduSession.apply()会阻塞,缓冲空间不可用。因为写入操作是在后台应用进行的的,因此任何错误都将存储在一个会话本地缓冲区中。注意:这个模式可能会导致数据插入是乱序的,这是因为在这种模式下,多个写操作可以并发地发送到服务器。这个模式有个bug
  3. MANUAL_FLUSH:每一个应用的KuduSession.apply()函数都会返回的非常快,但是写操作不会发送,直到用户使用flush()函数,如果缓冲区超过了配置的空间限制,KuduSession.apply()函数会返回一个错误

看了网上一些效率测试,相对来说,MANUAL_FLUSH的效率是最高的,而且高很多。

MANUAL_FLUSH

def upsertBatchRows(tableName: String, datas: List[Array[(String, String, String)]], client: KuduClient = this.client): Unit = {
  val table = this.getTable(tableName, client)
  val session = client.newSession()
  session.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH)
  session.setMutationBufferSpace(DATA_COMMIT_SIZE)
  var commitCount = 0
  datas.foreach(data => {
    val upsert = table.newUpsert()
    val row = upsert.getRow
    data.foreach(f => {
      f._2.toLowerCase match {
        case "bigint" => if (f._3.isEmpty) 0 else row.addLong(f._1.toLowerCase, f._3.toLong)
        case "decimal" => if (f._3.isEmpty) 0 else row.addDecimal(f._1.toLowerCase, java.math.BigDecimal.valueOf(f._3.n2e.toDouble))
        case "double" => if (f._3.isEmpty) 0.0 else row.addDouble(f._1.toLowerCase, f._3.toDouble)
        case "float" => if (f._3.isEmpty) 0.0 else row.addFloat(f._1.toLowerCase, f._3.toFloat)
        case "int" => if (f._3.isEmpty) 0 else row.addInt(f._1.toLowerCase, f._3.toInt)
        case "long" => if (f._3.isEmpty) 0 else row.addLong(f._1.toLowerCase, f._3.toLong)
        case "smallint" => if (f._3.isEmpty) 0 else row.addShort(f._1.toLowerCase, f._3.toShort)
        case "timestamp" => row.addTimestamp(f._1.toLowerCase, Timestamp.valueOf(f._3.n2e))
        case "tinyint" => if (f._3.isEmpty) 0 else row.addByte(f._1.toLowerCase, f._3.toByte)
        case "n" => row.setNull(f._1.toLowerCase)
        case _ => row.addString(f._1.toLowerCase, f._3.n2e)
      }
    })
    session.apply(upsert)
    //对于手工提交, 需要buffer在未满的时候flush
    commitCount += 1
    if (commitCount > DATA_COMMIT_SIZE / 2) {
        session.flush()
        commitCount = 0
      }
  })
  session.flush()
  session.close()
}

需要设置buffer大小,测试了50,1000,10000,发现设置为10000时,效率最高

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值