公司業務:數據錄入的時候,同一時刻,一條數據的某個字段存在多版本狀況。
根據資料,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