本来想动动手,然而Bigtable不开源-->_<--,那就把读论文的点写上来吧。网上这类文章挺多了,我也没有get到什么别人没get到的东西。纯记录的一篇无聊的文章。
Bigtable,谷歌内部使用的一个分布式存储系统,设计之初将其用于存储非常大规模的数据(petabytes级)。经过多年的实践,为谷歌的很多产品提供了灵活且高性能的数据存储解决方案。
Data Model
作为一个稀疏的(sparse)、持久化存储的分布式多维排序map,通过row keys、column keys、timestamp进行索引,数据值都是未经解析过的字节数组。
(row: string, column: string, time: int64) ——> string
rows: 每一个行被称为tablet,是数据分布和负载均衡的基本单位。Bigtable基于row key(行键)进行排序,拥有较好的位置相关性,利于数据查询。
column families: 几个column keys组成一个称为column familes的集合,是访问控制的最小单元,每一个column family通常存放着相同类型的数据。访问控制、内存和磁盘的使用统计等都通过column-family进行。
timestamp: 每个数据项可以包含不同版本的数据,通过timestamp进行索引。用户也可以自己生成timestamp,但需保持其唯一性,避免数据冲突。不同版本的数据按timestamp降序排序,最新版本排在最前面。(column-family有两个用户可设定的参数,可设定为自动废弃版本回收或指定保存版本的数量。)
注: tablet和SSTable的区别 —— tablet是分布式调度和存储的最小单元,是一个逻辑概念;SSTable是Bigtable中数据在磁盘的存储格式,tablet持久化到GFS文件即成为SSTable。
API
啊又不能用Bigtable,说这个有什么意思,学习下其他的就行啦。
Infrastructure
Bigtable构建于其他几个Google组件之上。
GFS: 存储日志和数据文件。
SSTable: 数据文件的存储格式。
Chubby: 分布式锁服务。
Implementation
系统实现的三个主要组件为:链接到用户程序的库,一个master服务器,很多tablet服务器。
master: 为tablets服务器分配tablets,均衡负载,监测tablets服务器的增减,回收GFS中的垃圾文件,处理数据模式的变化。
tablet servers: 每个tablet server管理一个tablets集,处理所存储tablets的读写请求,若tablets过大则进行分割。tablet servers可以根据工作负载进行动态地增减。
注: Bigtable客户端不依赖于master获取tablet位置信息,可以直接和tablet服务器进行读写通信。
tablet位置
使用一个类似于B+树的三层结构进行存储。
chubby file: 存有root tablet的位置信息。
root tablet: 存放一个特殊的元数据表, 表里的每个metadata tablet存放着的一个用户tablets数据集合的位置。
metadata tablets: 表里的每个metadata tablet存放一个用户tablets数据集合的位置信息。
tablet分配
master会记录当前活跃的tablets服务器,哪些tablets被分配到了哪些服务器,未分配的tablets。使用Chubby跟踪tablet服务器,master会监控一个server directory,tablet服务器启动时会在这个目录里创建属于自己的唯一文件。
compactions
minor compaction: memtable大小达到阈值后,就创建另一个新的memtable,旧的那个则被转换为SSTable写入GFS中。
merging compaction: 读取一些memtable和少数SSTables并写入到新的SSTables(避免当minor compaction一直进行时,造成新的SSTables数量过多)。
major compaction: 一个将所有SSTables写入到一个SSTables中的merging compaction,生成的SSTables中不含有删除的信息或已删除的数据。
Refinements
locality groups: 多个column family可以聚集成一个locality group,并对应一个SSTable, 根据相关性可以提高读取效率。
compression: 可以选择是否对SSTables进行压缩:根据用户指定的压缩形式将SSTable blcok在写入磁盘前进行压缩。有些客户端进行两段压缩,拥有很好的性能。
caching for read: tablet servers使用两级缓存以提高读取的性能。
- scan cache: 高级缓存,缓存通过SSTables接口向tablet serversh获取的K/Vs。有利于读取经常访问的数据。
- blcok cache: 低级缓存,缓存从GFS读取的SSTable blcoks。有利于读取最近所读数据的附近数据。
bloom filters: 允许读取特定的行/列数据,减少对一个locality group的所有SSTables的访问次数。
commit log: 每个tablet server的commit写入到一个log文件中,并将commits进行排序,比为每一个tablet保存一份commit log而拥有更好的性能。每个tablet server都持有两个log写线程分别写入各自对应的log文件,每次只有一个处于活跃,若正在写的线程效率很慢则切换至另一个线程。
tablet recovery: tablet从一台服务器上迁移到另一台时,源服务器先做一次minor compaction,当从源服务器上删掉数据时,再做一次minor compaction。
inmmutability: SSTables的不变性使得并发读取很高效,并且简化了删除数据的回收,还能更为快速地进行SSTables的分割。memtable是可变的,故通过copy-on-write来达到读写并行。