![分布式系统与一致性](https://wfqqreader-1252317822.image.myqcloud.com/cover/78/38507078/b_38507078.jpg)
4.1 BigTable的外部接口和架构
我们先来看BigTable对外提供的接口。
4.1.1 表
在逻辑上,BigTable的数据按表(table)来组织。在使用BigTable前,需要创建或者打开一个表。图4.1大致描述了BigTable中的一个表。
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_46_1.jpg?sign=1739315474-s9EfkvLMiP0lPAZgGqMhVteGeWHrBJtA-0-3930c09e3796211a6a39bf7c107a156a)
图4.1 BigTable中的表(此图参考BigTable论文[1])
4.1.2 数据
接下来,我们会逐一介绍图4.1中出现的表的构成元素。
● 一个表中的数据按行(row)组织,每一行用row key标识。row key是一个字符串。
● 在一行中,分成若干列(column),每个列都有自己的名字。
● 列被分成组,一组列叫作列族(column family)。
列族需要提前创建,即在调用写入接口前必须先创建列族。列不需要提前创建,也就是在调用写入接口时可以使用任意列名。
在同一个列族中,不同的行可以有不同的列,并且不会限制列的个数。列名也可以为空。我们来看下面的伪代码(与BigTable的实际接口语法有差异)例子。
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_47_1.jpg?sign=1739315474-UWgRbBxiV2krclLnh9e1ArK34TyoeK8i-0-c5554bf97e79bab630ece07394863e1b)
综合以上信息,BigTable的数据模型如表4.1所示,BigTable中的表逻辑上类似于这个样子。
表4.1 BigTable的数据模型
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_47_2.jpg?sign=1739315474-1XnV0ccR2vuEXgdtn9rjpXjvQk67EJ1K-0-750e30f8e67b12b861b120125fff29f4)
4.1.3 原子性
BigTable的接口支持一行内的原子操作,也就是允许一次操作多个列,并且保持原子性。
在下面的代码(参考BigTable论文[1],接近BigTable的真实语法)例子中,对同一行的两个列分别进行Set操作和Delete操作,这两个操作会保证原子性。
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_48_1.jpg?sign=1739315474-Gc0IKnpiGTewQ1cJg6iUOHFO4Ufd83M5-0-5c78ca2a83ac7d4bcc63dab8540f452d)
4.1.4 时间戳
每个单元格都包含多个版本的数据,这些版本通过时间戳(timestamp)标识。时间戳是一个64位的整型数字。这个时间戳可以是BigTable生成的,也可以是应用指定并传给BigTable的。如果是应用自己生成的,那么应用需要保证生成唯一的、不重复的时间戳。
有了时间戳之后,BigTable的数据模型如表4.2所示,BigTable中的表逻辑上类似于这个样子。
表4.2 BigTable的数据模型(有了时间戳之后)
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_48_2.jpg?sign=1739315474-B097P9bkJSHjp8Lhp9abhAKBz0PIXzMc-0-6d23d145e4e873dd66aece04a27b41fc)
4.1.5 BigTable的数据模型
上面我们看到了BigTable表的逻辑结构,在BigTable内部,数据模型是一个多维排序Map。这个Map结构把row key、column key(包括family)和时间戳这三个维度映射到一个值,并且按这三个维度排序:
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_49_1.jpg?sign=1739315474-urXhI2FQ51hHobf6dkYZk8WVhPmO4nAi-0-a7f9668c0321ed0f9b01c2456b3c0ce9)
BigTable的实际数据模型如表4.3所示。
表4.3 BigTable的实际数据模型
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_49_2.jpg?sign=1739315474-Co9VNoCZokRdwRQClUxQMb8Bie3st9c4-0-a344e898aaed29452620198aba3ee2e8)
可以看到,这个实际的数据模型就是很多key-value对按照key排序得到的。所以,虽然BigTable支持表、列甚至列族等复杂的逻辑数据模型,但它仍然被认为是一种key-value型的数据库。
通常这个Map很大,BigTable会按row key对它进行切分,每一份都叫作tablet。
继续拿表4.3举例,这个表可以被拆分成两个tablet,即tablet1和tablet2,分别如表4.4和表4.5所示。
表4.4 BigTable tablet1
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_49_3.jpg?sign=1739315474-I7U1G1MyITQBtSf0v7TNbut56iWleJPZ-0-fc0cec7395f3b36dcc8cc85fc9ba31a5)
表4.5 BigTable tablet2
![](https://epubservercos.yuewen.com/DD4A5F/20266984001431406/epubprivate/OEBPS/Images/41041_50_1.jpg?sign=1739315474-RmYMdKwNb7JEOrlGZXIEMu5Js0VA9EPK-0-0b085338b38254e1c5fe8165f6d921b6)
4.1.6 BigTable的架构
BigTable在架构上包含5个组件:GFS、chubby、client、master和tablet server,分别说明如下。
● BigTable会将数据以日志文件和数据文件的形式存储在GFS中(后面的4.2.3节会详细介绍)。
● BigTable会为每个tablet指定一个tablet server,tablet server负责处理所有对这个tablet的读操作和写操作,并把这些读操作和写操作转化成对GFS的读/写操作。一个tablet只会由一个tablet server负责,一个tablet server会负责多个tablet。
● 一个主(master)节点负责把一个tablet指派给一个tablet server,在BigTable集群中只会有一个master。
● 客户端(client)是嵌入在应用中的一个库(library),或者叫作SDK。客户端不但包含对tablet server操作的代码,还包含了GFS的客户端和chubby的客户端。
● chubby是Google公司内部的一个分布式锁服务,类似于第7章中讲解的ZooKeeper。chubby负责维护BigTable集群,它有两个职责:
■ 选举master。
■ 维护tablet server(即维护当前BigTable集群中有哪些tablet server,并且这些tablet server是否还活着)。
另外,chubby还保存了BigTable集群的基础信息,包括root tablet的location和root tablet在GFS中的存储位置(后面的4.2.1节会详细讲解)。