google bigtable论文原文_谷歌三驾马车-BigTable

论文题目:BigTable: A Distributed Storage System for Structured Data

中文翻译参考:

Google Bigtable (中文版)​dblab.xmu.edu.cn
5a8ba80482d54b4fe03112efaddad565.png

文章架构:

  • 第 2 部分详细描述了数据模型;
  • 第 3 部分大概介绍了用户 API;
  • 第 4 部分简要介绍了 BigTable 所依赖的 Google 底层基础设施;
  • 第 5 部分描述了 BigTable 的实施方法;
  • 第 6 部分描述了我们针对 BigTable 做的性能改进;
  • 第 7 部分提供了 BigTable 的性能衡量方法;
  • 第 8 部分给出了几个实例来介绍 Google 如何使用 BigTable;
  • 第 9 部分介绍了我们在设计和支持 BigTable 过程中得到的经验教训;
  • 第 10 部分介绍相关工作;
  • 第 11 部分给出结论。

以下筛选出重点,并进行简要的分析。

第2部分-DataModel

BigTable的具体实现方式:一个稀疏的、分布的、永久的多维排序图。

采用行键(row key)、列键(column key)和时间戳(timestamp)对图进行索引。

(row: string, column string, time:int64)→string 【键值对】

Rows:

一个表中的行键,可以为任意字符,长度64KB,依据字典顺序进行维护。

特别的,在一个表中行区间(Tablet)是动态划分的。行区间是负载均衡和数据分发的基本单位。所以较短行区间的读取比较高效。(例如在同一域名下的网页将会被安排到相同的行区间中,使最后的检索速度加快。)

Column Families:

多个列键组成“列家族”。一行数据一般具有多个维度的参数,但是设计数据标签的时候要求列尽可能少。

BigTable中列键采用下面的语法命名:family:qualifier。family可以理解为一个特定列组的名称,一般必须有字段。qualifier相当于是该列组下的具体分类标识符。

从文献中可以看出,如果某一列的qualifier没有命名,那么该单元可以存放多个相同数据类型的数据。如果qualifier有命名,那么应独自占用一列。显然不同的的qualifier的数据类型不同。

此外,数据的访问与控制都是基于列家族的内容的进行操作的。

Timestamps:

Timestamps作为时间戳,给每一个数据添加一个独一无二的时间标签,精确到毫秒。这一点对于相同数据的多个版本特别有用。

第3部分-API

API部分主要是介绍BigTable具有的增删改等等功能。

需要注意的是,BigTable的采用的原子更新操作。可以将多个相关联的动作合起来一起操作。为后期Hive等其他的开发提供借鉴意义。

第4部分-基于Google的基础设施

BigTable使用分布式Google文件系统(GFS)来存储日志文件和数据文件。

存储的文件格式为Google SSTable文件格式。一个SSTable提供一个持久的、排序的、不可变的、从键到值的映射。一个SSTable的大小是64KB(大小可配)。

块的索引在SSTable的结尾,用来快速定位块的位置。

当一个SSTable打开时,块索引就会先被读取进入内存。利用二分查找找到合适的块地址,最终才从磁盘读取相应的块。当然如果SSTable足够小可以读取进去内存,那么BigTable就会直接将该SSTable读取进去内存操作。

同时,BigTable还依赖Chubby(一个高可用、持久性的分布式锁服务)。Chubby使用Paxos算法来保持一致性。

第5部分-具体实施方法

BigTable包括三个主要的功能组件:1)库函数、2)一个主服务器、3)多个Tablet服务器。

其中:库函数的主要负责服务器与客户端的通信。主服务器负责Tablet服务器的负载均衡,维护GFS的垃圾回收机制,表、列的创建等。每个Tablet服务器一般存放10~1000个Tablet,每个Tablet默认尺寸大小为100~200MB。

这里显然采用的是主从模式,一般来说会对主服务器带来很大的负载。论文中特意强调,实际设计时客户端并不是直接从主服务器读取数据,而是直接从Tablet服务器上读取数据,所以主服务器的负载较小。个人的观点是可能在客户端中存放了各个Tablet索引的元数据,从而减轻了主服务器的负载压力。Hadoop的1.X也是使用主从模型。

1、Tablet定位方法

Tablet的位置通过维护元数据表实现,每个元数据表分别记录了对应的表的位置。元数据表存放在分布式锁服务Chubby中,保证了数据的一致性。上述操作采用三层结构实现。

由于客户端不会直接与主服务器进行交互,所以客户端函数库会缓存Tablet位置信息。客户端的Tablet位置信息保存在缓存中,速度快。同时,定期更新Tablet位置信息。

2、Tablet的分配

主服务器根据全局的负载情况分别Tablet到对应的Tablet服务器。BigTable使用Chubby来跟中Tablet服务器。主服务器见识对应的Chubby上的目录,来发现Tablet服务器。

显然主服务器把Tablet的位置信息转交到Chubby上,这样可以更专注的进行负载均衡,表、列创建等其他事情。

3、Tablet的持久化存储与恢复

Tablet的持久化存储在GFS中。为了恢复一个Tablet,

第6部分-提升性能

6.1、Locality groups

客户端把多个列家族一起分组到一个locality group中,而每一个locality group大多独占一个SSTable。为了实现更高效的读操作,不被一起访问的列家族分割到不同的locality group中,反之亦然。

特别地,对于一些小的、常被访问的数据量(SSTable中)可以设置在内存保存。

6.2、压缩

客户端可以决定是否对某个SSTable进行压缩,通过压缩可以节省空间。而且是针对每一个块进行单独压缩,这样的话在解压缩时,只需要对小部分数据进行解压。

压缩算法采用“两段自定义压缩模式”。第一遍采用Bentley and Mcllroy模式,在大窗口下对长的、公共的字符串进行压缩。第二遍采用一个快速的压缩算法,已16KB为数据量窗口寻找重复的数据。

特别地,由于相邻行中存储的时相关信息,所以两种方法的压缩速度和效率都很快。编码在100~200MB/S,解码在400~1000MB/S,空间压缩率10:1。

6.3、读缓存

设置二处缓存机制,Scan缓存与Block缓存。Scan缓存了SSTable中常用的键值对,Block缓存了从GFS当中读取的SSTable块。

6.4、Bloom过滤器

允许客服端为某个特定的locality group中的SSTable创建Bloom过滤器。通过查看对应的Bloom过滤器可以知道该SSTable是否含有指定的“行-列队”的特定数据。

6.5、日志

每个Tablet服务器具备一个独立的日志文件,其中包含的时多个不同的Tablet的更新内容。

特别地,为了避免日志的重复读写,以键(表、行名称、日志顺序号)的顺序队日志文件的条目进行排序【支持并行排序】。(好处:一次查询,便可顺序批量读取数据。)

此外,更为更快排序,采用并行排序。为了日志读写正常,采用双线程进行日志记录。

6.6、加速Tablet的恢复

当主服务器根据负载均衡的需要,把一个Tablet从一个Tablet服务器转移另一个Tablet时,源Tablet服务器会对该Tablet进行一个次压缩。在完成压缩过程之后,这个源Tablet服务器就停止提供针对这个Tablet的服务。

6.7、SSTable的不可变性

SSTable一旦写成功之后是不可变更的,Hdfs与其类似。注意,由于读取数据时系统可能需要对mentable数据结构进行读写操作,所以需要每个mentable行具有“copy-on-write”。

7、应用案例

8、性能

9、经验教训

  1. 大的分布式系统很容易发生多种错误,不仅是其他分布式系统遇到的网络分割和故障,而且还包括:内存与网络故障、时钟不对齐、机器挂起、依赖的其他系统组件问题、非计划之外的硬件维护。
  2. 不要盲目开发新的特性,需要根据实际需求进行开发。
  3. 需要一套合理的自我监控系统,包括监视进程。
  4. 遵循简单设计原则。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值