google big table杂谈

1: tablet分区 ---->  列族 ---->  列 相互关系是啥???????

2: zk真的负责 hbase数据的位置定位吗 ???????

找到 master  tablet服务器  zk各自的服务分工和相互协调

http://blog.csdn.net/andyxm/article/details/9096935

3: 一个大小为120MB的 stu表, 两个列族, 基本信息列族 +  扩展信息列族,

          那么stu表在hbase中有几个 tablet, 逻辑图是什么样子的???   ????????????

1 摘要

big table是一个分布的结构化数据存储系统,用来处理海量数据,机器规模为数千台普通PC

数据量级别为PB。

bigtable在google应用于: Web索引  Google Earch  Google Finace, 不同应用对bigtable提出要求差异非常大,无论从数据量还是响应速度上,有的需要及时响应,快速返回数据给最终用户,有的需要高吞吐的批处理,尽管应用需求差异很大,但是基于bigtable灵活高性能的特点,以及bigtabl简单的数据模型,用户能够动态的控制数据的分布和格式,bigtable依旧能够提供不同的处理方案。

2 介绍

bigtable特点: 适用性广泛, 可扩展, 高性能, 高可用性。

在很多方面,bigtable和数据库很类似,它使用了很多数据库的实现策略。

并行数据库和内存数据库已经具备了可扩展和高性能,bigtable提供了一个和这些系统完全不同的接口,

bigtable不支持完整的关系数据模型,而是提供了简单的数据模型,利用这个模型客户可以动态控制数据的分布和格式,用户可以自己推测底层存储数据的位置相关性, bigtable将存储的数据都视为字符串,但是bigtable本身不去解析这些字符串, 客户端程序通常会把各种结构化或者半结构化的数据串行到这些字符串里,通过仔细选择数据的模式,客户可以控制数据的位置相关性,最后可以通过bigtable的模式参数来控制数据是存放在内存中还是硬盘上。

3 数据模型

bigtable是一个稀疏的,分布式的,持久化存储的多维度排序Map,

Map的索引是行关键字,列关键字以及时间戳,map中的每个value都是一个未经解析的byte数组,如下:

(row:string,column:string,time:int64)--->string

下面是上述模型设计决策的产生过程:

要存储海量的网页和相关信息,这些数据用于不同项目,存储表名为webtable, 我们使用url作为行关键字,使用网页某些属性作为列名,并用获取该网页时间戳作为标识。

如下是webtable的字段片段:




 
 
 

3.1 行

行关键字可以是任意字符串,(最大支持64KB,对大部分用户来讲10-100字节足够)

 不管这一行有多少个列,对同一行关键字的读或者写操作都是原子的。

bigtable通过行关键字的字典顺序来组织数据,基于列式存储概念,表中的每一行都可以动态分区,

每个分区叫做 Tablet, Tablet是数据分布和负载均衡的最小单位,动态分区(Tablet)好处是在读取行中很少几列时效率很高,通常只需要很少几次机器间通讯即可。

3.2 列族

概念:几个列组成的集合叫做列族,

特点:a) 列族是访问控制的基本单位  b) 放在同一列族下所有数据通常都属于同一个类型

           c) 列族需要先创建   d) 一个表的列族最多几百个这种规模, 一旦创建很少变化

           e) 一个表可以有无限多个列,但是列族个数是有限度的

           f) 列族:列名 真实使用中都是这样使用的

扩展:访问控制,磁盘和内存的使用统计都是在列族层面进行的

3.3 时间戳

a) 时间戳类型是64位整数, bigtable给时间戳赋值,表示精确到毫秒的实时时间

b) 用户可以给时间戳赋值,但是必须应用程序生成全局唯一的以防止数据版本冲突

c) 不同版本数据按照时间戳倒序排序,最新的那一条放在最前面

d) 列族有两个参数, 1是只保存最后n个版本 或者是只保存最近几天写入的数据,通过这种方式来减轻多个版本数据的管理负担,让bigtable对废弃数据自动进行垃圾收集。

4 API

a) 修改集群 表 列族元数据API  访问权限

b) 查找行值 遍历  写入或者删除   带有正则的查询匹配数据  查询时间戳

c) 支持单行上的事务处理,这样可以对一个行关键字下的数据进行 原子性的 读-更新-写操作

d) 不支持通用的跨行事务处理

e) bigtable可以和mapreduce一起使用,bigtable可以作为mapreduce框架的输入和输出。

5 BigTable 构件

bigtable是建立在其他的几个google基础构建上。bigtable集群运行在一个共享的机器池中,池中的机器还运行其他的各种各样分布式应用,bigtable进程通常要和其他应用进程共享机器,并依赖集群管理系统来调度任务,管理共享机器上的资源,处理机器故障,监视机器状态。

 bigtable内部数据存储文件是Google SSTable格式,SSTable是持久的,排序的,不可变更的Map,

可以对此Map查询与一个key相关的value或者遍历某个key范围内的VALUE,

SSTable是一系列数据块(通常每个块是64KB,可以调整配置),SSTable使用块索引(通常存储在SSTable的最后)来定位块,在打开SSTable的时候,索引被加载到内存,每次查找都通过一次磁盘搜索完成,搜索过程如下:1 使用二分法在内存中的索引找到数据块的位置 2 然后从硬盘中读取

也可以吧SSTable放在内存中,这样就节省步骤2了,减少IO

BigTable依赖一个高可用,序列化的分布式锁服务组件,叫Chubby,

1)Chubby组件包含5个副本,一个是master并处理请求,当有副本失效时,Chubby使用Paxos算法保证副本一致性。

2)Chubby提供一个名字空间,里面包含了目录和小文件,每个目录或者小文件都可以当成一个锁,

读写文件的操作都是原子的,Chubby客户程序库提供对Chubby文件的一致性缓存,每个Chubby客户程序都维护一个与Chubby服务的会话,如果客户程序不能再租约到期内重新签订会话租约的话,对应会话就过期失效,这样此会话对应的锁和打开的文件句柄都会失效,Chubby客户程序可以在文件或者目录上注册回调函数,当文件或目录改变,或会话过期,回调函数会通知客户程序。

bigtable使用chubby完成以下的几个任务: (维护hbase数据一致性和稳定性和数据寻址)

a) 确保在任何给定时间内最多只有一个活动的Master

b) 存储bigtable数据的自引导指定位置

c) 查找tablet服务器,以及在tablet服务器失效时进行的善后

d) 存储bigtable模式信息(每张表的列族信息)

e) 存储访问控制列表

如果chubby长期无法访问,bigtable就会失效,比如使用11个chubby测试14个bigtable集群上,由于chubby不可用导致的bigtable中部分数据不能访问的平均比率是 0.0047%

6 介绍

bigtable分为三部分:  链接到客户程序的库   +   1个master服务器  +  多个tablet服务器

master职责: 给Tablet服务器分配tablets, 检测新加入或者过期的Tablet服务器, 对Tables服务器做负载均衡,对保存在GFS上的文件进行垃圾回收,建立表和列族

tablet服务器职责:  每台tablet服务器都管理一个tablet集合(十个至上千个tablet), 否则对其内的tablet的读写,在tablet过大时进行切割。

客户端程序: 读写数据直接和tablet服务器交互, 实际应用中master服务器负载很轻。

相互关系:

一个bigtable集群里有很多表,

每个表内有一个tablet集合,---> tablet就是hbase region的意思

而每个tablet包含了某个范围内行的所有相关数据,

初始状态下,一个表只有一个tablet, 随着表中数据增长,会被自动分割成多个tablet, 缺省情况下每个tablet

尺寸为100-200MB。

6.1 Tablet位置

hbase tablet位置信息如下图结构:



 第一层是存储在Chubby中的文件,包含了root tablet的位置信息,

root table内数据是metadata表中所有tablet的位置信息,

metadata表的每个tablet包含了一个用户tablet的集合,

root table永远不会被分割, hbase上述流程保证了tablet位置信息存储就是三层。

METADATA表里面,每个tablet位置信息都存放在一个行关键字下面,这个行关键字由Tablet所在的表标识符和Tablet最后一行编码而成的,METADATA的每一行都存储了大约1KB的内存数据,在一个大小适中,容量限制为128M的METADATA Table中,采用这三层结构的存储模式,可以标识2的34次方的地址,

客户程序使用的库会缓存Tablet的位置信息,

1) 如果客户程序没有缓存某个Tablet的地址信息或者发现缓存的地址信息不正确,

客户程序就会在树状的存储结构中递归调查Tablet的位置信息。

2) 如果客户端缓存是空的,寻址算法会通过三次网络来回通讯来寻址,其中包括一次Chubby读操作

3) 如果客户端缓存数据过期了,寻址算法可能需要最多6次网络来回通讯才能更新数据, 通常我们会通过预取Tablet地址来进一步减少访问的开销:即每次需要从METADATA表中读取一个Tablet元数据时,都会多读取几个Tablet的元数据。

6.2 Tablet分配

任何时候一个tablet只能分配给一个tablet服务器,Master服务器记录当前有哪些活跃的服务器,哪些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服务器文件锁状态来检测何时Tablet服务器不再为Tablet提供服务,

如果一个Tablet服务器报告它丢失了文件锁,或者Master服务器最近几次尝试和它通讯都没有得到响应,

Master服务器就会尝试获取该Tablet服务器文件的独占锁,如果Master服务器成功获取到,说明Chubby是正常运行的,而Tablet服务器要么宕机要么不能和不能和Chubby通讯,因此Master就删除该Tablet服务器在Chubby上的服务文件以确保它不再给Tablet提供服务,而一旦Tablet服务器在Chubby上的服务器文件被删除,Master就会把之前分配给它的所有Tablet放入未分配的Tablet集合中

Master服务器故障不会改变现有Tablet在Tablet服务器上的分配状态。

集群启动Master服务器后,Master服务器在启动时执行如下步骤:

1) Master服务器从Chubby获取一个唯一的Master锁,用来阻止其他的Master服务器实例

2) Master服务器扫描Chubby服务器文件锁存储目录,获取当前正在运行的服务器列表

3) Master服务器和所有正在运行的Tablet服务器通讯,获取每个Tablet服务器上Tablet的分配信息

4) Master服务器扫描METADATA表获取所有的Tablet集合。

扫描过程中,master发现还没有分配的tablet,master会把这个tablet加入到未分配的tablet集合等待何时机会分配。

保存现有的Tablet集合会在如下情况下发生:

1) 建立一个新表/ 删除一个旧表 (master服务器执行)

2)两个tablet被合并 (master服务器执行)

3)一个tablet被分割成两个小的tablet (tablet服务器执行)

当步骤3)分割操作完成后,tablet服务器通过在METADATA表中记录新的Tablet信息来提交这个操作结果,

提交之后,tablet服务器会通知master服务器, 如果分割操作已提交信息没有通知到master服务器,

tablet服务器在装载已经被分割的子表时会发现新的tablet,通过对比 METADATA表中的tablet信息,

tablet服务器会发现不一致并重新向master服务器发送通知信息。

6.3 Tablet服务



 

如上图,tablet持久化信息保存在GFS上,更新操作提交到REDO日志中,更新操作中,最新提交的那些存放在一个排序的缓存中,这个缓存就是上图的memtable, 而更早的更新已经将数据持久化到sstable。

当对tablet服务器进行写操作时候,tablet服务器首先要检查这个操作格式是否正确,发起者是否权限,

当一个写操作提交成功后,写的内容插入到memtable里。

当对tablet服务器进行读操作时,tablet服务器会做类似的完整性和权限检查,读操作在一个由一系列

sstable 和memtable合并的视图里执行。 由于sstable和memtable是按字典排序的数据结构,因此可以高效生成合并视图,

当进行tablet合并和分割时,正在进行的读写操作能够继续进行。

6.4 空间收缩

随着写操作执行,memtable大小不断增加,增加到一定值,这个memtable就会被冻结,然后创建一个新的memtable, 而被冻结的memtable会被转化为sstable,然后写入gfs,

7 优化

7.1 局部性群组

将经常一起访问到的列族分配到局部性群组中,提供访问速率

同时可以将局部性群组设定为全部存储 在内存 中  ,  这样tablet服务器会将设定为内存中的局部性群族对应的sstable装载到内存,这个特性对于需要访问的小数据块特别有用。

7.2 压缩

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

为了提高读操作性能,tablet服务器使用二级缓存策略,扫描缓存 是第一级缓存,主要缓存tablet服务器通过

sstable接口获取的key-value对,block缓存是二级缓存 ,缓存GFS读取的sstable的block,

对于需要经常读取相同数据的应用程序来说,扫描缓存非常有效,

对于经常要读取读过的数据附近的数据应用程序来说 ,block缓存更有用。

7.3 .1 bloom过滤器

使用bloom过滤器查询一个sstable特定行列数据,这样我们只需要牺牲将bloom过滤器加载到内存的代价,

就换来了读操作显著减少磁盘访问次数的目的。

7.3.2 commit日志的实现

 如果我们把每个tablet操作的commit日志都存在一个单独文件的话,那么会产生大量的文件,

并且这些文件会并行写入GFS, 而GFS在将这些文件写入不同磁盘日志文件时,会产生大量seek操作,

 为了避免这些问题,我们设置每个tablet服务器一个commit日志文件,把修改操作的日志以追加方式写入同一个日志文件,因此一个实际的日志文件中混合了多多个tablet修改的日志记录。

使用单个日志提高显著提高了普通操作的性能,但是恢复的工作复杂化了,但一个tablet服务器宕机时,

他加载的tablet将会被移动到很多其他的tablet服务器上,每个tablet服务器都装载很少几个原来的服务器的tablet,当恢复一个tablet状态时,新的tablet服务器从原来的tablet服务器写的日志中提取修改的操作信息,

并重新执行。

当向GFS写commit日志时,可能会遇到系统颠簸,原因很多,比如写操作执行时候一个GFS宕机了,或者连续三个GFS副本所在服务器网络拥塞或者过载,为了确保在GFS负载高峰时修改操作还能顺利进行,每个tablet服务器实际上有两个日志写入线程,每个线程都写自己的日志文件,并且在任何时候,只有一个线程是工作的,如果一个线程在写入日志效率很低,tablet服务器会切换到另外一个线程,修改操作的日志就写入到这个线程对应的日志文件中,每个日志记录都有一个序列号,因此,在恢复的时候,tablet服务器能够检测出兵忽略掉由于线程切换而导致的重复的记录。

7.3.3 tablet恢复提速

7.3.4 利用不变性

我们在使用bigtable时,除了sstable缓存之外其他部分产生的sstable都是不变的,可以利用这一点对系统进行简化 看不懂啊看不懂......
 

8 性能评估

8.1 单个Tablet服务器性能

8.2 性能提升

9 实际应用

9.1 google analytics

用于帮着web站点管理员分析他们网站流量模式的服务,提供整体状态的统计数据,

比如每天独立访问的用户数量,每天每个url浏览次数, 用户使用网站的行为报告,

比如根据用户之前访问的某些网页,统计出几成用户购买了商品。

为了使用上述服务,web站点管理员只需要在他们web页面嵌入一段JS代码,在页面被调用时,

此代码会记录各种google analytics需要的信息,比如用户标识,获取页面相关信息,后google analytics汇总

这些数据,之后提供给web站点管理员。

9.2 google earth

google earth为用户提供高分辨率的地球表面卫星图像, 这个系统使用一个表存储预处理数据,

使用另一组表存储用户数据。

9.3 个性化查询

10 经验教训

1 很多类型的错误都会导致大型分布式系统受损,不仅仅是通常的网络中断,或者分布式协议中设想的

fail-stop类型的错误,比如还有内存数据损坏,网络中断,始终偏差,机器挂起,扩展和非对称网络分区,

使用的其他系统的bug(比如chubby), gfs配额溢出,计划内和计划外硬件维护。

在彻底了解诶一个新特性会被如何使用之后,在决定是否添加这个新特性,

大多数应用程序只是需要单行上的事务处理,有些应用需要分布式的事务功能。

系统级监控对bigtable很重要

简单设计是最宝贵的经验,生产代码有100000行,随着时间推移,新的代码以各种难以预料的方式加入系统,简洁的设计给维护和调试带来巨大好处

11 相关工作

12 结论

猜你喜欢

转载自chengjianxiaoxue.iteye.com/blog/2270553