Bigtable 结构化数据的分布式存储系统

Bigtable 数据的存储格式

Bigtable is a sparse, distributed, persistent multidimensional sorted map.

Bigtable 是一个 稀疏的、分布式的、持久化存储的多维度排序映射表. 表中的数据通过一个行关键字(Row Key)、一个列关键字(Column Key)以及一个时间戳(Time Stamp)进行索引. 在Bigtable中一共有三级索引. 行关键字为第一级索引,列关键字为第二级索引,时间戳为第三级索引。

Bigtable的存储逻辑可以表示为:

(row:string, column:string, time:int64)→string

Rows

  • Bigtable 的行关键字可以是任意的字符串,但是大小不能够超过 64KB
  • 表中数据都是根据行关键字进行排序的,排序使用的是词典顺序
  • 表中的每一行都可以动态分区,每个分区叫做一个tablet
  • 同一地址域的网页会被存储在表中的连续位置
  • 倒排便于数据压缩,可以大幅提高压缩率

需要特别注意的是对于一个网站 www.cnn.com 存储在 Bigtable 中的格式是 com.cnn.www

这样倒排的好处是,对于同一域名下的内容,我们可以进行更加快速的索引.

Column Families

  • 列族(Column Family)是列关键字组成的集合,是访问控制(Access Control)的基本单元
  • 存放在同一列族下的所有数据通常都属于同一个类型
  • 列族在使用之前必须先创建,然后才能在列族中任何的列关键字下存放数据
  • 列族创建后,其中的任何一个列关键字下都可以存放数据
  • 一张表中的列族不能太多(最多几百个),并且列族在运行期间很少改变。但一张表可以有无限多个列。(体现稀疏sparse)
  • 族名必须有意义,限定词则可以任意选定, 比如 “contents”, “title” 等等.
  • 组织的数据结构清晰明了,含义也很清楚

我们从 Bigtable 中读取数据先找到哪一行 然后再去选择读取那个一个 column.

Timestamps

  • Bigtable时间戳的类型是64位整型,可以由Bigtable可以给时间戳赋值,也可以通过用户程序给时间戳赋值
  • 数据项中,不同版本的数据按照时间戳倒序排序,即最新的数据排在最前面。
  • Google的很多服务比如网页检索和用户的个性化设置等都需要保存不同时间的数据,这些不同的数据版本必须通过时间戳来区分。
  • 每一个列族配有两个设置参数,Bigtable通过这两个参数可以对废弃版本的数据自动进行垃圾收集

API

Bigtable提供了建立和删除表以及列族的API函数。Bigtable还提供了修改集群、表和列族的元数据的API,比如修改访问权限。

  • Bigtable支持单行上的事务处理,目前还不支持通用的跨行事务处理
  • Bigtable允许把数据项用做整数计数器
  • Bigtable允许用户在服务器的地址空间内执行脚本程序

Chubby.

一个高可用的、序列化的分布式锁服务组件,一个Chubby服务包括了5个活动的副本,其中的一个副本被选为Master,并且处理请求。

Chubby的作用:

  1. 选取并保证同一时间内只有一个主服务器( Master Server )
  2. 存储BigTable数据的自引导指令的位置
  3. 获取子表的位置信息:查找Tablet服务器,以及在Tablet服务器失效时进行善后。
  4. 保存 Bigtable的模式信息及访问控制列表。

Chubby完成主服务器对子服务器(Tablet服务器)对监控,步骤如下:

  1. 初始化从Chubby中获取一个独占锁,确保同一时间只有一个主服务器
  2. 扫描服务器目录,找出当前活跃的子服务器
  3. 与所有活跃的字服务器取得联系了解tablet的分配情况
  4. 通过扫描METADATA,找出未分配的tablet并分配到合适的子服务器

主服务器的作用

  1. 新子表分配 , 当一个新的子表产生时,主服务器通过一个加载命令将其分配给一个空间足够的子表服务器。同时,创建新表、表合并以及较大子表的分裂都会产生一个或多个新子表。
  2. 子表服务器状态监控 , 主服务器必须对子表服务器的状态进行监控,以便及时检测到服务器的加入或撤销
  3. 子服务器之间的负载均衡 , 分割由子服务器发起,完成之后子服务器需要向主服务发出一个通知。

总体而言:

Chubby 负责元数据的存储和选择主服务器.

主服务器复杂子服务器的负载均衡

子服务器负责子表的管理,一个子服务器可以有很多很多张子表,处理对其子表的读写请求,以及子表的分裂或合并。

子表地址组成

Bigtable系统的内部采用的是一种类似B+树的三层查询体系

首先是第一层,Chubby file。这一层是一个Chubby文件,它保存着root tablet的位置。这个Chubby文件属于Chubby服务的一部分,一旦Chubby不可用,就意味着丢失了root tablet的位置,整个Bigtable也就不可用了。

第二层是root tablet。root tablet其实是元数据表(METADATA table)的第一个分片,它保存着元数据表其它子表的位置。root tablet很特别,为了保证树的深度不变,root tablet从不分裂。

第三层是其它的元数据子表,它们和root tablet一起组成完整的元数据表。每个元数据片都包含了许多用户子表的位置信息。

可以看出整个定位系统其实只是两部分,一个Chubby文件,一个元数据表。注意元数据表虽然特殊,但也仍然服从前文的数据模型,每个子表也都是由专门的子服务器负责,这就是不需要主服务器提供位置信息的原因。客户端会缓存子表的位置信息,如果在缓存里找不到一个子表的位置信息,就需要查找这个三层结构了,包括访问一次Chubby服务,访问两次子服务器。

Compactions

随着写操作的执行,memtable的大小不断增加。(最近提交的那些存放在一个排序的缓存中,我们称这个缓存为 memtable;较早的更新存放在一系列SSTable中)当memtable的尺寸到达一个门限值的时候,这个memtable就会被冻结,然后创建一 个新的memtable;被冻结住memtable会被转换成SSTable,然后写入GFS(我们称这种Compaction行为为Minor Compaction)。

Minor Compaction过程有两个目的:

  • 压缩Tablet 服务器使用的内存
  • 在服务器灾难恢复过程中,减少必须从提交日志里读取的数据量

每一次Minor Compaction都会创建一个新的SSTable。如果Minor Compaction过程不停滞的持续进行下去,读操作可能需要合并来自多个SSTable的更新;否则,我们通过定期在后台执行Merging Compaction过程合并文件,限制这类文件的数量。

Merging Compaction过程读取一些SSTable和memtable的内容,合并成一个新的SSTable。只要Merging Compaction过程完成了,输入的这些SSTable和memtable就可以删除了。

Bigtable循环扫描它所有的Tablet,并且定期对它们执行 Major Compaction。Major Compaction机制允许Bigtable回收已经删除的数据占有的资源,并且确保BigTable能及时清除已经删除的数据(alex注:实际是回收资源。数据删除后,它占有的空间并不能马上重复利用;只有空间 回收后才能重复使用),这对存放敏感数据的服务是非常重要。

猜你喜欢

转载自blog.csdn.net/Maestro_T/article/details/123103137