google Bigtable数据存储系统性能分析Word文档下载推荐.docx
- 文档编号:3696899
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:13
- 大小:73.60KB
google Bigtable数据存储系统性能分析Word文档下载推荐.docx
《google Bigtable数据存储系统性能分析Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《google Bigtable数据存储系统性能分析Word文档下载推荐.docx(13页珍藏版)》请在冰点文库上搜索。
例如,假设需要存储海量的网页及相关信息,这些用于很多不同的项目的数据,保存为一个特殊的表叫做Webtable。
在Webtable里,使用URL作为行关键字,使用网页的某些属性作为列名,网页的内容存在“contents:
”列中,并用获取该网页的时间戳作为标识,(如图2—1[5])。
其中行名是一个反向URL。
contents列族存放的是网页的内容,anchor列族存放引用该网页的锚链接文本。
CNN的主页被SportsIllustrater和MY-look的主页引用,因此该行包含了名为“anchor:
”和“anchhor:
my.look.ca”的列。
每个锚链接只有一个版本。
而contents列则有三个版本,分别由时间戳t3,t5,和t6标识。
2.1、行
表中的行关键字可以是任意的字符串。
对同一个行关键字的读或者写操作都
是原子的(不管读或者写这一行里多少个不同列),这个设计决策能够使用户很容易的理解程序在对同一个行进行并发更新操作时的行为。
Bigtable通过行关键字的字典顺序来组织数据。
表中的每个行都可以动态分区。
每个分区叫做一个“Tablet”,Tablet是数据分布和负载均衡调整的最小单位。
这样做的结果是,当操作只读取行中很少几列的数据时效率很高,通常只需要很少几次机器间的通信即可完成。
用户可以通过选择合适的行关键字,在数据访问时有效利用数据的位置相关性,从而更好的利用这个特性。
例如,在Webtable里,通过反转URL中主机名的方式,可以把同一个域名下的网页聚集起来组织成连续的行。
具体来说,可以把
2.2、列族
列关键字组成的集合叫做“列族”,列族是访问控制的基本单位。
存放在同一列族下的所有数据通常都属于同一个类型。
列族在使用之前必须先创建,然后才能在列族中任何的列关键字下存放数据。
列族创建后,其中的任何一个列关键字下都可以存放数据。
根据其设计意图,一张表中的列族不能太多(最多几百个),并且列族在运行期间很少改变。
与之相对应的,一张表可以有无限多个列。
列关键字的命名语法如下:
列族:
限定词。
列族的名字必须是看得懂的字符串,而限定词的名字可以是任意的字符串。
比如,Webtable有个列族language,language列族用来存放撰写网页的语言。
在language列族中只使用一个列关键字,用来存放每个网页的语言标识符。
Webtable中另一个有用的列族是anchor,这个列族的每一个列关键字代表一个锚链接,如图2—1所示。
Anchor列族的限定词是引用该网页的站点名,Anchor列族每列的数据项存放的是链接文本。
访问控制、磁盘和内存的使用统计都是在列族层面进行的。
在Webtable的例子中,上述的控制权限能帮助管理不同类型的应用:
其中允许一些应用可以添加新的基本数据、一些应用可以读取基本数据并创建继承的列族、一些应用则只允许浏览数据(甚至可能因为隐私的原因不能浏览所有数据)。
2.3、时间戳
在Bigtable中,表的每一个数据项都可以包含同一份数据的不同版本,不同版本的数据通过时间戳来索引。
Bigtable时间戳的类型是64位整型。
Bigtable可以给时间戳赋值,用来表示精确到毫秒的“实时”时间,用户程序也可以给时间戳赋值。
如果应用程序需要避免数据版本冲突,那么它必须自己生成具有唯一性的时间戳。
数据项中,不同版本的数据按照时间戳倒序排序,即最新的数据排在最前面。
为了减轻多个版本数据的管理负担,对每一个列族配有两个设置参数,Bigtable通过这两个参数可以对废弃版本的数据自动进行垃圾收集。
用户可以指定只保存最后n个版本的数据,或者只保存“足够新”的版本的数据(比如,只保存最近7天的内容写入的数据)。
在Webtable的举例里,contents:
列存储的时间戳信息是网络爬虫抓取一个页面的时间。
上面提及的垃圾收集机制可以让人们只保留最近三个版本的网页数据。
3、BigTable的基础构件及实现概述
3.1、BigTable的基础构件
Bigtable是建立在其它的几个Google基础构件上的。
Bigtable使用Google的分布式文件系统(GoogleFileSystemGFS)[8]存储日志文件和数据文件。
Bigtable集群通常运行在一个共享的机器池中,池中的机器还会运行其它的各种各样的分布式应用程序,Bigtable的进程经常要和其它应用的进程共享机器。
Bigtable依赖集群管理系统来调度任务、管理共享的机器上的资源、处理机器的故障、以及监视机器的状态。
Bigtable内部存储数据的文件是GoogleSSTable[9]格式的。
SSTable是一个持久化的、排序的、不可更改的Map结构,而Map是一个key-value映射的数据结构,key和value的值都是任意的Byte串。
可以对SSTable进行如下的操作:
查询与一个key值相关的value,或者遍历某个key值范围内的所有的key-value对。
从内部看,SSTable是一系列的数据块(通常每个块的大小是64KB,这个大小是可以配置的)。
SSTable使用块索引(通常存储在SSTable的最后)来定位数据块,在打开SSTable的时候,索引被加载到内存。
每次查找都可以通过一次磁盘搜索完成:
首先使用二分查找法在内存中的索引里找到数据块的位置,然后再从硬盘读取相应的数据块。
也可以选择把整个SSTable都放在内存中,这样就不必访问硬盘了。
Bigtable还依赖一个高可用的、序列化的分布式锁服务组件,叫做Chubby[12]。
一个Chubby服务包括了5个活动的副本,其中的一个副本被选为Master,并且处理请求。
只有在大多数副本都是正常运行的,并且彼此之间能够互相通信的情况下,Chubby服务才是可用的。
当有副本失效的时候,Chubby使用Paxos算法[12]来保证副本的一致性。
Chubby提供了一个名字空间,里面包括了目录和小文件。
每个目录或者文件可以当成一个锁,读写文件的操作都是原子的。
Chubby客户程序库提供对Chubby文件的一致性缓存。
每个Chubby客户程序都维护一个与Chubby服务的会话。
如果客户程序不能在租约到期的时间内重新签订会话的租约,这个会话就过期失效了。
当一个会话失效时,它拥有的锁和打开的文件句柄都失效了。
Chubby客户程序可以在文件和目录上注册回调函数,当文件或目录改变、或者会话过期时,回调函数会通知客户程序。
Bigtable使用Chubby完成以下的几个任务:
确保在任何给定的时间内最多只有一个活动的Master副本;
存储Bigtable数据的自引导指令的位置(参考3.2.1节);
查找Tablet服务器,以及在Tablet服务器失效时进行善后(参考3.2.2节);
存储Bigtable的模式信息(每张表的列族信息);
以及存储访问控制列表。
如果Chubby长时间无法访问,Bigtable就会失效。
Google在使用11个Chubby服务实例的14个Bigtable集群上测量了这个影响[2]。
由于Chubby不可用而导致Bigtable中的部分数据不能访问的平均比率是0.0047%。
单个集群里,受Chubby失效影响最大的百分比是0.0326%[2]。
3.2、BigTable的实现
Bigtable包括了三个主要的组件[14]:
链接到客户程序中的库、一个Master服务器和多个Tablet服务器。
针对系统工作负载的变化情况,Bigtable可以动态的向集群中添加(或者删除)Tablet服务器。
Master服务器主要负责以下工作:
为Tablet服务器分配Tablets、检测新加入的或者过期失效的Table服务器、对Tablet服务器进行负载均衡、以及对保存在GFS上的文件进行垃圾收集。
除此之外,它还处理对模式的相关修改操作,例如建立表和列族。
每个Tablet服务器都管理一个Tablet的集合(通常每个服务器有大约数十个至上千个Tablet)。
每个Tablet服务器负责处理它所加载的Tablet的读写操作,以及在Tablets过大时,对其进行分割。
和很多Single-Master类型的分布式存储系统[8]类似,客户端读取的数据都不经过Master服务器:
客户程序直接和Tablet服务器通信进行读写操作。
由于Bigtable的客户程序不必通过Master服务器来获取Tablet的位置信息,因此,大多数客户程序甚至完全不需要和Master服务器通信。
在实际应用中,Master服务器的负载是很轻的。
一个Bigtable集群存储了很多表,每个表包含了一个Tablet的集合,而每个Tablet包含了某个范围内的行的所有相关数据。
初始状态下,一个表只有一个Tablet。
随着表中数据的增长,它被自动分割成多个Tablet,缺省情况下,每个Tablet的尺寸大约是100MB到200MB。
3.2.1、Tablet的位置
GoogleBigtable使用一个三层的、类似B+树的结构存储Tablet的位置信息(如图3—1[3])。
第一层是一个存储在Chubby中的文件,它包含了RootTablet的位置信息。
RootTablet包含了一个特殊的METADATA表里所有的Tablet的位置信息。
METADATA表的每个Tablet包含了一个用户Tablet的集合。
RootTablet实际上是METADATA表的第一个Tablet,只不过对它的处理比较特殊(RootTablet永远不会被分割)这就保证了Tablet的位置信息存储结构不会超过三层。
在METADATA表里面,每个Tablet的位置信息都存放在一个行关键字下面,而这个行关键字是由Tablet所在的表的标识符和Tablet的最后一行编码而成的。
METADATA的每一行都存储了大约1KB的内存数据。
在一个大小适中的、容量限制为128MB的METADATATablet中,采用这种三层结构的存储模式,可以标识2^34个Tablet的地址(如果每个Tablet存储128MB数据,那么一共可以存储2^61字节数据)。
客户程序使用的库会缓存Tablet的位置信息。
如果客户程序没有缓存某个Tablet的地址信息,或者发现它缓存的地址信息不正确,客户程序就在树状的存储结构中递归的查询Tablet位置信息;
如果客户端缓存是空的,那么寻址算法需要通过三次网络来回通信寻址,这其中包括了一次Chubby读操作;
如果客户端缓存的地址信息过期了,那么寻址算法可能需要最多6次网络来回通信才能更新数据,因为只有在缓存中没有查到数据的时候才能发现数据过期(假设METADATA的Tablet没有被频繁的移动)。
尽管Tablet的地址信息是存放在内存里的,对它的操作不必访问GFS文件系统,但是,通常会通过预取Tablet地址来进一步的减少访问的开销:
每次需要从METADATA表中读取一个Tablet的元数据的时候,它都会多读取几个Tablet的元数据。
在METADATA表中还存储了次级信息,包括每个Tablet的事件日志(例如,什么时候一个服务器开始为该Tablet提供服务)。
这些信息有助于排查错误和性能分析。
3.2.2、Tablet分配
在任何一个时刻,一个Tablet只能分配给一个Tablet服务器。
Master服务器记录了当前有哪些活跃的Tablet服务器、哪些Tablet分配给了哪些Tablet服务器、哪些Tablet还没有被分配。
当一个Tablet还没有被分配、并且刚好有一个Tablet服务器有足够的空闲空间装载该Tablet时,Master服务器会给这个Tablet服务器发送一个装载请求,把Tablet分配给这个服务器。
Bigtable使用Chubby跟踪记录Tablet服务器的状态。
当一个Tablet服务器启动时,它在Chubby的一个指定目录下建立一个有唯一性名字的文件,并且获取该文件的独占锁。
Master服务器实时监控着这个目录,因此Master服务器能够知道有新的Tablet服务器加入了。
如果Tablet服务器丢失了Chubby上的独占锁(比如由于网络断开导致Tablet服务器和Chubby的会话丢失)它就停止对Tablet提供服务。
(Chubby提供了一种高效的机制,利用这种机制,Tablet服务器能够在不增加网络负担的情况下知道它是否还持有锁)。
只要文件还存在,Tablet服务器就会试图重新获得对该文件的独占锁;
如果文件不存在了,那么Tablet服务器就不能再提供服务了,它会自行退出。
当Tablet服务器终止时(比如,集群的管理系统将运行该Tablet服务器的主机从集群中移除),它会尝试释放它持有的文件锁,这样一来,Master服务器就能尽快把Tablet分配到其它的Tablet服务器。
Master服务器负责检查一个Tablet服务器是否已经不再为它的Tablet提供服务了,并且要尽快重新分配它加载的Tablet。
Master服务器通过轮询Tablet服务器文件锁的状态来检测何时Tablet服务器不再为Tablet提供服务。
如果一个Tablet服务器报告它丢失了文件锁,或者Master服务器最近几次尝试和它通信都没有得到响应,Master服务器就会尝试获取该Tablet服务器文件的独占锁;
如果Master服务器成功获取了独占锁,那么就说明Chubby是正常运行的,而Tablet服务器要么是宕机了、要么是不能和Chubby通信了,因此,Master服务器就删除该Tablet服务器在Chubby上的服务器文件以确保它不再给Tablet提供服务。
一旦Tablet服务器在Chubby上的服务器文件被删除了,Master服务器就把之前分配给它的所有的Tablet放入未分配的Tablet集合中。
为了确保Bigtable集群在Master服务器和Chubby之间网络出现故障的时候仍然可以使用,Master服务器在它的Chubby会话过期后主动退出。
但是不管怎样,如同前面所描述的,Master服务器的故障不会改变现有Tablet在Tablet服务器上的分配状态。
当集群管理系统启动了一个Master服务器之后,Master服务器首先要了解当前Tablet的分配状态,之后才能够修改分配状态。
Master服务器在启动的时候执行以下步骤:
(1)Master服务器从Chubby获取一个唯一的Master锁,用来阻止创建其它的Master服务器实例;
(2)Master服务器扫描Chubby的服务器文件锁存储目录,获取当前正在运行的服务器列表;
(3)Master服务器和所有的正在运行的Tablet表服务器通信,获取每个Tablet服务器上Tablet的分配信息;
(4)Master服务器扫描METADATA表获取所有的Tablet的集合。
在扫描的过程中,当Master服务器发现了一个还没有分配的Tablet,Master服务器就将这个Tablet加入未分配的Tablet集合等待合适的时机分配。
可能会遇到一种复杂的情况:
在METADATA表的Tablet还没有被分配之前是不能够扫描它的。
因此,在开始扫描之前(步骤四),如果在第三步的扫描过程中发现RootTablet还没有分配,Master服务器就把RootTablet加入到未分配的Tablet集合。
这个附加操作确保了RootTablet会被分配。
由于RootTablet包括了所有METADATA的Tablet的名字,因此Master服务器扫描完RootTablet以后,就得到了所有的METADATA表的Tablet的名字了。
保存现有Tablet的集合只有在以下事件发生时才会改变:
建立了一个新表或者删除了一个旧表、两个Tablet被合并了、或者一个Tablet被分割成两个小的Tablet。
Master服务器可以跟踪记录所有这些事件,因为除了最后一个事件外的两个事件都是由它启动的。
Tablet分割事件需要特殊处理,因为它是由Tablet服务器启动。
在分割操作完成之后,Tablet服务器通过在METADATA表中记录新的Tablet的信息来提交这个操作;
当分割操作提交之后,Tablet服务器会通知Master服务器。
如果分割操作已提交的信息没有通知到Master服务器,Master服务器在要求Tablet服务器装载已经被分割的子表的时候会发现一个新的Tablet。
通过对比METADATA表中Tablet的信息,Tablet服务器会发现Master服务器要求其装载的Tablet并不完整。
因此,Tablet服务器会重新向Master服务器发送通知信息[11]。
3.2.3、Tablet服务
如图3—2[3]所示,Tablet的持久化状态信息保存在GFS上。
更新操作提交到REDO日志中。
在这些更新操作中,最近提交的那些存放在一个排序的缓存中,我们称这个缓存为memtable。
较早的更新存放在一系列SSTable中。
为了恢复一个Tablet,Tablet服务器首先从METADATA表中读取它的元数据。
Tablet的元数据包含了组成这个Tablet的SSTable的列表,以及一系列RedoPoint,这些RedoPoint指向可能含有该Tablet数据的已提交的日志记录。
Tablet服务器把SSTable的索引读进内存,之后通过重复RedoPoint之后提交的更新来重建memtable。
当对Tablet服务器进行写操作时,Tablet服务器首先要检查这个操作格式是否正确、操作发起者是否有执行这个操作的权限。
权限验证的方法是通过从一个Chubby文件里读取出来的具有写权限的操作者列表来进行验证(这个文件几乎一定会存放在Chubby客户缓存里)。
成功的修改操作会记录在提交日志里。
可以采用批量提交方式来提高包含大量小的修改操作的应用程序的吞吐量[5]。
当一个写操作提交后,写的内容插入到memtable里面。
当对Tablet服务器进行读操作时,Tablet服务器会作类似的完整性和权限检查。
一个有效的读操作在一个由一系列SSTable和memtable合并的视图里执行。
由于SSTable和memtable是按字典排序的数据结构,因此可以高效生成合并视图。
当进行Tablet的合并和分割时,正在进行的读写操作能够继续进行。
3.2.4、紧缩
随着写操作的执行,memtable的大小不断增加。
当memtable的尺寸到达一个门限值的时候,这个memtable就会被冻结,然后创建一个新的memtable;
被冻结住memtable会被转换成SSTable[14],然后写入GFS,我们称这种紧缩行为为MinorCompaction。
MinorCompaction过程有两个目的:
缩小Tablet服务器使用的内存,以及减少了在服务器灾难恢复过程中必须从提交日志里读取的数据量。
在Compaction过程中,正在进行的读写操作仍能继续。
每一次MinorCompaction都会创建一个新的SSTable如果MinorCompaction过程不停滞的持续进行下去,读操作可能需要合并来自多个SSTable的更新;
否则,我们通过定期在后台执行MergingCompaction过程合并文件,限制这类文件的数量。
MergingCompaction过程读取一些SSTable和memtable的内容,合并成一个新的SSTable。
只要MergingCompaction过程完成了,输入的这些SSTable和memtable就可以删除了。
合并所有的SSTable并生成一个新的SSTable的MergingCompaction过程叫作MajorCompaction。
由非MajorCompaction产生的SSTable可能含有特殊的删除条目,这些删除条目能够隐藏在旧的、但是依然有效的SSTable中已经删除的数据。
而MajorCompaction过程生成的SSTable不包含已经删除的信息或数据。
Bigtable循环扫描它所有的Tablet,并且定期对它们执行MajorCompaction。
MajorCompaction机制允许Bigtable回收已经删除的数据占有的资源,并且确保Bigtable能及时清除已经删除的数据,这对存放敏感数据的服务是非常重要。
4、BigTable的性能分析
4.1、BigTable的优点
Bigtable是压缩的、高性能、应用友好地专用数据库系统。
1、压缩性
压缩分为主要和次要的两部分。
次要的压缩仅仅包括几个Tablets,而主要的压缩时关于整个系统的压缩。
主压缩有回收硬盘空间的功能。
Tablets的位置实际上是存储在几个特殊的Bigtable的存储单元cell中。
很多应用程序也通过选择合适的行名来将相似的数据聚簇在一起,以获取较高的压缩率。
在Bigtable中存储同一份数据的多个版本的时候,压缩效率会更高。
2、数据模型简单
Bigtable不支持完全的关系数据模型,而是为客户提供了简单的数据模型,让客户来动态控制数据的分布和格式,并允许客户推断底层存储数据的局部性。
数据下标是行和列的名字,数据本身可以是任何字串。
Bigtable的数据是字串,没有解释。
客户会在把各种结构或者半结构化的数据串行化到数据中。
通过仔细选择数据表示,客户可以控制数据的局部化。
最后,可以使用Bigtable模式来控制数据是放在内存里还是在硬盘上。
3、分布式
Bigtable是一个构建在GFS之上的分布式散列机制。
它不是一个关系数据库。
它不支持联结或者SQL类型查询。
4、可扩展性、高性能
Bigtable在很多地方和数据库很类似:
它使用了很多数据库的实现策略。
并行数据库和内存数据库有可扩展性和高性能。
5、易于实现
Bigtable不支持事务,只保证对单条记录的原子性。
事务是好东西,但事务也是导致数据库实现复杂化、性能下降最主要的根源。
Bigtable的开发者通过调研后发现其实大家对事务都没什么需求,只要保证对单条记录的更新是原子的就可以了。
这样,为了支持事务所要考虑的串行化、事务的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- google Bigtable数据存储系统性能分析 Bigtable 数据 存储系统 性能 分析