bigtable原理
bigtable原理
数据模型
A Bigtable is a sparse, distributed, persistent multi-dimensional sorted map. The map is indexed by a row key, column key, and a timestamp; each value in the map is an uninterpreted arrays of bytes.
Bigtable是稀疏的、分布式的、持久化的、多维度的、顺序的map,我们可以将Bigtable的数据模型抽象为一系列的键值对,满足的映射关系为:key(row:string, column:string, time:int64) -> value(string)。
Bigtable的Key有三维,分别是行键(row key)、列键(column key)和时间戳(timestamp),行键和列键都是字节串,时间戳是64位整型。
为了方便管理,列又被分为多个列族(column family,是访问控制的单元),列键按照family:qualifier格式命名的。
行键、列键和时间戳分别作为table的一级、二级、三级索引,即一个table包含若干个row key,每个row key包含若干个列族,每个列族又包含若干个列,对于具有相同行键和列键的数据(cell),Bigtable会存储这个数据的多个版本,这些版本通过时间戳来区分。
如下图:

该表包含两个行键u1和u2,每个行键又含两个列族User和Social,User列族包含的列键有name、email、phone;Social列族包含的列键有friend、classmate;
- (u1, name, v1)->Ricky 表示一个键值对;
- (u1, email, v1)->ricky@gmail.com 和 (u1, email, v2)->ricky@yahoo.com 是两个不同的键值对。
综上,传统的map由一系列键值对组成,在Bigtable中,对应的键是由多个数据复合而成的,即row key,column key和timestamp。
最后:
Bigtable按照行键的字典序存储数据,因为系统庞大且为分布式,所以排序这个特性会带来很大的好处,行的空间邻近性可以确保当我们在扫描表时,我们感兴趣的记录会大概率的汇聚到一起。
Tablet是Bigtable分配和负载均衡的单元,Bigtable的表根据行键自动划分为片。最初表都只有一个tablet,但随着表的不断增大,原始的tablet自动分割为多个tablet,片的大小控制在100-200MB。
支撑技术
Bigtable的实现依托于Google的几个基础组件:
- Google File System(GFS),一个分布式文件系统,用于存储日志和文件;
- Google Sorted Strings Table(SSTable),一个不可修改的有序键值映射表,提供查询、遍历的功能;
- Chubby,一个高可靠用于分布式的锁服务,其目的是解决分布式一致性的问题,通过Paxos算法实现。Chubby用于片定位,片服务器的状态监控,访问控制列表存储等任务。注:Chubby并不是开源的,但 Yahoo!借鉴Chubby的设计思想开发了Zookeeper,并将其开源。
bigtable集群
Bigtable集群包括三个主要部分:
- 供客户端使用的库,客户端需要读写数据时,直接与片服务器联系。因为客户端并不需要从主服务器获取片的位置信息,所以大多数客户端从来不需要访问主服务器,主服务器的负载一般很轻。
- 主服务器(master server),主服务器负责将片分配给片服务器,监控片服务器的添加和删除,平衡片服务器的负载,处理表和列族的创建等。注意,主服务器不存储任何片,不提供任何数据服务,也不提供片的定位信息。
- 片服务器(tablet server),每个片服务器负责一定量的片,处理对片的读写请求,以及片的分裂或合并。每个片实际由若干SSTable文件和memtable组成,而且这些SSTable和memtable都是已排序的。片服务器可以根据负载随时添加和删除。这里片服务器并不真实存储数据,而相当于一个连接Bigtable和GFS的代理,客户端的一些数据操作都通过片服务器代理间接访问GFS。

注意,主服务器负责将片分配给片服务器,而具体的数据服务则全权由片服务器负责。但是不要误以为片服务器真的存储了数据(除了内存中memtable的数据),数据的真实位置只有GFS才知道,主服务器将片分配给片服务器的意思应该是,片服务器获取了片的所有SSTable文件名,片服务器通过一些索引机制可以知道所需要的数据在哪个SSTable文件,然后从GFS中读取SSTable文件的数据,这个SSTable文件可能分布在好几台chunkserver上。
当片服务器启动时,它会在Chubby的某个特定目录下创建并获取一个锁文件(互斥锁),这个锁文件的名称是唯一表示该tablet server的。master server通过监控这个目录获取当前存活着的tablet server的信息。
- 如果tablet server失去了锁(比如网络问题),那么tablet server也就不再为对应的tablet服务了。
- 如果锁文件存在,那么tablet server会主动获取锁。
- 如果锁文件不存在,那么tablet server就永远不会再服务对应的tablet了,所以tablet server就会kill自己。
- 当tablet server要终止时,它会自己释放占有的锁,master server就会把该tablet server上的tablet分配给其它的tablet server。
那么maser server是如何获知tablet server不再服务了呢?master server会定期轮询每个tablet server的锁状态。如果tablet server报告自己失去了已经失去了锁,或者master server不能获取tablet server的状态,那么master server就会尝试去获取tablet server对应的锁文件。如果master server获取到了锁文件,并且Chubby是处于正常工作的状态的,此时master server就确认tablet server已经无法再提供服务了,master server删除相应的锁文件并把tablet server对应的tablet分配给新的tablet server。
如果master server与Chubby之间出现了网络问题,那么master server也会kill自己。但是这并不会影响tablet与tablet server之间的分配关系。
master server的启动需要经历一下几个阶段。
- master server需要从Chubby获取锁,这样可以确保在同一时刻只有一个master server在工作。
- master server扫描Chubby下特定的目录(即tablet server创建锁文件的目录),获取存活着的tablet server的信息。
- master server与存活着的tablet server通信,获取已被分配到tablet server的tablet信息。
- master server扫描METADATA tablet,获取所有的tablet信息,然后把未分配的tablet分配给tablet server。
片的定位
前面提到主服务器不提供片的位置信息,那么客户端是如何访问片的呢?Bigtable使用一个类似B+树的数据结构存储片的位置信息。

定位系统:
- Chubby file,保存着root tablet的位置。这个Chubby文件属于Chubby服务的一部分,一旦Chubby不可用,就意味着丢失了root tablet的位置,整个Bigtable也就不可用了。
- root tablet,root tablet其实是元数据表(METADATA table)的第一个分片,它保存着元数据表其它片的位置。root tablet很特别,为了保证树的深度不变,root tablet从不分裂。
- 其它的元数据片,它们和root tablet一起组成完整的元数据表。每个元数据片都包含了许多用户片的位置信息。
可以看出整个定位系统其实只是两部分,一个Chubby文件,一个元数据表。每个分片也都是由专门的片服务器负责,这就是不需要主服务器提供位置信息的原因。客户端会缓存片的位置信息,如果在缓存里找不到一个片的位置信息,就需要查找这个三层结构了,包括访问一次Chubby服务,访问两次片服务器。
元数据表
元数据表(METADATA table)是一张特殊的表,它被用于数据的定位以及一些元数据服务,不可谓不重要。
- 元数据表的行键=片所属表名的id+片最后一行行键而成,所以每个片在元数据表中占据一条记录(一行),而且行键既包含了其所属表的信息也包含了其所拥有的行的范围;
- 除了知道元数据表的地址部分是常驻内存以外,还可以发现元数据表有一个列族称为location,我们已经知道元数据表每一行代表一个片,那么为什么需要一个列族来存储地址呢?因为每个片都可能由多个SSTable文件组成,列族可以用来存储任意多个SSTable文件的位置。一个合理的假设就是每个SSTable文件的位置信息占据一列,列名为location:filename。当然不一定非得用列键存储完整文件名,更大的可能性是把SSTable文件名存在值里。获取了文件名就可以向GFS索要数据了。
- 元数据表不止存储位置信息,也就是说列族不止location,这些数据暂时不是咱们关心的。

客户端会缓存tablet的位置信息,客户端在获取tablet的位置信息时,会涉及到两种情况:
- 如果客户端没有缓存目标tablet的位置信息,那么就会沿着root tablet定位到最终的tablet,整个过程需要3次网络往返(round-trips)。
- 如果客户端缓存了目标tablet的位置信息,但是到了目标tablet后发现原来缓存的tablet位置信息过时了,那么会重新从root tablet开始定位tablet,整个过程需要6个network round-trips。
片的存储和读写
片的数据最终还是写到GFS里的,片在GFS里的物理形态就是若干个SSTable文件。下图展示了读写操作基本情况

当片服务器收到一个写请求,片服务器首先检查请求是否合法。如果合法,先将写请求提交到日志去,然后将数据写入内存中的memtable。memtable相当于SSTable的缓存,当memtable成长到一定规模会被冻结,Bigtable随之创建一个新的memtable,并且将冻结的memtable转换为SSTable格式写入GFS,这个操作称为minor compaction。
当片服务器收到一个读请求,同样要检查请求是否合法。如果合法,这个读操作会查看所有SSTable文件和memtable的合并视图,因为SSTable和memtable本身都是已排序的,所以合并相当快。
每一次minor compaction都会产生一个新的SSTable文件,SSTable文件太多读操作的效率就降低了,所以Bigtable定期执行merging compaction操作,将几个SSTable和memtable合并为一个新的SSTable。BigTable还有个更厉害的叫major compaction,它将所有SSTable合并为一个新的SSTable。
bigtable原理的更多相关文章
- BigTale
Google's BigTable 原理 (翻译) 题记:google 的成功除了一个个出色的创意外,还因为有 Jeff Dean 这样的软件架构天才. ...
- google的三篇论文
文章:MapReduce/GFS/BigTable三大技术资料 文章:Google File System(中文翻译) 文章:MapReduce:超大机群上的简单数据处理 文章:Google's Bi ...
- Bigtable 论文 阅读笔记 - 原理部分
不支持markdown,桑心.更好的阅读体验请看:Github/Bigtable.md Paper: Google Bigtable paper Notes author: Lhfcws Wu Tim ...
- NOSQL数据模型和CAP原理
NOSQL数据模型和CAP原理 http://blog.sina.com.cn/s/blog_7800d9210100t33v.html 我本来一直觉得NoSQL其实很容易理解的,我本身也已经对NoS ...
- CAP原理的证明
CAP概述 C: Consistency 一致性 A: Availability 可用性 P:Partition Tolerance分区容错性 CAP理论的核心是:一个分布式系统不可能同时很好的满足一 ...
- 【转】HBase原理和设计
简介 HBase —— Hadoop Database的简称,Google BigTable的另一种开源实现方式,从问世之初,就为了解决用大量廉价的机器高速存取海量数据.实现数据分布式存储提供可靠的方 ...
- (zz) 谷歌技术"三宝"之BigTable
006年的OSDI有两篇google的论文,分别是BigTable和Chubby.Chubby是一个分布式锁服务,基于Paxos算法:BigTable是一个用于管理结构化数据的分布式存储系统,构建在G ...
- Hbase原理
Hbase原理 概述 HBase是一个构建在HDFS上的分布式列存储系统:HBase是基于Google BigTable模型开发的,典型的key/value系统:HBase是Apache Hadoop ...
- MapReduce/Hbase进阶提升(原理剖析、实战演练)
什么是MapReduce? MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算.概念"Map(映射)"和"Reduce(归约)",和他们 ...
随机推荐
- C++ map<key , value> key值为指针
STL中map的key能否用char *呢?当然可以! 在程序中需要用到一个map,本来是这样写的, map<string, int> mapStr; 为了追求效率,把string改成了c ...
- webpack - HtmlWebpackPlugin理解
该插件的两个主要作用: 为html文件中引入的外部资源如script.link动态添加每次compile后的hash,防止引用缓存的外部文件问题 可以生成创建html入口文件,比如单页面可以生成一个h ...
- mui 列表项左右滑删除功能升级(仿微信左滑 点击删除后出现确认删除)
mui 列表项左右滑删除功能升级(仿微信左滑 点击删除后出现确认删除) 2018-06-19更新显示样式
- Js 判断浏览器类型整理
判断原理 JavaScript是前端开发的主要语言,我们可以通过 编写JavaScript程序来判断浏览器的类型及版本.JavaScript判断浏览器类型一般有两种办法,一种是根据各种浏览器独有的属性 ...
- 安装NVIDIA驱动时禁用自带nouveau驱动
安装英伟达驱动时,一般需要禁用自带nouveau驱动,按如下命令操作: sudo vim /etc/modprobe.d/blacklist-nouveau.conf 添加如下内容: blacklis ...
- LM && NTLM && ophcrack && RainBow table (转)
Windows密码的加密方式:Windows 主要使用以下两种(包含但不限于)算法对用户名和密码进行加密:分 别是LanManager(LM)和NTLM,LM只能存储小于等于14个字符的密码hash, ...
- How to make PostgreSQL functions atomic?
Question: How to make PostgreSQL functions atomic? Assume I have some PostgreSQL functions like the ...
- Android 里的数据储存
数据持久化 关于数据储存,这个话题已经被反复讨论过很多次了,我是不建议把网络存储这种方式纳入到数据储存的范围的,因为这个和Android没多少关系,因此就有如下的分类: 本地储存(也称之为数据持久化, ...
- Ubuntu18.04命令行连接WiFi
查看是否已经正确安装无线网卡 iwconfig .启动无线网卡, 如果网卡是wlan0 # 方式1 ifconfig wlan0 up # 或者方式2 ip link set wlan0 up .扫描 ...
- c++类大四个默认函数-构造函数 析构函数 拷贝构造函数 赋值构造函数
每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数).对于任意一个类A,如果不编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如: A ...