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