[4][lecture] Lecture 3: GFS
Posted WhateverYoung
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[4][lecture] Lecture 3: GFS相关的知识,希望对你有一定的参考价值。
6.824 2018 Lecture 3: GFS
- hdfs based on
- 系统级别论文,网络带宽权衡、容错、一致性
- 权衡了一致性和性能,简化设计
- map/reduce底层依赖的网络存储
什么是一致性?
每次读都能读到最新的写入
数据并发访问时,存在复制集场景下较难实现严格的一致性,写入要写入所有复制集,读才能任意节点读到数据,那么弱一致性允许读到老的数据,强一致性则不允许,强一致性的应用代码较为容易开发,性能较差,因为写入要多节点都写入才可以,这里有老大难的超时网络问题,弱一致性性能好容易扩展但是应用开发会有问题,在强和弱之间因为权衡产生了不同的一致性模型,贯穿分布式领域
理想的一致性模型?
集群和单机对外表现一致,并发写乱序,同时修改一个目录,lock保护串行;实现的难点在于,并发,硬盘/网络/硬件失效,要想在集群环境下达到一致性,势必需要协调通信,因此性能下降;通信协议会相当复杂,实现起来难免有bug(raft做到了!)因此大部分系统选择弱一致性,比如gfs,hdfs,大部分nosql系统
GFS设计目标?
容错,最大程度自动恢复,1000s普通机器,失效在所难免假设失效率1次/台/年,那么1000台的集群每天失效3台;水平扩展,高性能并发读写;高效利用好有限的带宽
设计准则
master,存储目录结构,包括目录,文件,open/close/read/write not posix,对于目录,存储哪些文件在该目录下,对于文件,存储了128M则有2个chunk servers,3副本共计6个chunk servers,以及chunk的元数据,每个chunk 64 bytes元数据,单点master,利用operation log持久化保证恢复,周期性flush检查点,同时采用了影子master在异常场景提供读可用性
chunkservers,64MB per chunk(a ordinary linux file each chunk),3 replications on three servers,三副本提供的高可用以及热点数据的读扩展性,不用RAID是因为失效是整机失效,而不是硬盘层面;64M的chunk,主要是master要维护所有元数据在内存,同时workload发现大数据场景也还能接受
Client read
发送文件名和chunk index到master,master返回chunk servers包含这个chunk,包括chunk版本号,client缓存这些数据,访问最近的chunk server,校验chunk version,如果校验失败,重新请求master。以上客户端缓存为了尽可能减少数据交互过程中和master的交互,因为master为了设计简单,采用单点设计,有可能瓶颈,因此其他设计尽可能减少master的交互,chunk version保证不要读到老数据
Client write
并发随机写,发送文件名到master得到chunk位置和主chunk server,master返回chunk servers,chunk version以及主节点,主节点获得60s租约,client通过网络拓扑计算pipeline复制链,并将要写的数据发送到三副本节点,全部写入完成后,client找到主节点通知写入,主节点分配序列号和该次写入,并将信息同步到另外两副本,全部写完成后,返回client成功;如果两个client并发写同一个文件在同一个位置,根据序列号决定具体行为,序列号高者得,但存在重试机制。(这里控制信号和数据信号分割,设计精妙),并发append写,会乱序
Client record append
client通信master获取chunk位置,和前述一致,先把数据发送到三副本节点,但是不指定offset,沟通主节点,分配序列号,检查当前chunk是否还有足够空间,不够padding补齐该chunk后client重试,如果可以写,选择offset本地完成写入后发送写入请求到其他两幅吧,携带offset,如果有副本写入失败,返回客户端重试,客户端通信master获得新的信息后重试写入,注意此时三副本chunk数据不完全一致,有的成功了,有的可能有空洞,要通过读取时skip掉空洞,并根据seq号做好去重才行,写入成功后返回client
集群状态
master可以指定新的主节点,赋予租约
master复制chunk,如果chunk数目不足
master负载均衡chunk,根据磁盘,IO等等信息
master不存数据分布信息,依靠心跳信息上报获得全量信息,只存储元数据信息目录文件名,以及文件对应的chunk信息,chunk version等,chunk本身信息由chunk server负责上报失效
chunk server失效,client重试
master失效,则gfs失效,影子server可以提供读服务,可能返回老数据,因为影子和master有一定的延迟,不提供写的原因怕脑裂问题gfs的一致性
目录级别,master内部锁机制,单点保证一致性,不具有扩展性和高可用,因为单点
文件级别,record append场景,依旧有可能有空洞,可以通过其他技术规避,checksum,seq唯一等等;其他写,没有一致性保证,可以用record append 临时文件加上atomic rename来保证一致性;可能短时间内读到老数据,写失败,主节点失效场景,client读到老数据,通过更新租约,可以重新得到新版本
结论
- gfs在性能,容错,一致性中取得了好的权衡,作为MR的底层系统,表现优异,后续发展过程也印证了这一点,作为BigTable,Spanner,F4的底层存储,越来越宽,当然设计应该也变得更加通用
- 适用场景,并行追加写,大尺度的顺序读写,高吞吐,容错,高可用
- 需要提高,单点master,海量小文件性能(master瓶颈),客户端会读到老数据,追加写会有空洞和重复
References
inspiration
- 高可用设计:master 和 chunkserver 在宕机后都能够快速恢复。master 除了记录 operation log,还会在日志数量达到一定程度时,将 operation log 整理成 checkpoint,每次恢复仅需从上一个 checkpoint 开始回放(replay)日志即可。
- 高可用设计:master 的状态,包含 operation log 以及 checkpoints,会被复制到多个不同的机器上,每个写操作只有在 operation log 复制完毕后,才会被 committed。一旦 master 宕机,监控系统会立即发现,并在存有 master 状态的机器上启动一个新的 master。除此之外,GFS 还提供 shadow master,在 master 宕机时提供只读服务。
- master 单点避免瓶颈设计:单个 chunk 的大小选择较大(64MB),从而减少每个文件所占用的 chunk 数量;client 对元数据的请求作了合并和缓存;client 只经过 master 取元数据,所有的原始数据的存取都不经过 master;所有的元数据都存储在 master 的内存中
- 经典设计:文件元数据与数据流的分离;数据流的并行与流水化;数据的备份与容错;考虑数据分布的负载均衡;简化一致性模型;(没有实现原子性追加写,也是缺陷!);client和chunkserver均不缓存文件数据。
- 工程优化设计:租约方式,将修改授权从master下放到数据节点;支持写时复制的元数据管理,支持快照操作(B树实现);实现数据的垃圾回收机制;
- 缺陷:master节点仍然单点不能多活;小文件的处理;客户端读取数据可能小错误;
FAQ
Q: record append是最少一次写,而没有保证只发生一次?
A: 只发生一次写入实现难度较高,主节点需要记录接入的状态来做重复写的检测,并维护到磁盘,该状态还需要复制到其他节点防止主节点失效,raft可以做到这点,不过要使用更复杂的一致性通信协议
Q: client 对于pading和重复记录如何处理?
A: magic number或者check sum可以检测空洞,每条记录分配唯一id可以去重,不完美但蛮实用
Q: 引用计数作用?
A: 实现copy-on-write机制的chunk snapshot机制
Q: master失效如何处理?
A: replication master,没有明说如何切换到备份主节点,可能需要人为介入,保障数据一致性,单点无法保证master的高可用,需要raft来做ft
Q: gfs在可用性,一致性和性能上表现如何?
A: 对于针对mr的应用优化的gfs,workload为高并发高吞吐,大文件顺序读写场景,并且应用可以接受文件空洞,重复数据,以及少量的读到数据,gfs做的很好,简单的设计完成了既定的设计目标
以上是关于[4][lecture] Lecture 3: GFS的主要内容,如果未能解决你的问题,请参考以下文章
[7][lecture] Lecture 4:VMware fault-tolerant virtual machines
[7][lecture] Lecture 4:VMware fault-tolerant virtual machines