一篇有关bigtable的slide
http://pages.cs.wisc.edu/~remzi/Classes/739/Fall2017/Papers/bigtable-slides-05.pdfpages.cs.wisc.edu1、论文结构
在google的基础架构中, bigtable处于GFS之上,在应用层之下,为上层应用提供了一个扩展能力比较强的中间层存储系统(比GFS提供更好的基本能力,譬如更好的副本一致性管理,单行事务处理能力);bigtable将结构化数据扁平化存储,逻辑结构上是个k-v,它存储数据具有几个特点:Sparse、multi-version
这里sparse可以这么理解:google的某些业务场景是那种表中有很多column是没有数据的,用传统的DBMS来存储会造成比较大的空间浪费(因为mysql表中,无论某一列有没有数据都会占用位置);而bigtable逻辑上以k-v形式存储表数据,物理将表结构数据拆分成tablet,最后将数据下沉到gfs中;这里其实可以理解为bigtable将二维表结构序列化成一维的k-v存储,避免了sparse表的空间浪费,起到了压缩的作用
2、数据模型
row-key排序,row-key + qualifier + version -> value
存在列簇的概念:column family,由若干个column组成一个column family;
这些column存储的时候会放在一起,也就是说物理上相近;为了区分每个column,所以有qualifier;其实可以发现bigtable已经有列式存储的影子了(hbase就是借鉴于bigtable)
upd: bigtable本质上与hbase还是有区别,hbase将不同row的column family合并成一个个的tablet,bigtable并没有做到这种纯粹的列式粒度,仍然以row为单位来存储;
那么既然并没有做成列式存储,bigtable里面的column family有何意义呢?这里我这么理解(私货):
即使没有做到列式存储,对于sparse表的存储,压缩能力也是非常重要的;引入column family之后,按key排序可以将相近的column放在相邻的位置,考虑到column family里面的数据一般比较相近,压缩的空间也会比较大;
参考: https:// zhuanlan.zhihu.com/p/35 622907
3、数据存储模型
meta部分:
分了两层,增强了索引的能力,加了个根表(第一层元数据),根表到第二层meta的索引,第二层meta到用户表层的索引,也就是tablet的物理位置的索引(有点像内核里面的内存逻辑地址映射表),这部分论文没细提,我理解是放在chubby上的,是需要持久化的;
upd:这部分之前理解有误,正确的情况是:根表的元数据信息放在Chubby上,就像是OS的BIOS引导信息,根表也就是一级元数据表跟第二层元数据表,同普通用户表一样作为一个tablet存放在GFS上;
数据部分:
Bigtable(大表) -> tablet(小表) -> sstable(小小表)
第一层划分是大表到小表,将连续的rowkey对应的column family的数据放在一个tablet里面;
tablet是bigtable管理的最小单位;
而sstable是一个tablet又进行了进一步的划分,是LSM机制下的一种划分方法(minor compaction)
整理:(bigtable中有column family的概念,但是没有明确说物理存储tablet的时候是按照cf来划分的,如果还是按照整行row来保存kv,不能算是列式存储)
如果bigtable以column family为单位(至少他是个控制单位) 来物理隔离tablet, 可以理解为一个列式存储的nosql存储引擎,它将结构化数据以k-v的形式保存在文件系统中;而且保存的方式是以column方式为主,bigtable首先将相邻的数据构建成一个column family的概念,物理上将其放在相同的tablet中(tablet到sstable其实一样,因为sstable中除了level 0,其实也是有序的,不过这里不知道跟leveldb是不是一样);在column family内部,又根据rowkey + column family + qualifier作为Key排序,将column family内部相同的列放在一起;这样对于某一垂直列的range查询会非常迅速;不过这也牺牲了传统关系型数据库的优点,单个row上的数据几乎是没法快速合并的,所以做Join这样的操作非常不友好
4、整体架构
5、一致性方面
6、重要设计点
Bigtable支持单行事务
看起来是用MVCC实现的事务隔离
Bigtable如何实现单行事务 - 程序园www.voidcn.com为什么不支持多行事务?
首先单行与多行事务,其实也就是行级事务与表级事务的区别:
数据库事务系列-HBase行级事务模型 - 有态度的HBase/Spark/BigDatahbasefly.com![c9c5a1b9fb222918e057f8b73c2e9299.png](https://i-blog.csdnimg.cn/blog_migrate/adf470d3582835e7d61ada4952d037bf.png)
可以看出维护一个表级别的ACID其实开销是比较大的,某种意义上(无论是不是lock-free的)都是要互斥到整个表中关联的行,这些行可能在一个表中,有可能跨表,甚至跨节点;此时就要在多节点上做分布式事务;根据CAP原理,一致性跟高可用之间非常难搞,所以bigtable干脆就不支持跨行事务了; 不过这块是Jeff心中对bigtable一个不满意的地方,后来在Google 存储系统的演进路线可以看到,针对这块不足提出了很多方案: 首先基于BigTable上层构建了MegaStore,这里面提出了实例组的概念,事务已经开始支持跨行。这里面写入多行数据的事务保证是:通过先写入一条根实例数据对应bigtable的单行,这是能保证原子性的,之后再去Replay这条日志;如果要实现跨实例组的事务,需要额外的手段,譬如:分布式队列来实现最终一致性 或者 两阶段提交来保证
Part2: MegaStore
Megastore在bigtable上面又做了一层应用层,在Google内部广泛使用;google对它的定义是数据库,不过严格意义上,他不是严格的关系型数据库,而是介于NoSql与RDBMS之间的一个系统;既有很强的scale out能力,又提供了比较高级别的事务管理以及事务并发控制能力;可以看做是一个tradeoff。有一篇论文:
Megastore: Providing Scalable, Highly Available Storage for Interactive Services