内容简介:欢迎阅读其他Ozone系列文章
Ozone采用Ratis保证数据一致性,Ratis采用Raft协议实现,代码可见Github。本文首先介绍Ratis的gRPC模块代码,后续会陆续介绍其他模块。
1. Ratis简介
目前主要有两种分布式协议Paxos、Raft。Raft在保证一致性效果上等价于Paxos,和Paxos同等高效。而 Raft的优势是易理解,易实现。
Ratis采用Raft实现,为了保证Ozone数据一致性,Ozone的每个读写请求,都采用三备份,需要写入一个Leader和两个Follower。一个Leader和两个Follower为一个group,各为一个Ratis Server,只是角色不同,一组Ratis Server分布在三个Datanode里,作为Datanode的子线程。一个leader和两个follower各将一份请求写到log里,请求被一个group的大多数Ratis Server写入log后,即回复给client。
以写数据请求为例,该请求发到Leader后,Leader不仅需要将写数据请求写入log,而且需将被写的数据写入Leader的本地存储。Ratis负责请求写入log,然后Ratis回调Ozone的writeStateMachineData将数据写入Leader本地存储。请求写入Leader的log后,Leader将写请求以及数据发给Follower,数据需要从Leader本地存储读,数据不从请求里获取的原因是需要保证Leader写入了数据。然后Follower开始写log以及数据。可以看出,Leader将数据写入本地存储后,才将请求发给Follower,因为本地存储是磁盘,会造成Leader和Follower串行将数据写入磁盘,速度较慢。优化的方法是,Leader先将数据写入内存Cache,再将数据写入本地存储磁盘。而Leader在将数据写入内存Cache后,就可以将数据读出,并发给Follower,这样Leader和Follower可以并行将数据写入磁盘。
2. Ratis模块简介
Ratis主要模块分为三部分:ratis-client、ratis-grpc、ratis-server。
ratis-client封装给上层使用,提供操作group的接口:groupAdd、groupRemove、getGroupList等,以及发送请求的接口sendRequest等。Ozone使用ratis时,需要首先用groupAdd创建一个Leader和两个Follower的group,然后将请求包装成Ratis的请求RaftClientRequest,通过sendRequest发给Leader。
ratis-server负责数据同步主要逻辑:选举、快照、日志同步等功能,每个leader和follower都是一个RaftServerImpl实例。
ratis-grpc负责ratis-client和ratis-server,以及ratis-server和ratis-server之间的通信。
3. Ratis gRPC简介
Ratis采用gRPC作为网络框架,gRPC相关封装代码在ratis-grpc包下。一个完整的请求分为client和leader、leader和两个follower之间通信。例如Ozone需要ratis将请求写三份时,会用ratis client向ratis leader发送该请求,而ratis leader又会向两个ratis follower发送该请求,当ratis leader和两个ratis follower的大多数写完该请求时,ratis leader会向ratis client回复写成功。client、leader、follower通信时序图如下,后文会做详细介绍。
4. Client和Leader通信
该部分相关代码在ratis-grpc/src/main/java/org/apache/ratis/grpc/client,该目录下有三个文件负责通信:GrpcClientProtocolClient、GrpcClientProtocolService、GrpcClientRpc。
ratis client相关代码在ratis-client目录下,本文不涉及该部分。client调用GrpcClientRpc::sendRequestAsync向leader发送请求。leader会在GrpcClientProtocolService的RequestStreamObserver::onNext里处理该请求。leader处理请求时,不仅会自己将请求写入log,还会通知两个follower写入log,可见下文。leader处理完后会向client回复,client在GrpcClientProtocolClient的AsyncStreamObservers::onNext里判断写请求三备份是否成功。
5. Leader和Follower通信
该部分相关代码在ratis-grpc/src/main/java/org/apache/ratis/grpc/server,该目录下有三个文件负责通信:GrpcClientProtocolService、GrpcLogAppender、GrpcServerProtocolClient。
leader在GrpcClientProtocolService的RequestStreamObserver::onNext里收到请求后,会交给RaftServerImpl::submitClientRequestAsync处理,该函数首先校验当前server是否是leader等,然后leader将请求放入待写队列,并通知leader向follower发请求的线程GrpcLogAppender。GrpcLogAppender负责将请求从leader发送到follower,leader为每个follower维护一个GrpcLogAppender线程。
GrpcLogAppender调用GrpcServerProtocolClient:: appendEntries将Leader已经写成功的请求发给follower,follower在GrpcServerProtocolService的ServerRequestStreamObserver::onNext里接收请求,并交给RaftServerImpl:: appendEntriesAsync处理,appendEntriesAsync需要首先校验Leader的请求,包括该请求的源Server是否是Leader,以及该请求是否已经在Follower写入等,然后将请求写入日志,处理完后回复给leader,leader在GrpcLogAppender的AppendLogResponseHandler::onNext检查follower是否写成功。如果leader和两个follower大多数写成功,leader向client回复成功,client在上文提到的GrpcClientProtocolClient的AsyncStreamObservers::onNext处理回复。
欢迎阅读其他Ozone系列文章
欢迎关注我们公众号
腾 讯 大 数 据 诚 招 计 算 、 存 储 、 消 息 中 间 件 、 调 度 、 中 台 等 各 方 向 的 大 数 据 研 发 工 程 师 , 请 私 信 或 联 系 j e r r y s h a o @ t e n c e n t . c o m 。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Lighttpd源码分析
高群凯 / 机械工业出版社 / 2010-3 / 59.00元
本书主要针对lighttpd源码进行了深度剖析。主要内容包括:lighttpd介绍与分析准备工作、lighttpd网络服务主模型、lighttpd数据结构、伸展树、日志系统、文件状态缓存器、配置信息加载、i/o多路复用技术模型、插件链、网络请求服务响应流程、请求响应数据快速传输方式,以及基本插件模块。本书针对的lighttpd项目版本为稳定版本1.4.20。 本书适合使用lighttpd的人......一起来看看 《Lighttpd源码分析》 这本书的介绍吧!