TFS
- 两台Name Server,作文件系统管理结点,互为双机备份。多台Data Server。
- 数据组织:以block文件(一般64M一个block)的形式存放数据文件,block有多个副本。
- 用户自己保存TFS文件名与实际文件的对照关系——减少元数据量。
- 元数据:文件名内置元数据信息(如图片大小、时间、访问频次、所在的逻辑块号等),元数据信息很少,仅仅需要一个fileID从而定位文件。
- 放弃了传统的目录树结构,使得整个集群的可拓展性提高,比较像OSS
OceanBase
思想
- 虽然数据库系统数据量十分庞大(可能几十亿、几百亿条甚至更多),但一段时间(例如一天)的修改量并不大(通常不超过几千万条到几亿条)
- 将数据分为增量数据+基线数据
- 增量数据:使用单台服务器记录一段时间的修改增量,存储以内存表为主,ssd为辅
- 基线数据:在增量数据时间段内保持不变的数据。存储于多台服务器中(ChunkServer)
- 将数据分为增量数据+基线数据
- 使用主键对表中数据进行排序和存储,主键可包含多列并具有唯一性。
- 基线数据按主键排序并划分成sstable,一个或多个sstable组合为一个tablet(块),并存储在ChunkServer上。
查询、写事务
- 查询:由MergeServer把基线数据和增量数据融合后返回给调用者,分散在多台服务器上
- 写事务:集中在UpdateServer进行,避免了复杂的分布式写事务,可实现跨行跨表。
- 以内存表的方式记录修改,达到一定量,切换新的内存表,原来的内存表被冻结,先临时以一种紧凑的格式写到SSD盘中,转换成持久化数据后即可回收。
- 合并过程
- 1)UpdateServer冻结当前内存表并开启新内存表,此后新的修改写入新内存表;
- 2)ChunkServer融合当前基线数据与冻结的内存表,生成新基线数据;
- 3)当所有tablet的新基线数据生成后,UpdateServer冻结的内存表即可释放,其所占内存也被回收。
GFS + BigTable + MapReduce
- 需要是松散耦合的模型
思想
- 组件失效当成常态
- 从而放松了一致性模型的要求,引入了原子性的记录追加操作
体系架构
结点组成
- Master结点
- 一个GFS集群包含一个逻辑上唯一的Master节点
- 物理上有Master节点复制机制,为便于理解,可认为一个逻辑的Master节点包括两台物理主机,即两台Master服务器
- 功能
- 执行所有的namespace操作
- 管理整个系统的所有chunk副本
- 创建新chunk和它的副本
- 决定Chunk的存储位置
- 在所有的Chunk服务器之间进行负载均衡
- 协调各种系统活动以保证Chunk被完全复制
- 资源回收
- 一个GFS集群包含一个逻辑上唯一的Master节点
- Client节点
- 实现了GFS文件系统的API接口函数,代码以库的形式链接到客户程序中
应用程序同时以Master节点和Chunk服务器通讯,对数据进行读写操作
对Master只获取元数据(control message)、对Chunk服务器进行数据交互
Master内容管理
- 所有的文件系统源数据
- Namespace
- 文件和Chunk的映射信息
- Chunk当前的位置信息
- 访问控制信息
- 系统范围内的活动
- Chunk租约管理
- 孤儿Chunk的回收
- Chunk在Chunk服务器之前的迁移
变更日志及checkpoint
- 写日志机制
- 被持久化后才对客户端是可见的
- 灾难回复
- Master通过重演操作日志,把文件系统恢复到最近状态
- 日志过长?使用checkpoint,如下:
- Master通过重演操作日志,把文件系统恢复到最近状态
- 日志checkpoint
- 日志增长到一定就写一个checkpoint,同步磁盘
Master状态复制与影子机制
- 状态复制
- Master状态会被复制到多台机器上,也就是操作日志和checkpoint文件。
- 所以对Master状态修改成功:将日志成功写入到了Master的备份节点和本机硬盘。
- Master切换
- 使用类似DNS别名的规范访问Master。如果失效(GFS系统外部的监控进程监控到了),则在有完整操作的备份节点启动新的Master进程,通过更改别名的实际指向,让客户端访问新的Master结点
- 影子机制
- 会在主Master结点宕机时提供文件系统的只读访问
- 影子的数据可能比“主”Master更新要慢(通常不到1秒)。
- 可能过期的是文件的元数据
- 原因:因为文件内容是从Chunk服务器上读取的,应用程序不会发现过期的文件内容。
GFS数据访问
1)客户端将文件名和程序指定的字节偏移根据固定的Chunk大小转换成文件的Chunk索引,进而把文件名和Chunk索引发送给Master节点。
2)Master节点将相应的Chunk标识和副本的位置信息发还给客户端。客户端用文件名和Chunk索引作为key缓存这些信息,之后客户端发送请求(包含Chunk标识和字节范围)到其中的一个副本Chunkserver(一般选择最近的)。
3)该Chunkserver读取chunk数据返回客户端。
在开始了对Chunk的数据读取操作后,客户端不必再和Master节点通讯,除非缓存的元数据信息过期或者文件被重新打开。
Master节点的回应也可能包含了被请求Chunk的后续Chunk的信息——实际过程中,客户端通常会在一次请求中查询多个Chunk信息。
同样代价额外元数据,避免客户端和Master节点未来可能会发生的几次通讯。
小文件对于GFS缺点
- 小文件包含较少的Chunk。当有许多客户端对同一个小文件进行多次访问,该Chunk会变“热”,导致局部过载
GFS数据更新
- 写数据流程
- 靠租约来选择结点
- 1. client询问master哪个服务器有租约(Master建立租约,并将其授权给某个副本,称其为Primary结点,由它来确定数据修改的顺序,其它副本照着Primary结点一起做,如图中Secondary Replica A/B)
- 2. Master将主Chunk的标识符以及其它副本(secondary副本/二级副本)的位置返回给客户机。客户机缓存这些数据以便后续操作
- 此后只有在主Chunk不可用或主Chunk回复信息表明它已不再持有租约时,客户机才重新联系Master节点。
- 3. 客户机把数据推送到所有的副本上(可按任意的顺序推送)。
- Chunk服务器接收到数据并保存在它的内部LRU缓存中,直到数据被使用或过期交换出去。
- 4. 当所有的副本都确认收到了数据后,客户机发送写请求到主Chunk服务器。
- 主Chunk为接收到的所有操作分配连续的序列号(这些操作可能来自不同的客户机,序列号保证了操作顺序执行),按序列号的顺序把操作应用到primary自己的本地状态中。
- 5. 主Chunk把写请求传递到所有的二级副本。每个二级副本依照主Chunk分配的序列号以相同的顺序执行这些操作。
- 6. 所有的二级副本回复主Chunk“它们已经完成了操作”
- 7. 主Chunk服务器回复客户机(任何副本产生的任何错误都会返回给客户机)。
- 出现错误时,写操作可能在主Chunk和一些二级副本执行成功。(如果主Chunk上操作失败,操作不会被分配序列号,也不会传递)客户端请求被确认为失败,被修改的region处于不一致状态。客户机代码通过重复执行失败的操作来处理这样的错误。在从头开始重复执行之前,客户机会先尝试几次步骤(3)~(7)。
- 写数据分割
- 一次写入数据量较大,或跨越了多个chunk。客户机需要把他们分成多个写操作。
- 写操作的流程使得这些分解后的写操作在所有副本上都以相同的顺序执行完成,实现Chunk副本的一致性。
- 记录追加
GFS存储资源调整
- 创建Chunk
- 在Writer真正写入数据时才被物理创建
- 限制每个Chunk服务器上的近期创建chunk次数
- 尽量把Chunk的副本分布在多个机架之间
- 补充副本
- 丢失的多的补充副本优先级高
- 优先复制活跃文件的Chunk而不是最近刚被删除的文件的Chunk
- 提高会阻塞客户机程序处理流程的Chunk的优先级
- 负载均衡
- 1)通常移走剩余空间低于平均值的Chunk服务器上的副本,从而平衡系统整体的硬盘使用率。
- 2)Master逐渐的填满一个新的Chunk服务器,而不是在短时间内用新的Chunk填满它,以至于过载。
- 垃圾回收
- 不会立刻回收物理空间,只在文件和Chunk级别的常规垃圾收集时进行
- 文件被删除不立即物理删除,而是改名为带timestamp的隐藏文件名
- 名称空间定期回收
- 比如3天删除一次
- 孤立
- 隐藏文件被删除,Master里面对该文件的相关源数据才会被删除,有效切断了文件和它包含的所有Chunk的连接。