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