我們知道hbase是一個多版本的管理系統,在0.96的版本之前默認每個列是3個version,在hbase 0.96之后每個列是1個version,所謂的version其實就是同一條數據插入不同的時間戳來實現的,在hbase底層的存儲是基于時間戳排序的,所以每次我們查到的數據都是最新的版本,除非我們指定了要讀取特定的時間范圍的數據。
先看下Hbase里面Put和Delete命令的api:
Put:
Delete:
如上,常用的pu和delete方法基本都是第一個,默認我們使用Put命令插入一條數據后,它的時間戳取的是當前時間戳,當然我們也可以自己設置時間戳,但是我建議不要隨便設置這個時間戳,設置的不對有可能引起一些莫名奇妙的問題,剛才說過hbase在讀取的時候是按時間降序排序的,每次讀取到的都是最新的,那么假如在put的時候設置這個時間戳為Long.MAXVALUE,那么后面你在插入,刪除或者更新的時候沒有傳入時間戳,那么你就會驚奇的發現插入,刪除,更新全部失效,為什么?
因為你該次操作的時間戳小于Long.MAXVALUE,而且你的version只有一個,所以hbase認為一個舊的版本是不能覆蓋新的版本的,同樣刪除也是,你會發現無論你執行多少次刪除命令,該條數據就是不能夠被刪除掉。
注意,在上面的api中Put和Delete的第二個方法都是帶時間戳的,大家不要誤解,這個時間戳不是rowkey的,它這個時間戳是給下面的column用的,也就是說如果插入一行數據,這行數據中有多個列簇,每個列簇下面都有多個列的話,而且他們的時間戳都一樣,那么我就可以直接在put的第二個參數指定,而不需要在每個column上指定,當然如果我們在column上也指定了時間戳,那么默認優先使用column上的時間戳。
總結:
hbase的多版本存儲特性是一個強大的功能,在使用的時候應該注意盡量不要修改默認取當前時間戳的邏輯,如果修改了那么在其他添加,刪除,更新的時候都應該考慮當前的時間戳是否大于第一次插入時的時間戳,如果不是,那么本次修改就不會生效,所以某一天當你刪除一行hbase數據時,發現它并沒有被刪除掉,不要驚訝,在代碼沒有問題的情況下,最大的可能就是當前時間戳小于庫里數據的時間戳,這一點需要特別注意,最后再重復一遍,盡量不要在向hbase插入數據的時候設置自定義的時間戳,除非業務場景需要。