内容简介:主要内容有:分布式系统的一致性问题是大家津津乐道的话题。分布式系统由于本身分布式处理和计算的特点,需要协调各个服务器节点的服务状态保持一致来保证系统的容错能力,当某些节点出现故障的时候,不至于拖累整个集群。分布式存储作为大型系统的基石,对于跨节点的数据一致性要求很严格,尤其对于Ozone这样的强一致分布式存储系统,需要在节点间有广泛承认的协议来保证状态一致。Ozone采用了Raft协议来维护集群状态和共享数据。
之前的文章中给小伙伴们介绍了Hadoop家族中的新成员Ozone,今天继续聊聊分布式对象存储Ozone如何高效利用Raft协议完成一致性模型,并且通过优化方式最大化利用DataNode上的磁盘吞吐量。
主要内容有:
-
Raft选举机制
-
Raft一致性过程
-
Ozone为什么选择Raft协议
-
Raft的实现库Apache Ratis
Raft选举机制
分布式系统的一致性问题是大家津津乐道的话题。分布式系统由于本身分布式处理和计算的特点,需要协调各个服务器节点的服务状态保持一致来保证系统的容错能力,当某些节点出现故障的时候,不至于拖累整个集群。分布式存储作为大型系统的基石,对于跨节点的数据一致性要求很严格,尤其对于Ozone这样的强一致分布式存储系统,需要在节点间有广泛承认的协议来保证状态一致。Ozone采用了Raft协议来维护集群状态和共享数据。
Raft协议中会有3个角色身份:
-
Leader(领导者),由Leader来向其Follower身份发送各种指令。同时Leader通过心跳的方式来表明其Leader身份。
-
Follower(跟随者),Follower接收Leader的命令指示,并执行结果。如果在一定时间内没有收到Leader的消息,Follower会变为Candidate身份,重新竞选Leader身份。
-
Candidate(竞选者),Candidate可由Follower转变而来,可以竞选新的Leader领导者。Candidate向其他Follower机器发送投票选举,当超过半数以上的投票选择后,能成为Leader身份。
Split Vote(投票分裂):如果同时有两个Candidate在投票结束时获得了相同的投票,那么协议会认为竞选失败,在一段Timeout时间后,会发起新一轮的选择直到有一个Candidate获取多数票当选Leader。
主流的一致性算法中,比起过去常常被使用的Paxos,Raft协议更为简洁易懂
以下是取自raft.github.io的一个Raft协议的动画示意图,简述了Leader和Candidate的转换过程。
视频中有5个节点S1~S5,右边的区域为5个节点的日志RaftLog的变化。通过这个视频,大家可以理解下Raft协议中Leader,Follower和Candidate之间的状态转换流程。
Raft一致性过程
Raft协议本质上是通过本地的RaftLog保证数据的一致性,同时StateMachine会记录集群的状态。RaftLog使用了write ahead log (WAL) 的理念,将过程记录在Log里面,然后日志会apply log到StateMachine中记录状态,当有足够的Quorum宣布成功,整体操作就成功了。这样能保证集群所有节点的状态机变化是相对同步的,同时RaftLog会在节点重启时做replay回放操作,重新建立起重启前的StateMachine状态,让节点恢复到与重启前相对同步的状态。
Ozone为什么选择Raft协议
-
Ozone container需要高冗余度
从Ozone写入过程的container流程中,为了保证当前三副本的冗余机制,container需要在3个数据节点DataNode上分配空间并保证多数节点写成功。Raft协议中的日志机制可以保证在Leader写完成后,Replicate数量到follower上去,三副本中有一个follower写完成后,数据就持久化成功了。这个大多数数据写成功的操作可以直接由Raft协议帮助完成。
-
Ozone不同组件的定制化需求
Ozone当前不仅仅是数据层面的container有高冗余度的需求,元数据管理的Ozone Manager(OM) 和Storage Container Manager(SCM)也有高可用性的需求。 高可用性指在某一个节点或者进程故障的时候,服务可以迅速切换备用节点或者进程保证服务不中断。
以下是Ozone内部各组件的大致流程
Ozone元数据管理节点(Master)上的OM和SCM都有高可用性的需求。Ozone Manager作为主要提供读写Key地址的服务,已经实现了高可用性。OM同样利用Raft协议组织一个3节点的Raft Ring将OM从单节点转换成了集群制,保证Ozone Manager不会因为单点失败而导致服务不可用
SCM高可用性也在实现中,设计上SCM需要更多考虑内部资源比如pipeline和container信息的管理,还有跟数据节点的广播和心跳上报,从一致性模型上跟OM稍有不同。由于心跳的报告的内容较多,而且SCM也确保了心跳和报告的幂等性,所以这类数据不是必要通过Raft日志复制给follower,可以节省网络带宽的开销。
container的高可用性已经实现在DataNode的进程中,比起OM和SCM对于元数据管理的高可用性需求,container利用Raft协议更多地需要考虑数据的交互的传输,需要保证数据一致性,占用带宽较大。
OM、SCM、DataNode都有独立的进程。在一致性协议的使用上,三个进程都有各自的状态和日志记录内容的不同需求,同时State Machine更新状态后的Async请求回调中也需要负责更新不同的数据结构和内容。Raft本身代码清晰,而且比起Paxos来说流程和实现都显得更简洁,对于满足Ozone不同进程的定制化需求都更加灵活。
Raft的实现库Apache Ratis
2017年Apache社区孵化了开源项目Ratis,作为Raft协议的一种插件化实现方式。Ratis主打数据复制的吞吐量大和组件适配的灵活性,提供了各种插件式的应用方式,从通信协议到StateMachine和RaftLog都可以根据用户的定制插件化实现。这样的特点很好地满足Ozone项目对于数据吞吐率和高定制化的需求。在当前的Ozone项目实现中,OM,SCM和Container都分别实现自己的Ratis Server和Ratis StateMachine支持多副本一致性的需求,同时Ozone也利用Ratis Ring实现了管理container的数据管道data pipeline,大大提高了资源可用性和集群吞吐率。
Ratis除了Raft协议中经典的StateMachine和RaftLog之外,还实现了RetryCache,LogAppender等组件来完成分布式Raft协议的consensus和replication模型。
-
RetryCache可以对于Client请求查重,避免重复请求。
-
RaftLog作为Ratis Server的本地WAL,记录用户的操作到日志中。
-
LogAppender将Ratis Leader上WAL的更新Replicate到远端follower上,然后更新RaftLog上的commit index记录成功。
-
StateMachineUPdater根据RaftLog中的commit记录,回放apply到StateMachine中,然后purge WAL上已经输入的commit日志,达到回收空间的效果。同时还会负责给StateMachine打snapshot作为状态的checkpoint。
结束语
Apache Ozone作为一个强一致的分布式对象存储,巧妙地利用了Raft协议一致性和灵活性,完成了元数据和数据端的冗余度需求,同时Raft协议的实现Apache Ratis兼备了插件化的特点,使得Ozone可以根据不同服务的特殊需求定制Raft的接口,利用Raft协议管理包括数据面和元数据面的一致性和写入流程,让整体架构更为清晰明朗,Ratis本身基于高吞吐量日志的实现也帮助Ozone提高了写入带宽。之后的Ozone技术分享中会继续分享Ozone如何利用Raft group的交叉化管理更进一步加大了Container的写入带宽。
欢迎阅 读 其他Ozone系列文章
参考文档
-
https://raft.github.io/
-
http://ratis.incubator.apache.org/
-
https://blog.csdn.net/Androidlushangderen/article/details/99663173
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- tcache机制利用总结
- QQ二维码登陆机制分析+双重SSRF钓鱼利用
- 如何利用缓存机制实现 Java 类反射性能提升 30 倍
- LWN: 利用TCP SACK机制让远端Linux崩溃
- iOS 上利用 fallback 机制为不同语言的文字 (script) 设定字体,从而使得文本混排更为优雅
- 快速失败机制 & 失败安全机制
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。