F1到底是啥?Spanner的论文里只说它是广告业务系统,Google在今天五月另外还发过一篇文章专门讲的F1,当时没看懂就忘了,现在重看,可以串起来了。
F1才是所谓的分布式数据库,Spanner是它下层的k/v存储(保证了冗余分布和ACID),二者其实是紧密结合的,上层应用的数据模型决定了下层的设计实现,因为F1以前在MySQL上就是按CustomerID做shard,所以到了Spanner里才会有树状的directory,并且以directory为粒度来实现冗余分布,甚至我前天没搞明白的那个问题(为什么不用LSM-tree而用B-tree)很可能也是指:在物理文件的组织上采用树状结构来对应directory,可每个文件本身还是LSM,因为WAL还在,而且时间戳是每条数据的必备属性。
由于F1的那篇文章其实不是文章,只是个PPT,只讲了WHAT,没有讲HOW,而且篇幅很短,所以各种数据库功能实现到了什么程度以及如何实现的,现在还只能靠猜。但有几点比较明确:
1) 除了树状主键外,数据本身是Protocol Buffer格式的,直接作为key-value store的value存放到Spanner里。
2) PB格式的模型和传统关系型的数据模型很不一样,其field可以为略去可以重复,所以,某些从前要另外建表的场景,在PB里可能就直接全部存一起了,譬如customer { id, name, item[*] { iid, price[?], weight[?], size[?]} },这样,它就用数据的冗余来避免了JOIN和外键的需求。虽然分布式场合下,数据多存几遍多占些内存和硬盘空间已经不是问题,可冗余数据在需要更新的时候还是很麻烦,估计目前F1的场景里很少有这样的需求。
3) 他们自己也承认,基于这样的数据模型来实现的SQL,只是看着眼熟而已,如果真像传统SQL那么用,一些隐含的JOIN操作或遍历请求会使性能非常糟糕,但他们是Google,他们可以说这是ORM本身的问题 (“These hurt performance in all databases. They are disastrous on F1”),所以目前他们自己用的F1客户端的库也限定了使用者不能使用join,所有数据都必须显式地读取。
4) 所以,也许F1的确做到了传统数据库的功能,但它是基于完全不同的数据模型,这非常容易被误会,以为Google创造了和我们所理解的“数据库”一样的东西同时还具有自动扩展以及分布式冗余。世界不是那么美好的,Oracle的人也不是笨蛋,如果能做到,他们难道不想做或能力不够么。工程师作为搞技术的而不是搞市场或销售的人,要实事求是,Google首先有问题,乱用术语,动不动就Database或是SQL,真觉得是在博眼球,从文章里也可以看出来,F1和Spanner的两篇,提到对方的时候都说的不清不楚,好像都是自己更重要,作者署名里也完全没有重叠,完全是两个团队。他们这样做无可厚非,可我们外面的技术人员跟着起哄就没必要了。
最后还要说明一点,虽然Dremel也是基于PB数据格式的类SQL,但它和F1绝对是两码事,因为Dremel把PB的数据“列化”了,不光是列化后方便类SQL处理,甚至实际物理存储也列化了;而F1并没有打散PB的内容,也没有什么repetition level或definition level,它就是把PB数据放到key-value store的value里,然后在key上做“树状化”,也就是directory。这两个是对分布式数据处理问题的的两种实现。
再回到实际一点的问题,上面那些都是Google的东西,不是大家的,那么开源界能做什么?
如果不是跨数据中心冗余,Paxos状态机组和TrueTime真没必要。如果暂时抛开这个需求,只说在本地的多行操作一致性,目前HBase的做法和Spanner其实已经很像,都是通过对相同key前缀的数据聚合来实现(HBASE-5368),跨表操作的一致性其实原理上不难,也只能这么做,就像Spanner里的每个tablet组之上的transaction manager,HBase本来就用了ZooKeeper,估计也是因为需求不紧迫,也没有人去评估这样做的性能影响。
至于类SQL,关键还是使用HBase的人,如果我们现在就把PB的数据存进HBase会怎么样?能通过coprocessor设计出类似SQL的接口吗?性能会不会很差?这个话题太大了,要好好琢磨琢磨,Google目前的文章里还没有讲到他们是如何实现这一段,也没讲他们实现到什么程度,接下来看开源界会不会有类似的讨论。
好像其他也就没啥可以借鉴的了。。。
再过十几个小时就要出行,会有十来天没电脑,现在不写出来会憋的很惨,可本人传统数据库的功底很浅,所以,如有缪误,诚心求指正。
amazing article。能看到这个程度起码好多年关注hadoop系列了,博主留个其他链接欣赏博主其他文章,因为这个网站好像少点了。
此外,问下:我看directory的概念好像是多个表之间的关系,有父子关系的表。那如何确定这个父子关系呢?
将tablet由好几个directory组成。和hbase相比是不是将tablet这个单位更细化了?我没看到其他作用
谢谢指点!
感谢你的肯定。这个站架起来没几天,也没在外面贴过链接,你是怎么知道的啊?我没写过太多东西,我的新浪微博是@少年振南
directory是table的shard,table是有父子关系的,做shard的依据就是其中“父”的值,其关系的确定应该就是在k/v的key里,这是在定义table的时候通过interleave in parent关键字指定的,譬如论文里的例子:Album(2,1),其实就表明了这行数据的“父”是2,所以它必然和User(2)在同一个directory。而另外可能会有个directory专门存放User(3), Album(3,x),等等,这样就通过directory实现了相同User的数据集中在一起
和Hbase相比,它的确是把tablet细化了。
你下面的那个问题,是我的一个猜测,如果只有两层,可能看不出树状,设想一下三层Country->User->Album,就有个树的样子了,有的directory可能只细化到country,而有的country如果记录很多,就需要细化到user
还有个问题:“因为F1以前在MySQL上就是按CustomerID做shard,所以到了Spanner里才会有树状的directory,”
一个customerID做shard,如何看出了树状结构?
4xo8u5
4cprxl
xd4p96
tmgks5
5h9css
5gohyr
ltv7dd
xmv7vo
czns9d
08r1b6
g2bibz
du32u9
34ff3h
veqki1
qz7jn4
ppbpp1
iummkk
beu9f9
qdtmd9
jlcaln
jr16qh
vgxpkq
dg9zsa
b4pv0y
7x5d3t
fq5due