Bigtable: A Distributed Storage System for Structured Data

Bigtable: A Distributed Storage System for Structured Data

     Bigtable是一种分布式存储系统,用于管理结构化数据,旨在扩展到非常大的规模:跨越数千台商品服务器的pb级数据。谷歌的许多项目都在Bigtable中存储数据,包括web索引、谷歌Earth和谷歌Finance。这些应用程序对Bigtable提出了非常不同的要求,无论是在数据大小(从url到web页面到卫星图像)和延迟需求(从后端批量处理到实时数据服务)方面。尽管有这些不同的需求,但Bigtable成功地为所有这些谷歌产品提供了灵活、高性能的解决方案。在本文中,我们描述了Bigtable提供的简单数据模型,它为客户机提供了对数据布局和格式的动态控制,并描述了Bigtable的设计和实现

1. INTRODUCTION

     从2003年末开始,我们设计、实现并部署了一个分布式存储系统,用于在谷歌上管理结构化数据,称为Bigtable。Bigtable的设计可以可靠地扩展到pb级的数据和数千台机器。Bigtable已经实现了几个目标:广泛的适用性、可伸缩性、高性能和高可用性。Bigtable被超过60个谷歌产品和项目使用,包括谷歌Analytics、谷歌Finance、Orkut、个性化搜索、Writely和谷歌Earth。这些产品使用Bigtable处理各种苛刻的工作负载,从面向吞吐量的批处理作业到对最终用户的数据服务的延迟敏感。这些产品使用的Bigtable集群的配置范围很广,从少量到数千台服务器,存储的数据最多可达几百兆兆字节。

     在许多方面,Bigtable类似于数据库:它与数据库共享许多实现策略并行数据库[DeWitt和Gray 1992]和主内存数据库[DeWitt等人,1984]已经实现了可伸缩性和高性能,但Bigtable提供了不同于这些系统的接口。Bigtable不支持完整的关系数据模型;相反,它为客户端提供了一个简单的数据模型,该模型支持对数据布局和格式的动态控制,并允许客户端推断底层存储中表示的数据的位置属性数据使用可以是任意字符串的行和列名建立索引。Bigtable还将数据视为未解释的字符串,尽管客户端经常将各种形式的结构化和半结构化数据序列化到这些字符串中。客户端可以通过在模式中谨慎选择来控制数据的位置。最后,Bigtable模式参数让客户端动态控制是在内存外还是在磁盘上提供数据。

第2节更详细地描述了数据模型,第3节提供了客户机API的概述。第4节简要介绍了Bigtable所依赖的底层谷歌基础结构。第5节描述了Bigtable实现的基本原理,第6节描述了我们为提高Bigtable性能所做的一些改进。第7节提供了对bigtable性能的测量。我们在第8节中描述了几个如何在谷歌中使用Bigtable的例子,并在第9节中讨论了我们在设计和支持Bigtable时学到的一些经验教训。最后,第10节描述了相关的工作,第11节给出了我们的结论。

2. DATA MODEL

Bigtable集群是一组运行Bigtable软件的进程。每个集群服务于一组表Bigtable中的表是一个稀疏、分布式、持久的多维排序映射。数据被组织成三个维度:行、列和时间戳

               (row:string, column:string, time:int64) → string

我们将特定行键、列键和时间戳所引用的存储作为单元格。行组合在一起形成负载单位平衡和列组合在一起形成访问控制和资源核算单元

    在研究了类似bigtable的系统的各种潜在用途之后,我们确定了这个数据模型。考虑一个具体的例子,它推动了我们的许多设计决策:一个可以被许多不同项目使用的大量网页和相关信息的副本。我们称这个特殊的表为Webtable。在Webtable中,我们将使用url作为行键,web页面的各个方面作为列名,并在获取时将web页面的内容存储在时间戳下的content:列中,如图1所示。

Rows.  Bigtable按行键按字典顺序维护数据表中的行键是任意字符串(目前的大小为64KB,尽管对于我们的大多数用户来说10-100字节是一个典型的大小)。每读或写数据下一行键是可序列化的(无论许多不同的列中读取或写入行),一个设计决策,使客户更容易年代推断系统行为的并发更新相同的行。换句话说,行是Bigtable中事务一致性的单位,目前Bigtable不支持跨行事务

具有连续键的行被分组成片区,这些片区形成了分配和负载平衡的单元。因此,对短行范围的读取是高效的,通常只需要与少量机器进行通信。客户端可以通过选择行键来利用这个属性,以便为数据访问获得良好的局部性。例如,在Webtable中,通过反转url的主机名组件,相同域的页面被组合成连续的行。我们将在关键的com.google.maps/index.html下存储maps.google.com/index.html的数据。将来自相同域的页面存储在彼此相邻的位置,可以提高主机和域分析的效率。

Columns 列键被分组成称为列族的集合,这些列族构成访问控制单元。存储在列族中的所有数据通常是相同类型的(我们将同一列族中的数据压缩在一起)。在存储数据之前,必须显式地创建列族。创建一个族之后,可以使用族中的任何列键:数据可以存储在这样的列键下,而不会影响表的模式。我们的目的是让表中不同的列族数量少(最多几百个),并且这些列族在操作过程中很少改变;这个限制使得广泛共享的元数据不会太大。相反,一个表的列数可能是无限制的。

更改表的模式,可以删除整个列族,在这种情况下,存储在该列族中任何列键下的数据都将被删除。但是,由于Bigtable不支持跨多行事务,因此如果存储在特定列键下的数据位于多行中,则无法自动删除该数据。

    列键使用以下语法命名:family:qualifier。列族名必须是可打印的,但限定符可以是任意字符串。Webtable列族的一个例子是language,它存储编写网页所用的语言。我们只在语言族中使用一个带有空限定符的列键来存储每个网页的语言ID。这个表的另一个有用的列族是锚;这个系列中的每个列键表示一个锚,如图1所示。限定符是指的网站的名称;单元格包含与链接相关联的文本。

访问控制以及磁盘和内存计算都是在列族级别执行的。在Webtable的案例中,这些控件允许我们管理不同类型的应用程序:一些添加新的基本数据、一些读取基本数据并创建派生列家庭,和一些只允许查看现有数据(甚至可能没有查看所有现有的家庭隐私原因)。

Timestamps 表中的不同单元格可以包含相同数据的多个版本,这些版本是根据时间戳建立索引的。大表时间戳是64位整数。它们可以由Bigtable隐式地分配,在这种情况下,它们表示以微秒为单位的实时时间,也可以由客户机应用程序显式地分配。需要避免冲突的应用程序必须自己生成唯一的时间戳。单元格的不同版本按时间戳顺序递减存储,因此可以先读取最近的版本。

为了减少版本化数据的管理工作量,我们支持两个每列族设置,告诉Bigtable自动对版本化数据进行垃圾收集。客户端可以指定只保留数据的最后n个版本,或者只保留足够新版本(例如,只保留最近7天写的值)。在我们的Webtable示例中,我们可以将存储在contents:列中的爬行页面的时间戳设置为实际爬行这些页面版本的时间。上面描述的垃圾收集机制使我们能够告诉Bigtable只保留每个页面的三个最新版本

3. API 

Bigtable API提供了创建和删除表和列族的函数。它还提供更改集群、表和列族元数据(如访问控制权限)的功能。客户端应用程序可以在Bigtable中写入或删除值,从单独的行中查找值,或者迭代表中数据的一个子集。图2显示了使用RowMutation抽象来执行一系列更新的c++代码。(为了保持示例简短,不相关的细节被省略了。)对Apply的调用对Webtable执行了一个原子变化:它向www.cnn.com添加一个锚,并删除一个不同的锚。图3显示了c++代码,它使用了Scanner抽象来迭代特定行中的所有锚点。客户端可以遍历多个列族,有几种机制可以限制扫描遍历的行、列和时间戳。例如,我们可以将上面的扫描限制为只生成列与正则表达式anchor:*.cnn.com匹配的锚,或者只生成时间戳与当前时间相差10天以内的锚。Bigtable支持允许用户以更复杂的方式操作数据的其他几个特性。首先,Bigtable支持单行事务

可用于对存储在单行键下的数据执行原子的读-修改-写序列。Bigtable目前不支持跨行键的通用事务,尽管它提供了一个客户端跨行键批处理写操作的接口。其次,Bigtable允许将单元格用作整数计数器。最后,Bigtable支持在服务器的地址空间中执行客户端提供的脚本。脚本是用一种叫做Sawzall的语言编写的[Pike等人,2005],这种语言是谷歌为处理数据而开发的。目前,我们基于sawzall的API不允许客户端脚本写回Bigtable,但它允许各种形式的数据转换、基于任意表达式的过滤以及通过各种操作符进行汇总。

Bigtable可以和mapreduce一起使用[Dean and Ghemawat 2004], mapreduce是谷歌开发的用于运行大规模并行计算的框架。我们编写了一组包装器,允许Bigtable既用作MapReduce作业的输入源,也用作输出目标。

4. BUILDING BLOCKS

Bigtable构建在谷歌基础设施的其他几个部分上。Bigtable集群通常运行在运行各种其他分布式应用程序的共享机器池中Bigtable依赖于谷歌集群管理系统来调度作业、管理共享机器上的资源、监视机器状态和处理机器故障。大表进程通常与来自其他应用程序的进程共享相同的机器。例如,如图4所示,一个Bigtable服务器可以与amapreduce worker (Dean and Ghemawat 2004)、应用服务器和谷歌文件系统(GFS)的服务器运行在同一台机器上(Ghemawat et al. 2003)

Bigtable使用GFS存储日志和数据文件。GFS是一个分布式文件系统,它维护每个文件的多个副本,以提高可靠性和可用性。

    内部使用谷歌SSTable不可变文件格式存储Bigtable数据文件。SSTable提供了从键到值的持久、有序的不可变映射,其中键和值都是任意字节字符串。提供了查找与指定键关联的值的操作,以及在指定键范围内迭代所有键/值对的操作。在内部,每个SSTable包含一个块序列(默认情况下每个块的大小是64KB,但是大小是可配置的)。块索引(存储在SSTable的末尾)用于定位块;当SSTable被打开时,索引被加载到内存中。查找可以通过单个磁盘查找来执行:我们首先通过在内存索引中执行二分查找来找到适当的块,然后从磁盘中读取适当的块。另外,SSTable可以完全映射到内存中,这允许我们在不接触磁盘的情况下执行查找和扫描。

   Bigtable依赖于一个名为Chubby的高可用和持久的分布式锁服务[Burrows 2006]。Chubby服务由5个活动的副本组成,其中一个被选为主服务并主动服务请求。当大多数副本都在运行时,该服务就处于活动状态,并且可以相互通信。Chubby使用Paxos算法[Chandra等人,2007;Lamport 1998],以保持其复制品在面对失败时的一致性。Chubby提供了一个由目录和小文件组成的命名空间。每个目录或文件都可以用作锁,对文件的读写是原子的。Chubby客户端库提供了对Chubby文件的一致缓存。每个Chubby客户端维护一个与Chubby服务的会话。如果客户端无法在租约到期时间内更新其会话租约,则该客户端会话将过期。当客户端会话到期时,它将丢失所有锁和打开句柄。Chubby客户端还可以在Chubby文件和目录上注册回调,以通知更改或会话过期

Bigtable将Chubby用于各种任务:确保在任何时候最多只有一个active master;存储Bigtable数据的引导位置(参见5.1节);发现药片服务器并完成药片服务器死亡(见第5.2节);和存储Bigtable模式(参见5.5节)。如果Chubby长时间不可用,Bigtable也会不可用。2006年8月,我们在跨越11个Chubby实例的14个Bigtable集群中测量了这种效应。由于Chubby不可用(由Chubby停机或网络问题引起),存储在Bigtable中的某些数据在Bigtable服务器上不可用的平均百分比为0.0047%。受Chubby不可用性影响最大的单个集群的百分比为0.0326%。

5. IMPLEMENTATION

Bigtable实现有三个主要组件:链接到每个客户机的库、一个主服务器和许多平板电脑服务器。平板电脑服务器可以从集群中动态添加(或删除),以适应工作负载的变化。

master负责分配tablet到tablet server,检测tablet server的添加和过期,平衡tablet server的负载,收集GFS中的垃圾文件。此外,它还处理模式更改,如表和列族的创建和删除。

每个平板电脑服务器管理一组平板电脑(通常我们在每个平板电脑服务器上有10到1000台平板电脑)。平板电脑服务器处理对已加载的平板电脑的读写请求,并对体积过大的平板电脑进行拆分。

   与许多单主机分布式存储系统一样[Ghemawat等人,2003;Hartman和Ousterhout 1993],客户端数据不通过主机移动:客户端直接与平板电脑服务器进行读写。因为大表客户端也不依赖主表获取平板电脑位置信息,所以大多数客户端从不与主表通信。因此,大师在练习中是轻负荷的。Bigtable集群存储许多表。每个表由一组片剂组成,每个片剂包含与行范围相关的所有数据。最初,每个表只包含一个平板电脑。随着表的增长,它会自动分割为多个平板电脑,每个平板电脑的默认大小约为1 GB。虽然我们的模型支持任意大小的数据,但当前的Bigtable实现并不很好地支持非常大的值。由于平板电脑不能在一行中间分割,我们建议用户一行包含的数据不要超过几百GB。在本节的其余部分中,我们将描述Bigtable实现的一些细节。

5.1 Tablet Location

我们使用类似于B+树的三层层次结构[Comer 1979]来存储平板电脑的位置信息(图5)。第一级是存储在Chubby中的文件,其中包含根平板电脑的位置。根片包含一个特殊元数据表的所有片的位置。每个元数据平板电脑包含一组用户平板电脑的位置。

METADATA表在行键下存储平板电脑的位置,行键是平板电脑的表标识符及其结束行的编码。每一行元数据在内存中存储大约1KB的数据。在128mb元数据片的适度限制下,我们的三层定位方案足以处理234个片(或128mb片中的261个字节)。

客户端库遍历位置层次结构来定位平板电脑,并缓存它找到的位置。如果客户机不知道平板电脑的位置,或者如果它发现缓存的位置信息不正确,那么它将递归地向上移动平板电脑位置层次结构。如果客户端缓存为空,定位算法需要三次网络往返,包括一次从Chubby读取数据。如果客户机的缓存是陈旧的,位置算法最多需要6次往返,因为陈旧的缓存条目只有在丢失时才会被发现(我们预计这种情况不会很频繁,因为元数据平板不应该移动得很频繁)。虽然平板电脑位置存储在内存中,所以不需要GFS访问,但我们在通常情况下通过让客户端库预取平板电脑位置来进一步降低这个成本:它在读取元数据表时读取多个平板电脑的元数据。

5.2 Tablet Assignment

每个平板电脑在同一时间最多分配给一个平板电脑服务器。master跟踪运行中的平板电脑服务器集,以及当前分配给平板电脑服务器的平板电脑,包括哪些平板电脑未分配。当一个平板电脑被取消分配,并且一个平板电脑服务器有足够的空间可用时,master通过向平板电脑服务器发送一个平板电脑加载请求来分配平板电脑。只有当下一次主服务器故障转移之前没有收到tablet加载请求时,分配才会失败:tablet服务器只接受来自当前主服务器的tablet加载请求。因此,一旦master发送了tablet load请求,它可以假定tablet被分配,直到tablet服务器死亡,或者tablet服务器通知master它已经卸载了tablet。

Bigtable使用Chubby来跟踪平板电脑服务器。当平板电脑服务器启动时,它会在特定的Chubby目录中创建并获得一个唯一命名的文件的排他锁。主机监视这个目录(servers目录)以发现平板电脑服务器。如果一个平板电脑服务器失去了它的独占锁,它将停止为它的平板电脑服务:例如,一个网络分区可能会导致服务器失去它的Chubby会话。(Chubby提供了一种有效的机制,允许平板电脑服务器在不引起网络流量的情况下检查自己是否仍然持有锁。)只要文件仍然存在,平板电脑服务器就会尝试重新获取文件上的排他锁。如果它的文件不再存在,那么平板电脑服务器将永远无法再提供服务,所以它会自杀。

master负责检测平板服务器何时不再为其平板提供服务,并尽快重新分配这些平板。为了检测tablet服务器何时不再为其tablet提供服务,master会定期向每个tablet服务器询问其锁的状态。如果一个平板电脑服务器报告它失去了它的锁,或者如果主服务器在它的最后几次尝试中无法到达服务器,主服务器将尝试获取服务器文件的排他锁。如果主服务器能够获得锁,那么Chubby就是活动的,而平板电脑服务器要么是死的,要么是无法连接到Chubby,所以主服务器通过删除服务器文件来确保平板电脑服务器永远不能再服务。一旦服务器的文件被删除,主服务器就可以将之前分配给该服务器的所有平板电脑移动到未分配的平板电脑集合中。为了确保Bigtable集群不受主服务器和Chubby之间网络问题的影响,如果主服务器的Chubby会话到期,主服务器就会自杀。主服务器故障不会改变平板电脑对平板电脑服务器的分配

5.3 Tablet Serving

平板电脑的持久状态存储在GFS中,如图6所示。更新被提交到存储重做记录的提交日志中。最近提交的文件存储在内存中一个被称为memtable的有序缓冲区中。memtable以行为基础维护更新,其中每一行都是写时复制,以保持行级一致性。旧的更新存储在sstable序列中(它们是不可变的)。

为了恢复平板电脑,平板电脑服务器从metadata表中读取元数据。这个元数据包含sstable列表,包括一个平板电脑和一组重做点,重做点是指向任何可能包含平板电脑数据的提交日志的指针。服务器读取sstable的索引到内存中,并通过应用重做点之后提交的所有更新来重建memtable。

当一个写操作到达平板服务器时,服务器检查它是否是格式良好的(也就是说,不是从一个有bug或过时的客户端发送的),发送方是否被授权执行修改。授权是通过从Chubby文件中读取被允许的写入者列表来执行的(这几乎总是在Chubby客户机缓存中很受欢迎)。一个有效的变更被写入提交日志。群提交用于提高小突变的吞吐量[DeWitt等人,1984;Gawlick和Kinkade, 1985]。在提交写操作之后,它的内容被插入到memtable中。

当读操作到达平板电脑服务器时,同样会检查其格式良好性和适当的授权。一个有效的读操作是在sstable和memtable序列的合并视图上执行的。sstable和memtable是按字典顺序排序的数据结构,可以有效地形成合并后的视图。

在拆分和合并平板电脑时,输入的读写操作可以继续进行。读取和写入也可以发生在写字板被压缩的时候;下一节将描述压缩。

5.4 Compactions

随着写操作的执行,memtable的大小增加。当memtable的大小达到一个阈值时,memtable被冻结,一个新的memtable被创建,冻结的memtable被转换为SSTable并写入GFS。这个小型压缩过程有两个目标:它可以减少平板电脑服务器的内存使用量,如果该服务器失效,它可以减少在恢复期间从提交日志中读取的数据量。

每一个小的压缩都会创建一个新的SSTable。如果此行为未检查,则读取操作可能需要合并任意数量的sstable的更新。相反,我们通过定期在后台执行合并压缩来限制这些文件的数量。合并压缩读取一些SSTable和memtable的内容,并写出一个新的SSTable。一旦压缩完成,输入的sstable和memtable就可以被丢弃。

将所有SSTable重写为一个SSTable的合并压缩称为主要压缩。由非主要压缩生成的sstable可以包含特殊的删除项,这些删除项可以抑制仍然存在的旧sstable中已删除的数据。另一方面,major compaction会生成一个不包含删除信息或删除数据的SSTable。Bigtable在其所有的平板电脑中循环使用,并定期将主要压缩应用于它们。这些主要的压缩允许Bigtable回收被删除数据所使用的资源,并允许它确保被删除的数据及时地从系统中消失,这对于存储敏感数据的服务非常重要。大表读性能得益于GFS中的局部优化。当写入文件时,GFS尝试将数据的一个副本放在写入器所在的同一台机器上。当读取GFS文件时,读取将从最近的可用副本提供。因此,在平板电脑服务器与GFS服务器共享机器的常见情况下,平板电脑服务器会将数据压缩到sstable中,这些sstable在本地磁盘上有一个副本,这样当后续的读请求被处理时,就可以快速访问这些sstable。

6. REFINEMENTS

上一节中描述的实现需要进行大量的细化,以实现用户所需的性能、可用性和可靠性。本节将更详细地描述实现的各个部分,以突出显示这些细化。

本地组。每个列族被分配到一个客户端定义的位置组,这是一个抽象,使客户端能够控制他们的数据存储布局。在压缩过程中,为每个片剂中的每个位置组生成一个单独的SSTable。将通常不会一起访问的列族隔离到单独的局部组中,可以实现更高效的读取。例如,Webtable中的页面元数据(如语言和校验和)可以在一个位置组中,而页面的内容可以在不同的组中;想要读取元数据的应用程序不需要读取所有页面内容

此外,可以根据本地组指定一些有用的调优参数。例如,可以将区域组声明为内存中。用于内存中位置组的sstable被延迟加载到平板电脑服务器的内存中。因为sstable是不可变的,所以不存在一致性问题。加载后,可以在不访问磁盘的情况下读取属于这些位置组的列族。这个特性对于频繁访问的小块数据非常有用;我们在内部使用它来处理METADATA表中的tablet-location列族。

压缩。客户端可以控制是否压缩本地组的sstable,如果压缩,则使用哪种压缩格式。用户指定的压缩格式应用于每个SSTable块(其大小可通过特定于位置组的调优参数来控制)。虽然单独压缩每个块会损失一些磁盘空间,但我们可以在不解压整个文件的情况下读取一小部分SSTable。许多Bigtable客户端使用双通道自定义压缩方案。第一遍使用了Bentley和McIlroy[1999]的方案,该方案压缩了跨越一个大窗口的长公共字符串。第二步使用快速压缩算法,在一个16kb的小窗口中查找重复的数据。这两个压缩通道都非常快,它们在现代机器上以100 - 200 MB/s的速度编码,并以400 - 1000 MB/s的速度解码。

缓存读取性能。为了提高读性能,平板电脑服务器使用了两种级别的缓存。扫描缓存是一种高级缓存,它将SSTable接口返回的键值对缓存到平板电脑服务器代码中。块缓存是一个较低级的缓存,用来缓存从GFS读取的SSTable块。扫描缓存对于那些倾向于重复读取相同数据的应用程序是最有用的。Block Cache对于那些倾向于读取与最近读取的数据相近的数据的应用程序非常有用(例如,顺序读取,或者随机读取一个热行中同一位置组中的不同列)。

布鲁姆过滤器。如5.3节所述,读取操作必须从组成平板电脑状态的所有sstable中读取。如果这些sstable不在内存中,我们可能会做很多磁盘访问。我们通过允许客户端指定Bloom过滤器[Bloom 1970]应该为特定位置组中的sstable创建,从而减少访问次数。Bloom过滤器允许我们询问SSTable是否包含指定行/列对的任何数据。对于某些应用程序,用于存储Bloom过滤器的少量平板服务器内存大大减少了读取操作所需的磁盘查找数量。我们使用bloom过滤器还可以避免对不存在的行或列的大多数查找进行磁盘访问。

提交日志的实现。如果我们将每个平板电脑的提交日志保存在一个单独的日志文件中,那么将有大量的文件同时被写入GFS中。根据每个GFS服务器上的底层文件系统实现,这些写操作可能需要大量的磁盘查找,以便写入不同的物理日志文件。此外,每个平板电脑有单独的日志文件也会降低组提交优化的效率,因为组往往更小。为了解决这些问题,我们将突变附加到每个平板服务器的单个提交日志中,这将在同一个物理日志文件中混合不同平板的突变[Gray 1978;Hagmann 1987]。

使用一个日志可以在正常操作期间提供显著的性能优势,但它会使恢复复杂化。当一个平板电脑服务器死亡时,它所服务的平板电脑将被转移到大量其他平板电脑服务器上;每个服务器通常装入少量的原始服务器的平板电脑。为了恢复平板电脑的状态,新的平板电脑服务器需要从原始平板电脑服务器写的提交日志中重新应用该平板电脑的突变。然而,这些平板电脑的突变混合在同一个物理日志文件中。一种方法是让每个新的平板电脑服务器读取这个完整的提交日志文件,并应用它需要恢复的平板电脑所需的条目。

为了避免重复的日志读取,我们首先按照键htable、行名、日志序列编号对提交日志条目进行排序。在排序后的输出中,特定片剂的所有突变都是连续的,因此可以通过一个磁盘查找和一个顺序读取来有效地读取。为了并行排序,我们将日志文件划分为64 mb的段,并在不同的平板电脑服务器上对每个段并行排序。这个排序过程由主服务器协调,当一个平板服务器表明它需要从一些提交日志文件中恢复突变时,就会启动这个排序过程。

向GFS写入提交日志有时会由于各种原因导致性能中断(例如,涉及写入的GFS服务器机器崩溃,或者负载过重,或者到达特定GFS服务器集的网络路径出现网络阻塞)。为了防止GFS延迟峰值的变化,每个平板电脑服务器实际上有两个日志写入线程,每个线程都写入自己的日志文件;在同一时间,这两个线程中只有一个处于活跃状态。如果对活动日志文件的写操作执行不佳,日志文件的写操作将切换到其他线程,提交日志队列中的变更将由新活动的日志写线程进行写操作。日志项包含序列号,以允许恢复过程删除此日志切换过程产生的重复条目。

7. PERFORMANCE EVALUATION

我们建立了一个带有N台平板服务器的Bigtable集群,以测量随着N的变化,Bigtable的性能和可伸缩性。平板电脑服务器配置为使用1gb内存,并写入由1786台机器组成的GFS单元,每台机器有两个400gb IDE硬盘驱动器。N台客户机机器生成了用于这些测试的Bigtable负载。(我们使用与平板电脑服务器相同数量的客户端,以确保客户端不会成为瓶颈。)每台机器都有两个双核2 GHz的Opteron芯片,有足够的物理内存来容纳所有正在运行的进程的工作集,还有一个千兆以太网链路。这些机器被安排在一个两级树形交换网络中,在根处有大约100200gb /s的聚合带宽可用。所有的机器都在相同的托管设施中,因此任何一对机器之间的往返时间都不到一毫秒。

平板电脑服务器、主服务器、测试客户机和GFS服务器都运行在同一组机器上。每台机器都运行一个GFS服务器。其中一些机器还运行平板服务器、客户端进程或来自其他作业的进程,这些作业在这些实验的同时使用池。R是测试中涉及的Bigtable行键的不同数量。选择R,以便每个基准测试在每个平板服务器上读取或写入大约1gb的数据。

顺序写基准测试使用名称为0到r1的行键。这个行键空间被划分为10N个大小相等的范围。这些范围由中央调度器分配给N个客户端,一旦客户端完成对分配给它的上一个范围的处理,中央调度器就会将下一个可用的范围分配给客户端。这种动态分配有助于减轻由客户机上运行的其他进程引起的性能变化的影响。我们在每个行键下写了一个字符串。每个字符串都是随机生成的,因此不可压缩。此外,不同行键下的字符串是不同的,因此不可能进行跨行压缩。randomwrite基准类似,除了行键在写入之前被哈希取模R,这样在整个基准测试期间,写入负载大致均匀地分布在整个行空间。

顺序读基准以与顺序写基准完全相同的方式生成行键,但是它不是在行键下写入数据,而是读取存储在行键下的字符串(该字符串是由之前对顺序写基准的调用所写入的)。同样,随机读基准测试也会影响随机写基准测试的操作。扫描基准测试类似于顺序读取基准测试,但是使用Bigtable API提供的支持扫描行范围内的所有值。使用扫描可以减少基准测试执行的RPC的数量,因为单个RPC可以从平板服务器获取大量的值序列。

9. LESSONS

在设计、实现、维护和支持Bigtable的过程中,我们获得了一些有用的经验和教训

我们得到的一个教训是,大型分布式系统容易受到许多类型故障的影响,而不仅仅是许多分布式协议中假定的标准网络分区和故障停止故障。例如,我们已经看到了由以下所有原因引起的问题:内存和网络损坏、大的时钟偏差、挂起的机器、扩展的和非对称的网络分区、我们正在使用的其他系统中的bug(例如Chubby)、GFS配额溢出,以及计划和非计划的硬件维护。随着我们在这些问题上获得了更多的经验,我们已经通过改变各种协议来解决这些问题。例如,我们在RPC机制中添加了校验和。我们还通过删除系统的一个部分对另一个部分的假设来处理一些问题。例如,我们不再假设一个给定的Chubby操作只能返回一个固定的错误集。

我们得到的另一个教训是,在清楚新功能将如何使用之前,推迟添加新功能是很重要的。例如,我们最初计划在API中支持通用事务。但是,因为我们没有立即使用它们,所以我们没有实现它们。现在,我们已经有许多实际的应用程序在Bigtable上运行,我们已经能够检查它们的实际需求,并发现大多数应用程序只需要单行事务。当人们请求分布式事务时,最重要的用途是维护二级索引,我们计划添加一个专门的机制来满足这一需求。新机制将不如分布式事务那么通用,但将更加高效(特别是对于跨越数百行或更多行的更新),并且还将更好地与我们的乐观跨数据中心复制方案进行交互。

我们学到的最重要的一课就是简单设计的价值。考虑到我们系统的大小(大约100,000行非测试代码),以及代码以意想不到的方式随着时间的推移而演进的事实,我们已经发现代码和设计的清晰性在代码维护和调试方面有巨大的帮助。其中一个例子就是我们的平板电脑服务器成员协议。我们的第一个协议很简单:主服务器定期向平板服务器发出租约,如果租约到期,平板服务器就会自杀。不幸的是,在存在网络问题时,该协议显著降低了可用性,并且对主恢复时间也很敏感。我们重新设计了几次协议,直到我们有了一个执行良好的协议。然而,最终的协议过于复杂,并且依赖于chubby特性的行为,而这些特性很少被其他应用程序使用。我们发现,我们花费了过多的时间调试晦涩的角落情况,不仅是在Bigtable代码中,也在Chubby代码中。最终,我们放弃了这个协议,转而使用一个更新更简单的协议,它完全依赖于广泛使用的Chubby特性。

11. CONCLUSIONS

我们已经描述了Bigtable,这是一个将结构化数据存储在谷歌的分布式系统。自2005年4月以来,Bigtable集群一直在生产环境中使用,在此之前,我们在设计和实现上花费了大约7个人年的时间。截至2006年8月,已有60多个项目在使用Bigtable。我们的用户喜欢Bigtable实现提供的性能和高可用性,而且他们可以在资源需求随时间变化时,通过简单地向系统添加更多的机器来扩展集群的容量。

考虑到Bigtable的不同寻常的界面,一个有趣的问题是,我们的用户适应使用它有多难。新用户有时不确定如何最好地使用Bigtable接口,特别是如果他们习惯使用支持通用事务的关系数据库。然而,许多谷歌产品成功使用Bigtable的事实表明,我们的设计在实践中工作得很好。

我们正在实现几个额外的Bigtable特性,比如支持二级索引,以及构建具有多个主副本的跨数据中心复制的Bigtable的基础设施。我们还开始将Bigtable作为服务部署到产品组中,这样各个组就不需要维护自己的集群了。随着我们的服务集群规模的扩大,我们将需要在Bigtable本身处理更多的资源共享问题[Banga等人,1999;Bavier等人,2004]。

最后,我们发现在谷歌上构建我们自己的存储解决方案有显著的优势。通过为Bigtable设计自己的数据模型,我们获得了很大的灵活性。此外,我们对Bigtable实现的控制,以及Bigtable所依赖的其他谷歌基础设施,意味着我们可以在出现瓶颈和效率低下时消除它们。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大数据技术领域有很多重要的文献,以下是其中一些著名的大数据技术文献: 1. "MapReduce: Simplified Data Processing on Large Clusters" by Jeffrey Dean and Sanjay Ghemawat - 这篇论文介绍了Google的MapReduce框架,它是大数据处理的基础之一。 2. "The Google File System" by Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung - 这篇论文描述了Google的分布式文件系统(GFS),它是大数据存储的关键技术之一。 3. "Bigtable: A Distributed Storage System for Structured Data" by Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C. Hsieh, Deborah A. Wallach, Mike Burrows, Tushar Chandra, Andrew Fikes, and Robert E. Gruber - 这篇论文介绍了Google的Bigtable,它是一种高性能、可扩展的分布式存储系统,被广泛应用于大数据领域。 4. "Hadoop: The Definitive Guide" by Tom White - 这本书是关于Apache Hadoop的权威指南,详细介绍了Hadoop的架构、组件和使用方法。 5. "Spark: Cluster Computing with Working Sets" by Matei Zaharia, Mosharaf Chowdhury, Michael J. Franklin, Scott Shenker, and Ion Stoica - 这篇论文介绍了Apache Spark,一个快速、通用的大数据处理引擎,具有内存计算和容错性能。 6. "Storm: Distributed and Fault-Tolerant Real-Time Computation" by Nathan Marz and James Warren - 这篇论文介绍了Apache Storm,一个用于实时数据处理的分布式计算系统,具有高可靠性和可扩展性。 7. "Kafka: A Distributed Streaming Platform" by Jay Kreps, Neha Narkhede, and Jun Rao - 这篇论文描述了Apache Kafka,一个高吞吐量、可持久化、分布式发布订阅消息系统,被广泛应用于大数据流处理。 这些文献涵盖了大数据技术的核心概念、架构和关键技术,对于理解和应用大数据技术非常有帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值