今天我们回归技术路线,讲讲Google三驾马车里的BigTable。以前有个说法叫做麻子不叫麻子,叫坑人。取其原意是满脸是坑的人,谐音表示人被坑了。我们知道水浒里面有李鬼装李逵然后遇到真李逵的段子。BigTable这篇论文非常的难懂,很大程度上是因为它选择了一些名为李逵实为李鬼的名字来装饰自己,从而使得通俗易懂的数据模型变得奇葩起来。
Google三架马车里面,唯独BigTable写得高深难懂,很多时候其实是你首先要理解BigTable里面的一些名字的基本概念。因为BigTable借用了很多的关系数据库的术语来表示并非是关系数据库的东西,所以我们的理解就似是而非了。这篇文章我们先聊一聊BigTable的数据模型。下一篇文章我们再仔细谈BigTable的实现。
关于这个数据模型我一直很困惑,一知半解,直到某天读了一篇文章:Understanding HBase and BigTable,顿时有豁然开朗的感觉。本文的数据模型部分很大程度上是我理解了这篇文章以后自己的一个小结,强烈建议大家再把这篇文章翻出来读一读。
BigTable的论文是这样解释BigTable的:
A BigTable is a sparse, distributed, persistent multidimensional sorted map.
大家注意一下,BigTable是一个Map不是一个Table。所以一开始就给带到沟里去了,你想象一个有行有列的table的时候,对方告诉你其实就是Map。 Map是什么,学过数据结构的都知道。C++有 map和unordered_map, Java有TreeMap HashMap。说白了map就是有key有value的KV store。这就是为什么BigTable被叫做key-value store的原因。其实我觉得干脆改名叫BigMap大家估计就没那么糊涂了。Map叫Table,就和李鬼叫李逵区别不大,只有坑人的份。所以下面开始我就用BigMap来称呼。
我们继续看看这个map是什么样的,map的value很简单,是个string。Key就比较复杂了,它是一个复合key<key1, key2, key3>.其中这几个key的名字分别如下:
key1: row
key2: column
key3:timestamp
所以我们知道为什么又一次坑爹了,因为在一个正常的Table里面的row和column到这里变成了key的一部分。在BigTable里,key3是个64bit的number,key1和key2分别是string。key1是很单纯的string,而key2则复杂一点,key2的组成如下
key2prefix:postfix
key2prefix叫做column family,和postfix一起组成完整的key,column family在每个BigMap里面有有限个,但是那个postfix其实可以有无数多个。我这里用key1,key2,key3是希望大家不要再去联想那个有行有列的对我们非常熟悉的关系数据库里面的表。说白了,就是key和value的一个很简单的数据模型。
我们再看看这个定义:
Sorted:这个好理解了,BigMap是个sortedMap,不是个HashMap。这一点不同于Amazon的Dynamo,另外一个非常著名的Key-Value store。具体来讲是sort在key1和key2的顺序,而key3的timestamp则从大排到小。要注意的是,虽然说key3被称为timestamp,实际上按照论文的说法,你可以自己随便指定值,而不是非得要当前的timestamp。
Persistent:这个也好理解。这个Map不会因为断了电,机器挂了之类的数据就丢失了。
Sparse:说白了这个Map非常的sparse,不像我们理解的关系数据库里面的表那样,每个行列组成的格子里面都有值。
对BigTable进行查找主要有几种方式:
- 给key1,key2,key3,返回的是小于或者等于key3的那个最大的数据。
- 给了key1和key2,返回是key3值最高的那个数据。
- key2可以只给prefix,返回所有prefix符合的值。
从上述查询来看,其实key3叫timestamp还算合理,但是key1和key2分别叫row和column则有些坑爹,加上整个Map又被叫成了Table,所以我读的时候总是会联想到那个关系数据库里面行列组成的Table,于是在理解数据模型的时候就被带到沟里了。等我终于理解以后,我真有一种特别想骂人的感觉。所以取名很重要,不会因为黄小明改名成黄晓明就变成帅哥的。
转自:飞总聊IT