hbase并发插入之checkAndPut

最近在写spark程序的时候遇到了hbase并发插入的问题,用sparkstreaming来接收kafka的数据,由于数据量较大,我用spark的executer端去并行插入hbase,结果发现有些数据没插进去,经过排查之后,发现是同一个批次中行键相同的数据,这些数据只能插入一部分或者都能插入,这里面存在一定的概率问题,原因就是不同的executer端会反复读写这些行键相同的数据行,导致数据不满足一致性。
后来用checkAndPut解决了这个问题,简单说来,就是在put数据之前先经过某些条件的验证,只有满足条件的put才会入库。
checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put) 第一个参数是行键,第二个参数是列族,第三个参数是列名,第四个参数是预期的列值,最后一个参数是put对象。

def putsumm(rowkey:String,htable:HTableInterface,obj:ExpressPointAlloSummary): Unit ={
    var checkvalue :Array[Byte] = null
    val get = new Get(rowkey.getBytes())
    val orderd = htable.get(get)
    if (recordExist(orderd)) {
      checkvalue = getColumnValue(orderd, "brgew").getBytes()
    }

    var orderNumSuccess: Boolean = false
    // 循环写入数据次数
    var orderNumLoopNum: Int = 0
    while (!orderNumSuccess && orderNumLoopNum < 20) {
      val rltPut = new Put(rowkey.getBytes)
      rltPut.add(Bytes.toBytes("f"), Bytes.toBytes("fc_time"), Bytes.toBytes(obj.fc_time))
      rltPut.add(Bytes.toBytes("f"), Bytes.toBytes("site_cd"), Bytes.toBytes(obj.site_cd))
      rltPut.add(Bytes.toBytes("f"), Bytes.toBytes("dest_site"), Bytes.toBytes(obj.dest_site))
      rltPut.add(Bytes.toBytes("f"), Bytes.toBytes("brgew"), Bytes.toBytes(obj.brgew))
      rltPut.add(Bytes.toBytes("f"), Bytes.toBytes("gewei"), Bytes.toBytes(obj.gewei))


      orderNumSuccess = htable.checkAndPut(
        Bytes.toBytes(rowkey),
        Bytes.toBytes("f"),
        Bytes.toBytes("brgew"),
        checkvalue, rltPut)
      logger.info("wyk")
      orderNumLoopNum+=1
    }
    println(orderNumSuccess)
}

当然在并发超级高的时候,可能一直不满足条件,就会一直不入库,但这种概率是非常低的,可以忽略不计,为了避免陷入死循环或者循环时间太久,这里限制只循环20次,已经满足业务场景了。在这里插入代码片

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值