上篇关于HBase source code的文章介绍了Cell.
现在介绍Cell的一个实现, KeyValule. 也可以说是关键的实现.
如果说Cell只是提供一个basic unit的框架的话, 那么KeyValue就是实打实的底层存储模型.
(KeyValue实现有2744行, 不贴code了...)
KeyValue的模型:
<keylength> <valuelength> <key> <value>, 更进一步的<key>可以被进一步拆分:
<rowlength> <row> <columnfamilylength> <columnfamily> <columnqualifier> <timestamp> <keytype>, 所以正常来说整个KeyValue模型应该是:
<keylength> <valuelength> <rowlength> <row> <columnfamilylength> <columnfamily> <columnqualifier> <timestamp> <keytype> <value>
从Cell那里得知, 应该还有tags啊! 对, 没错, 不过这是optional的, 就是可有可无. 所以最完整的模式应该是:
<keylength> <valuelength> <key> <value> <tagslength> <tagsbytes>
(tagsbyte还可以拆分: <taglength><tagtype><tagbytes>) tag的个数可以很多个. 不过总tag长度不能超过65,535就是了 这个数字是什么大家懂的.
插个图:
无论从图中的单位还是从实现Cell的角度都可以看得出来, KeyValue 内部成员同样有一个byte[]数组, offset和length 和Cell是一样的.
其实为什么用byte作基本单位想必也很显然, 就是为了减少overhead
但是我们看到Key那么长也是醉了, 所以HBase一直鼓励Column的设计一定要轻便.
说一个容易混淆点: 关于row和key!!!
row其实就是我们俗称的row key. 就是row的属性值.
key是storage的一个概念. 一个key应该是由rowkey, column family, column qualifier, timestamp, type组合而成. 其实也就是一个Cell的key.
KeyValue没有实现Java的Comparable接口
但是内部提供了很多关于Comparator的内部类, 原因是这样的, 因为KeyValue的存储模型是基础, 而HBase中的各部件的比较不唯一. 需要根据上下文来决定的.
所以KeyValue采取了提供多个Comparator的方式.
MetaComparator: 这是用来比较hbase:meta中的KeyValue
KVComparator: 这只用来比较KeyValue中属于Key的部分, 这意味着, 只要两个Cell做比较时, 只要Key相同, 两个Cell就相同, 无论Value为何值.
RowOnlyComparator: 只用来比较KeyValue的Key中属于row的部分
RawBytesComparator: 这是工程师们再对HBase作测试的, 测试类而已, 平常使用用不到.
既然KeyValue是实现Cell接口的, 所以Cell接口里面定义的methods, 必须都实现, 不累赘叙述.
还有包括各种copy类型的操作, 从I/O流读入成KeyValue或写出成I/O流的操作, 不可能一一列举.
不过虽然说是2744行, 不过还是算蛮容易读的, 当然要了解到细节处处还是花费一些时间.
我是属于不算深入, 但不至于浅尝, 最重要的是这个class的目的和意义和用途和提供的methods我都知道了, 这就够研究使用了.
除非要到需要改source code的程度, 则可能需要细究一下.
不过因为是较底层的数据结构, 应该改不到这里, 里面到是有用到好多经典算法, 值得学习与品味, 例如二分搜索, 跟课本如出一辙, 第一次感觉课本所学跃然于实际应用中, 有点意思.
好, 如此!
from Reid Chan