Ozone原理|Ratis代码解析之一-gRPC

栏目: IT技术 · 发布时间: 3年前

内容简介:欢迎阅读其他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通信时序图如下,后文会做详细介绍。

Ozone原理|Ratis代码解析之一-gRPC

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系列文章

浅谈配置化的Ozone网络拓扑结构

Ozone如何利用Multi-Raft优化写入吞吐量

如何用hadoop的用法来玩转ozone

浅谈Ozone的HA能力

Ozone on K8S

聊一聊Ozone如何高效利用Raft机制

Hadoop原生对象存储Ozone

欢迎关注我们公众号

Ozone原理|Ratis代码解析之一-gRPC

j e r r y s h a o @ t e n c e n t . c o m


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据结构 Python语言描述

数据结构 Python语言描述

[美] Kenneth A. Lambert 兰伯特 / 李军 / 人民邮电出版社 / 2017-12-1 / CNY 69.00

在计算机科学中,数据结构是一门进阶性课程,概念抽象,难度较大。Python语言的语法简单,交互性强。用Python来讲解数据结构等主题,比C语言等实现起来更为容易,更为清晰。 《数据结构 Python语言描述》第1章简单介绍了Python语言的基础知识和特性。第2章到第4章对抽象数据类型、数据结构、复杂度分析、数组和线性链表结构进行了详细介绍,第5章和第6章重点介绍了面向对象设计的相关知识、......一起来看看 《数据结构 Python语言描述》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器