zoukankan      html  css  js  c++  java
  • HBase中数据的多版本特性潜在的意外

    HBase做为KeyValue结构存储,在存储上是依照RowKey的字典序进行排序,对于很多应用而言这可能远远不够,好在HBase的数据可以存储多个版本,并且版本可以排序,其理论上最大的版本数目Integer.MAX_VALUE,这在一定程度上简化应用端的设计 

    举个例子,假设现在有一个应用,对用户的每次登录信息(如:时间+IP)进行,并要求可以快速获取指定用户的最近登录信息,如果选用HBase存储则可以设计为:RowKey为用户ID,value为IP地址,并指定timestamp为登录时间,依照版本的保留特性,可以很容易地保存用户近一月、近一年的登录信息。 

    看起来上面的设计很不错,毕竟用户啥都不需要操作,HBASE可以很容易为你保留近一段时间内的数据 

    但是,如果一知半解,很可能会发生一些你意料之外的现象 

    1.先后插入两条数据,他们拥有相同的RowKey,列,以及timestamp,不同的value 
    实际结果:只能获取到第2次插入的数据,而不是两个版本 

    2.先插入一条数据,版本为t1,然后删除版本t1,再插入一条数据,版本仍为t1 
    实际结果:读取版本为t1的数据时为空 

    3.先删除版本小于t1的数据,再插入一条数据,版本为t2,并且t2<t1 
    实际结果:读取版本为t2的数据时为空 

    出现这样现象的原因可由KeyValue的大小计较 和 HBase的插入删除逻辑解释 

    a.KeyValue的大小比较规则,优先级从大到小依次为RowKey cf+cq timestamp type, 
    具体点比如说,在比较2个KeyValue时,先比较RowKey的大小('a' < 'b'),相同的情况下比较cf+cq的大小('cf1:q1'<'cf2:q1'<'cf2:q2'),如果还是相同的话就比较时间戳(3042211081<3042211080,注意 我没写错,你没看错,时间戳的long值越大,表示数据越新,在从小到大的队列中越靠前),如果上述仍然还相同则比较TYPE('DeleteFamily' < 'DeleteColumn' < 'Delete' < Put) 


    b.HBase的插入和删除都是是向HBase提交一条KeyValue,而真正的物理删除发生在compact时,所以,在客户端,虽然相同的版本插入和删除有先后顺序,但是在服务端上,这是不可见的,相同的版本号,delete类型的KV永远都排在put前,而读到delete的kv后,就直接返回了 

    如果要避免23现象出现,则需要在插入前做compact操作,这样才能得到想要的结果 

    4.HBase设计为版本数最多为Integer.MAX_VALUE,但是如果你真插入了接近该数的版本后,那可能有很大的风险在等着你 
    首先,compact时很有可能就out of memory 
    其次,单个rowkey的region再大也是不会split的

    转载请注明出处,期待共同进步...
  • 相关阅读:
    一个简单XQuery查询的例子
    《Microsoft Sql server 2008 Internals》读书笔记第七章Special Storage(1)
    《Microsoft Sql server 2008 Internals》读书笔记第八章The Query Optimizer(4)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(4)
    SQL Server中SMO备份数据库进度条不显示?
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(5)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(3)
    《Microsoft Sql server 2008 Internal》读书笔记第八章The Query Optimizer(2)
    省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例
    FireFox意外崩溃时的手工恢复命令
  • 原文地址:https://www.cnblogs.com/zhangyukun/p/3713876.html
Copyright © 2011-2022 走看看