hbase时间戳修改带来的问题总结

公司业务:数据录入的时候,同一时刻,一条数据的某个字段存在多版本状况。
根据资料,hbase 插入数据的时候能够手动设置时间戳,这样把多个版本的时间戳区别开,可是发现hbase数据不能删除。java

通过分析,这是因为:插入数据时候,人为设定的时间戳大于,删除的时间戳。 当client端系统时间大于集群系统时间,就会可能出现这种状况。数据库

做结,hbase java代码部署的client服务器,最好和集群hbase服务器时间作同步,就会避免以上问题。服务器

 

你们知道,像OB,HBase这种存储系统,插入数据的时候,通常数据上都会有一个时间戳(ts)。spa

Hbase有一个TTL(time to live),能够标识数据的有效期,好比,能够把TTL设置成86400*1000,也就是说数据将于1天后过时。这是一个表级的设置,必须在建表时指定。blog

可是若是说你须要存储某一天内的数据,到次日0点失效。这种状况TTL是无法控制的,由于TTL只能控制数据在一段时间后失效,而不能控制在特定的时间点失效。部署

TTL的本质是经过对比数据的ts,与当前系统时间,而后肯定是否应该失效,因而,咱们能够经过ts来hack一下。同步

假设数据的TTL是1天,若是我在凌晨1点插入数据,那么正常状况,它会到次日凌晨1点失效。实际上就是判断:currentMilliseconds - ts > 86400*1000,若是知足,数据就失效了。博客

这时若是要控制数据在次日0点就失效,咱们把插入数据的ts日后推一小时就能够了,它就会提早失效。it

 

这个方案理论上看起来没有问题,可是若是你的表涉及到删除数据,那么,坑就来了。集群

 

HBase普通的操做,都会写入WAL(Write ahead log),累积到必定数量后(或者根据时间),根据操做的ts,进行merge,而后对真实的数据作commit,这个跟数据库的log是有点相似的。

 

这里面隐含的一点是,hbase中的操做,是须要ts比当前数据中的ts大,操做才会有效,不然就无效(正常的都是这样的,由于时间是不断变大的嘛)。

 

好比当前有2个操做:

put 'key', 'value', ts=1

put 'key', 'value', ts=2

那么通过合并后,实际上只会有一个操做:

put 'key', 'value', ts=2(由于这个时间戳比较大嘛)

 

接着来,若是有3个操做:

put 'key', 'value', ts=1

put 'key', 'value', ts=2

del 'key', 'value', ts=3

那么,合并后,就只有delete的操做了。

坑就在这里,由于咱们是手动设置插入数据的ts的。这就意味着,若是要删除数据,那必需要将删除操做的ts设置得比原来的数据的ts要大(在咱们的状况中,两个时间都是将来)。

 

若是删除操做,使用了系统默认的ts,那么形成的结果是:数据没法被删除。

 

OK,那咱们就知道,会将删除的ts设大。但是这时,若是你再插入数据,就必须将插入数据的ts设置得比删除操做的ts还要大。。。其实就是,对同一个cell的操做,要想你的操做有效,你必须将它的ts设置为比当前操做序列中最大的还要大。。。

 

而后,若是一不当心,你想固然地把删除的ts设置成了Long.MAX_VALUE,你就会发现,你永远也插入不了数据了。。。。(其实不是永远啦,要到下一次major compact)。

 

最后的总结:谨慎修改数据的ts。。。

最后参考一个博客,很实用:http://zjushch.iteye.com/blog/1243522

相关文章
相关标签/搜索