Bigtable是一个分布式的结构化数据存储系统,它被设计用来处理海量数据:通常是分布在数千台普通服务器上的PB级得数据。
1.数据模型
Bigtable是一个稀疏的,分布式的,持久化存储的多维度排序Map,Map的key是行关键字,列关键字以及时间戳组成,Map的value是一个未经解析的字节数组。
-
行(字符串) 同一个行关键字的读或者写都是原子的,Bigtable通过行关键字的字典顺序来组织数据。Bigtable的表会根据行键自动划分为片(tablet),片是负载均衡的单元。最初表都只有一个片,但随着表不断增大,片会自动分裂,片的大小控制在100-200MB。行是表的第一级索引.
-
列族(字符串) 列关键字组成的集合叫做列族,列族是访问控制的基本单元,存放在同一列族下的数据通常都属于同一类型,列族应该不易太多,并且不常改变。列是第二级索引,每行拥有的列是不受限制的,可以随时增加减少。
-
时间戳(64位整数) 时间戳是第三级索引。Bigtable允许保存数据的多个版本,在Bigtable中,表的每一个数据项都可以包含同一份数据的不同版本,不同版本的数据通过时间戳来索引。数据的不同版本按照时间戳降序存储,因此先读到的是最新版本的数据
table{
// ...
"aaaaa" : { //一行
"A:foo" : { //一列
15 : "y", //一个版本
4 : "m"
},
"A:bar" : { //一列
15 : "d",
},
"B:" : { //一列
6 : "w"
3 : "o"
1 : "w"
}
},
// ...
}
查询时,如果只给出行列,那么返回的是最新版本的数据;如果给出了行列时间戳,那么返回的是时间小于或等于时间戳的数据。
- 持久化,Bigtable的数据最终会以文件的形式放到GFS去。
- 分布式,Bigtable建立在GFS之上本身就意味着分布式
- 稀疏 ,一个表里不同的行,列可能完完全全不一样。
2. Bigtable集群
Bigtable集群包括三个主要部分:一个供客户端使用的库,一个主服务器(master server),许多片服务器(tablet server)。
-
每个片服务器负责一定量的片,处理对其片的读写请求,以及片的分裂或合并。片服务器可以根据负载随时添加和删除。这里片服务器并不真实存储数据,而相当于一个连接Bigtable和GFS的代理,客户端的一些数据操作都通过片服务器代理间接访问GFS。
-
主服务器负责将片分配给片服务器,监控片服务器的添加和删除,平衡片服务器的负载,处理表和列族的创建等。主服务器不存储任何片,不提供任何数据服务,也不提供片的定位信息。
-
客户端需要读写数据时,直接与片服务器联系。因为客户端并不需要从主服务器获取片的位置信息,所以大多数客户端从来不需要访问主服务器,主服务器的负载一般很轻。
3. BigTable和GFS的关系
集群包括主服务器和片服务器,主服务器负责将片分配给片服务器,而具体的数据服务则全权由片服务器负责。片服务器不是真的存储了数据(除了内存中memtable的数据),数据的真实位置只有GFS才知道,主服务器将片分配给片服务器的意思是,片服务器获取了片的所有SSTable(片在GFS里的物理形态)文件名,片服务器通过一些索引机制可以知道所需要的数据在哪个SSTabl文件,然后从GFS中读取SSTable文件的数据,这个SSTable文件可能分布在好几台chunkserver上。