BigTable是一个分布式存储系统,他可以支持PB级别的数据,包括几千个商业服务器。Google的许多项目都存储在BigTable上,包括WEB索引、Google Earth 和Google Finance。这些应用对BigTable提出了截然不同的需求,无论是从数据量(从URL到网页到卫星图像)而言,还是从延迟需求(从后端批量处理到实时数据服务)而言。尽管这些不同的需求,BigTable已经为所有的Google产品提供了一个灵活的、高性能的解决方案。本文中,我们描述了BigTable提供的简单数据模型,它允许客户端对数据部署和格式进行动态控制,我们描述了BigTable的设计和实施。
在过去的两年半时间里,我们已经设计、实施和部署了一个分布式存储系统BigTable,来管理Google当中的结构化数据。BigTable被设计成可以扩展到PB的数据和上千个机器。BigTable已经达到了几个目标:广泛应用性、可扩展性、高性能和高可用性。Google的六十多款产品和项目都存储在BigTable中,包括Google Analytics和Google Finance,Orkut,Personalized Search,Writely和Google Earth。这些产品使用BigTable来处理不同类型的工作负载,包括面向吞吐量的批处理作业以及对延迟敏感的终端用户数据服务。这些产品所使用的BigTable的簇,涵盖了多种配置,从几个到几千个服务器,并且存储了几百TB的数据。
在许多方面,BigTable都和数据库很相似,它具有和数据库相同的实施策略。并行数据库[14]和内存数据库[13]已经取得了可扩展性和高性能,但是BigTable提供了和这些系统不一样的接口。BigTable不能支持完整的关系型数据模型,相反,它为客户提供了一个简单数据模型,该数据模型可以支持针对数据部署和格式的动态控制,并且可以允许用户去推理底层存储所展现的数据的位置属性(比如具有相同前缀key的数据位置很接近,读取时候可进行一定的预取来进行优化)。BigTable使用行和列名称对数据进行索引,这些名称可以是任意字符串。BigTable把数据视为未经解释的字符串,客户可能经常把不同格式的结构化数据和非结构化数据都序列化成字符串。最后,BigTable模式参数允许用户动态地控制,是从磁盘获得数据还是从内存获得数据。
BigTable是一个稀疏的、分布式的、持久化存储的多维排序Map。Map的索引是行关键字、列关键字以及时间戳;Map中的每个value都是一个未经解析的byte数组。
假设我们想要拷贝一个可能被很多项目都使用的、很大的网页集合以及相关的信息,让我们把这个特定的表称为Webtable。在Webtable当中,我们使用URL作为行键,网页的不同方面作为列键,并把网页的内容存储在contents:column中,如图1所示
表中的行关键字可以是任意的字符串(目前支持最大64KB的字符串,但是对大多数用户,10-100个字节就足够了)。对同一个行关键字的读或者写操作都是原子的(不管读或者写这一行里多少个不同列),这个设计决策能够使用户很容易的理解程序在对同一个行进行并发更新操作时的行为。
Bigtable通过行关键字的字典顺序来组织数据。表中的每个行都可以动态分区,每个分区叫做一个”Tablet”,Tablet是数据分布和负载均衡调整的最小单位。这样做的结果是,当操作只读取行中很少几列的数据时效率很高,通常只需要很少几次机器间的通信即可完成。
用户可以通过选择合适的行关键字,在数据访问时有效利用数据的位置相关性,从而更好的利用这个特性。举例来说,在Webtable里,通过反转URL中主机名的方式,可以把同一个域名下的网页聚集起来组织成连续的行。具体来说,我们可以把maps.google.com/index.html的数据存放在关键字com.google.maps/index.html下。把相同的域中的网页存储在连续的区域可以让基于主机和域名的分析更加有效。 列关键字组成的集合叫做“列族“,列族是访问控制的基本单位。存放在同一列族下的所有数据通常都属于同一个类型(我们可以把同一个列族下的数据压缩在一起)。列族在使用之前必须先创建,然后才能在列族中任何的列关键字下存放数据;列族创建后,其中的任何一个列关键字下都可以存放数据。根据我们的设计意图,一张表中的列族不能太多(最多几百个),并且列族在运行期间很少改变。与之相对应的,一张表可以有无限多个列。