Bigtable:结构化数据的分布式存储系统(三)

译自Bigtable_A Distributed Storage System for Structured Data

作者:Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C.Hsieh, Deborah A. Wallach Mike Burrows, Tushar Chandra, Andrew Fikes, Robert E.Gruber

6 功能优化

前面章节介绍了Bigtable的实现。要满足高性能、高可用和可靠性要求,还需要对Bigtable进行大量优化。本节详细介绍了Bigtable实现的其它部分。

位置组

客户端程序可以将多个列族组合成一个位置组。Tablet中的每个位置组都有一个单独的SSTable。把不会一起访问的列族分成不同的位置组可以提高读取操作的效率。例如,在Webtable表中,网页元数据(如语言和Checksum)可以放在一个位置组中,网页内容可以放在另一个位置组中。这样,当一个应用程序读取网页元数据的时候,就不需要读取所有的页面内容。

此外,可以以位置组为单位设定一些有用的调优参数。例如,可以把一个位置组的存储位置都设定为内存。Tablet服务器按照惰性加载的策略把存储位置设定为内存的位置组的SSTable装载进内存。加载完成后,访问属于该位置组的列族时就不需要读取硬盘了。这个特性对于需要频繁访问的小块数据特别有用:在Bigtable内部,我们利用这个特性提高元数据表中具有位置相关性的列族的访问速度。

压缩

客户端程序可以决定是否需要压缩一个位置组的SSTable;如果需要压缩,以什么格式来压缩。每个SSTable的块(块的大小由位置组的调优参数决定)都以用户指定的压缩格式来压缩。分块压缩确实会占用少量空间,但经过分块压缩,只读取SSTable的一小部分数据时就不必解压整个文件了。很多客户端程序使用的是定制化两步式压缩方式。第一步是利用Bentley-McIlroy算法,在较大的扫描窗口里对常见的长字符串进行压缩;第二步是快速压缩,即在16KB的小扫描窗口中寻找重复数据。两个步骤的压缩速度都很快,压缩速率达到100-200MB/s,解压速率达到400-1000MB/s。

在选择压缩算法时,我们主要关注的虽然是速度,但这种两步压缩方式在空间压缩方面表现也非常出色。例如,对于Webtable,我们使用这种压缩方式来存储网页内容。在测试中,我们在一个压缩的位置组中存储了大量网页。考虑到实验目的,我们仅存储了每个文档的一个版本的数据。该模式的空间压缩比达到了10:1,而传统的Gzip在压缩HTML页面时的压缩比为3:1或4:1。在两步式压缩模式下,从同一主机获取的页面都保存在相邻的位置。这样,Bentley-McIlroy算法便可以从来自同一个主机的页面里找到大量的重复内容。其它很多应用程序也通过选择合适的行名将相似的数据集中在一起,实现较好的压缩率。在Bigtable中存储同一份数据的多个版本时,压缩效率会更高。

通过缓存提高读操作的性能

为了提高读操作的性能,Tablet服务器采用了二级缓存策略。扫描缓存是一级缓存,主要缓存Tablet服务器通过SSTable接口获取的Key-Value对;数据块缓存是二级缓存,缓存的是从GFS读取的SSTable中的数据块。扫描缓存适用于需要经常重复读取相同数据的应用程序;数据块缓存适用于需要经常读取近期已读数据的周边数据的应用程序(如顺序读或在热点行的位置组中随机读取不同的列)。

布隆过滤器

如5.3节所述,一个读操作必须读取构成Tablet状态的所有SSTable的数据。如果SSTable不在内存中,则需要多次访问硬盘。允许客户端程序指定特定位置组的SSTable的Bloom过滤器后,能够有效减少硬盘访问次数。使用Bloom过滤器能够查询一个SSTable是否包含特定行和列的数据。对于某些应用程序,只要留出少量内存来存储Bloom过滤器,就能大幅减少读操作的磁盘访问次数。采用Bloom过滤器后,当应用程序访问不存在的行或列时,读操作就不需要再访问硬盘了。

提交日志的实现

如果把对每个Tablet操作的提交日志都单独存成一个文件,就会产生大量的文件,这些文件会同时写入GFS。考虑到GFS服务器底层文件系统的实现方案,把这些文件写入不同的磁盘日志文件时,会产生大量的磁盘Seek操作。另外,批量提交时操作次数一般较少,而把对每个Tablet操作的提交日志都单独存成一个文件则无法发挥批量提交的优势。为了避免这些问题,我们将每个Tablet服务器的提交日志文件数量设置为1,把修改操作的日志以追加的方式写入同一个日志文件,这样同一个日志文件中包含了对多个Tablet修改的记录。

单个日志显著提高了普通操作的性能,却增加了恢复工作的难度。Tablet服务器宕机时,其加载的Tablet会被移到其它各个Tablet服务器上:每个Tablet服务器一般只加载原来服务器上的几个Tablet。恢复Tablet的状态时,新的Tablet服务器要从原来的Tablet服务器写的日志中提取修改操作的信息,并重新执行。但这些修改操作的日志记录都是记录在同一个日志文件中的。一种解决办法是由新的Tablet服务器读取完整的提交日志文件,然后只重复执行需要恢复的Tablet的相关修改操作。根据这种方法,假如有100台Tablet服务器,每台都加载了失效的Tablet服务器上的一个Tablet,则该日志文件需要被读取100次(每个服务器读取一次)。

为避免多次读取日志文件,我们首先把日志按照关键字(table,row name,logsequencenumber)排序。排序之后,对同一个Tablet修改操作的日志记录就连续存放在一起了,这样只需要一次磁盘Seek操作。为了并行排序,我们先将日志分割成64MB的段,之后在不同的Tablet服务器同时对段进行排序。排序工作由Master服务器协调处理,并且在某个Tablet服务器需要从提交日志文件恢复Tablet时开始执行。向GFS写提交日志时可能会出现系统颠簸,原因不一而同(例如写操作时GFS服务器宕机,或GFS副本所在的连续三个服务器网络拥塞或者过载)。为了确保修改操作能够在GFS负载高峰时顺利进行,每个Tablet服务器实际上有两个日志写入线程,每个线程都写自己的日志文件。同一时间,只有一个线程处于工作状态。如果一个线程的写入效率很低,Tablet服务器会切换到另外一个线程,修改操作的日志记录便会写入到这个线程对应的日志文件中。每个日志记录都有一个序列号。在恢复时,Tablet服务器能够检测出并忽略掉由于线程切换而产生的重复记录。

加快Tablet恢复速度

当Master服务器把Tablet从一个Tablet服务器移到另一个Tablet服务器时,源Tablet服务器会对该Tablet进行Minor 压缩。这一操作减少了Tablet服务器的日志文件中没有归并的记录,从而缩短了恢复时间。压缩完成之后,该服务器就停止为该Tablet提供服务。在卸载Tablet之前,源Tablet服务器还会再次快速进行一次Minor压缩,消除在前一次压缩过程新产生的未归并记录。第二次Minor压缩完成以后,Tablet就可以被装载到新的Tablet服务器上了,且不需要从日志中进行恢复。

利用不变性

使用Bigtable时,除了SSTable缓存之外的其它部分产生的SSTable都是不变的,我们可以利用这一点对系统进行简化。例如,从SSTable读取数据时不需要对文件系统访问操作进行同步,从而高效地实现对行的并行操作。memtable是唯一一个能被读和写操作同时访问的可变数据结构。为了减少在读操作时的竞争,我们对memtable采用COW(Copy-on-write)机制,从而实现读写操作并行执行。

由于SSTable是不变的,永久删除数据的问题就转化为对废弃SSTable进行垃圾回收的问题了。每个Tablet的SSTable都在METADATA表中注册了。Master服务器采用“标记-删除”的垃圾回收方式删除SSTable集合中的废弃SSTable,METADATA表则保存了RootSSTable的集合。

最后,SSTable的不变性提高了Tablet的分割效率,不需要为每个分割出来的Tablet建立新的SSTable集合,而是共享原来Tablet的SSTable集合。

7 性能评估

为了测试Bigtable的性能和可扩展性,我们建立了一个由N台Tablet服务器组成的Bigtable集群,服务器数量可以随机调整。每台Tablet服务器配置了1GB的内存,数据写入到一个由1786台组成的GFS集群上,每台机器配有2个400GB的IDE硬盘。我们使用N台客户机生成的工作负载测试Bigtable。(客户机数量和Tablet服务器数量一致,确保客户机不会成为影响性能的瓶颈。)每台客户机配置了2GZ的双核Opteron处理器、足以容纳所有进程工作集的物理内存以及一张千兆位的以太网卡。这些机器都接入到一个两层的树状交换网络里,根节点上的带宽总计约为100-200Gbps。所有机器采用相同的设备,从而保证任何两台机器间的网络来回时间都小于1ms。

Tablet服务器、Master服务器、测试机以及GFS服务器都运行在同一组机器上。每台机器都运行一个GFS服务器。其它机器要么运行Tablet服务器、要么运行客户端程序、要么运行测试过程中使用这组机器的其它任务启动的进程。

R是测试过程中Bigtable包含的不同的列关键字的数量。合理设置R的值,保证每次基准测试对每台Tablet服务器读/写的数据量都在1GB左右。

在序列写的基准测试中,我们使用的列关键字的范围是0到R-1。这个范围又被划分为10N个大小相同的序列区间。核心调度程序把这些区间分配给N个客户端,这种动态分配机制有助于减少客户机上同时运行的其它进程对性能的影响。我们在每个列关键字下写入一个单独的字符串。每个字符串都是随机生成的,因此无法压缩。另外,不同列关键字下的字符串也是不同的,因此也就不存在跨行压缩的问题。随机写基准测试采用类似的方法,不过行关键字在写入前先做Hash。Hash采用按R取模的方式,保证在整个基准测试过程中,写入的工作负载均匀的分布在列存储空间内。

序列读的基准测试生成列关键字的方式与序列写相同。不同于序列写,序列读是读取列关键字下的字符串(字符串由之前序列写基准测试程序写入)。随机读的基准测试与随机写相似。

扫描基准测试和序列读类似,但使用的是Bigtable提供的API,扫描行范围内的所有值。 一次RPC调用能够从一个Tablet服务器取回大量值,因此扫描基准测试可以减少RPC调用的次数。

随机读(内存)基准测试和随机读类似,但随机读(内存)中,包含基准测试数据的位置组被设置为“in-memory”。因此,读操作直接从Tablet服务器的内存中读取数据,不需要从GFS读取数据。针对这个测试,我们把每台Tablet服务器存储的数据从1GB减少到100MB,这样就可以把数据全部加载到Tablet服务器的内存中了。

图6为读取/写入1000字节值时基准测试的性能 表格为每个Tablet服务器每秒钟的操作次数;曲线为所有Tablet服务器每秒钟的操作次数总和。

单个Tablet服务器的性能

首先来分析单个Tablet服务器的性能。随机读的性能比其它操作慢一个数量级甚至更多。每个随机读操作都要通过网络从GFS向Tablet服务器传输64KB的SSTable,而我们只使用其中大小是1000字节的值。Tablet服务器每秒大约执行1200次读操作,即每秒从GFS读取大约75MB的数据。这个传输带宽足以占满Tablet服务器的CPU,因为其中涉及了网络协议栈的消耗、SSTable解析以及Bigtable代码执行;也足以占满我们系统中网络的链接带宽。大多数采用这种访问模式的BigTable应用程序通常会将数据块大小控制在8KB。

内存中的随机读操作速度快很多,因为所有1000字节的读操作都是从Tablet服务器的本地内存中读取数据,不需要从GFS读取64KB的数据块。

随机写和序列写操作的性能比随机读要好,因为每个Tablet服务器直接把写入操作的内容以批量提交的方式追加到提及日志文件的尾部,通过数据流的形式写入到GFS,从而提高性能。随机写和序列写在性能上没有太大的差异,这两种写操作实际上都是把操作内容记录到同一个Tablet服务器的提交日志文件中。

序列读的性能优于随机读,因为每取出64KB的SSTable数据块后,这些数据便会缓存到数据块缓存中,后续的64次读操作直接从缓存读取数据。

扫描的性能更出色。因为客户端程序每次RPC调用都会返回大量值,调用的消耗基本可以抵消。

性能提升

系统中的Tablet服务器从1台增加到500台以后,系统的整体吞吐量增长了100多倍。

比如,Tablet服务器的数量增加到500台以后,内存中随机读操作的性能提升了300倍,原因在于该基准测试的瓶颈是单台Tablet服务器的CPU。

尽管如此,性能的提升依然不显著。从大多数基准测试中可以看出,当Tablet服务器数量从1台增加到50台时,每台服务器的吞吐量会出现明显下降,原因在于多台服务器间的负载不均衡,大多数情况是因为其它程序抢占了CPU和网络。负载均衡的算法会尽量避免这种不均衡,但这个算法也存在不足:一方面,减少Tablet的移动会导致重新负载均衡能力受限(如果Tablet被移动了,那么在短时间内(一般是1秒内)这个Tablet是不可用的);另一方面,基准测试程序产生的负载会有波动。

随机读基准测试的测试结果显示,随机读的性能提升受Tablet服务器数量的影响最小(服务器的数量却增加了500倍,但整体吞吐量只提升了100倍)。这是因为每个1000字节的读操作都会产生大小为64KB的数据块的网络传输消耗,占用网络中各种共享的1GB链路,导致服务器数量增加、吞吐量急剧下降的局面。

参考资料

  1. Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C.Hsieh, Deborah A. Wallach Mike Burrows, Tushar Chandra, Andrew Fikes and Robert E.Gruber. Bigtable_A Distributed Storage System for Structured Data

  2. Yan Wei. Google Bigtable中文版

转载于:https://juejin.im/post/5cef9f676fb9a07eb74b20dc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值