etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程
1. etcd 项目结构和功能
etcd
项目代码的目录结构如下:
$ tree
├── auth
├── build
├── client
├── clientv3
├── contrib
├── embed
├── etcdctl
├── etcdmain
├── etcdserver
├── functional
├── hack
├── integration
├── lease
├── logos
├── mvcc
├── pkg
├── proxy
├── raft
├── scripts
├── security
├── tests
├── tools
├── vendor
├── version
└── wal
每个模块的功能如下:
etcd
核心的模块有 lease
、mvcc
、raft
、etcdserver
,其余都是辅助的功能。其中 etcdserver
是其他模块的整合。
2. etcd 整体架构
etcd
整体架构图如下:
2.1 客户端层
包括 clientv3
和 etcdctl
等客户端。用户通过命令行或者客户端调用提供了 RESTful
风格的 API
,降低了 etcd
的使用复杂度。
除此之外,客户端层的负载均衡(etcd V3.4
版本的客户端默认使用的是 Round-robin
,即轮询调度)和节点间故障转移等特性,提升了 etcd
服务端的高可用性。需要注意的是,etcd V3.4
之前版本的客户端存在负载均衡的 Bug,如果第一个节点出现异常,访问服务端时也可能会出现异常,建议进行升级。
2.2 API 接口层
API
接口层提供了客户端访问服务端的通信协议和接口定义,以及服务端节点之间相互通信的协议。
etcd
有 V3
和 V2
两个版本。
etcd V3
使用gRPC
作为消息传输协议;etcd V2
默认使用HTTP/1.x
协议。
对于不支持 gRPC
的客户端语言,etcd
提供 JSON
的 grpc-gateway
。通过 grpc-gateway
提供 RESTful
代理,转换 HTTP/JSON
请求为 gRPC
的 Protocol Buffer
格式的消息。
2.3 etcd Raft 层
负责 Leader
选举和日志复制等功能,除了与本节点的 etcd Server
通信之外,还与集群中的其他 etcd
节点进行交互,实现分布式一致性数据同步的关键工作。
2.4 逻辑层
etcd
的业务逻辑层,包括鉴权、租约、KVServer
、MVCC
和 Compactor
压缩等核心功能特性。
2.5 etcd 存储
实现了快照、预写式日志 WAL
(Write Ahead Log
)。etcd V3
版本中,使用 BoltDB
来持久化存储集群元数据和用户写入的数据。
3. 各个模块之间的交互
下图中展示了 etcd
处理一个客户端请求涉及的模块和流程。
从上至下依次为 客户端 → API
接口层 → etcd Server
→ etcd raft
算法库。我们根据请求处理的过程,将 etcd Server
和 etcd raft
算法库单独说明。
3.1 etcd Server
接收客户端的请求,在上述的 etcd
项目代码中对应 etcdserver
包。请求到达 etcd Server
之后,经过 KVServer
拦截,实现诸如日志、Metrics
监控、请求校验等功能。
etcd Server
中的 raft
模块,用于与 etcd-raft
库进行通信。
applierV3
模块封装了 etcd V3
版本的数据存储;WAL
用于写数据日志,WAL
中保存了任期号、投票信息、已提交索引、提案内容等,etcd
根据 WAL
中的内容在启动时恢复,以此实现集群的数据一致性。
3.2 etcdraft
etcd
的 raft
库。raftLog
用于管理 raft
协议中单个节点的日志,都处于内存中。
raftLog
中还有两种结构体 unstable
和 storage
,这两种结构体分别用于不同步骤的存储,区别如下
unsable
中存储不稳定的数据,表示还没有commit
;storage
中都是已经被commit
了的数据;
除此之外,raft
库更重要的是负责与集群中的其他 etcd Server
进行交互,实现分布式一致性。
3.3 交互细节
在上图中,客户端请求与 etcd
集群交互包括如下两个步骤:
首先是写数据到
etcd
节点中;其次是当前的
etcd
节点与集群中的其他etcd
节点之间进行通信,确认存储数据成功之后回复客户端;
请求流程可划分为以下的子步骤:
客户端通过负载均衡算法选择一个
etcd
节点,发起gRPC
调用;etcd Server
收到客户端请求;经过
gRPC
拦截、Quota
校验,Quota
模块用于校验etcd db
文件大小是否超过了配额;接着
KVServer
模块将请求发送给本模块中的raft
,这里负责与etcd raft
模块进行通信;发起一个提案,命令为
put foo bar
,即使用put
方法将foo
更新为bar
;在
raft
中会将数据封装成raft
日志的形式提交给raft
模块;raft
模块会首先保存到raftLog
的unstable
存储部分;raft
模块通过raft
协议与集群中其他etcd
节点进行交互。
需要注意的是,在 raft
协议中写入数据的 etcd
必定是 leader
节点,如果客户端提交数据到非 leader
节点时,该节点需要将请求转发到 etcd leader
节点处理。
响应流程的步骤如下:
提案通过
RaftHTTP
网络模块转发,集群中的其他节点接收到该提案;在收到提案之后,集群中其他节点向
leader
节点应答“我已经接收这条日志数据”;Leader
收到应答之后,统计应答的数量,当满足超过集群半数以上节点,应答接收成功;etcd raft
算法模块构造Ready
结构体,用来通知etcd Server
模块,该日志数据已经被commit
;etcd Server
中的raft
模块(交互图中有标识),收到Ready
消息后,会将这条日志数据写入到WAL
模块中;正式通知
etcd Server
该提案已经被commit
;etcd Server
调用applierV3
模块,将日志写入持久化存储中;etcd Server
应答客户端该数据写入成功;etcd Server
调用etcd raft
库,将这条日志写入到raftLog
模块中的storage
;
上述过程中,提案经过网络转发,当多数 etcd
节点持久化日志数据成功并进行应答,提案的状态会变成已提交。
在应答某条日志数据是否已经 commit
时,为什么 etcd raft
模块首先写入到 WAL
模块中?
这是因为该过程仅仅添加一条日志,一方面开销小,速度会很快;另一方面,如果在后面 applierV3
写入失败,etcd
服务端在重启的时候也可以根据 WAL
模块中的日志数据进行恢复。etcd Server
从 raft
模块获取已提交的日志条目,由 applierV3
模块通过 MVCC
模块执行提案内容,更新状态机。
整个过程中,etcd raft
模块中的 raftLog
数据在内存中存储,在服务重启后失效;客户端请求的数据则被持久化保存到 WAL
和 applierV3
中,不会在重启之后丢失。
参考:
https://kaiwu.lagou.com/course/courseInfo.htm?courseId=613#/detail/pc?id=6403
etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程相关推荐
- 福利模块功能实现及考勤模块准备
为什么80%的码农都做不了架构师?>>> 今天完成了福利模块业务相关功能实现,福利模块主要实现功能有: 福利状态:确定员工缴纳状态和基数 福利计算:福利操作员计算公积金和社保 ...
- python笔记05: 程序结构
程序结构 三大结构 顺序 分支 循环 分支 单路分支 分支的基本语法 if 条件表达式:语句1语句2语句3...... 条件表达式就是计算结果必须为布尔值的表达式 表达式后面的冒号不能少 注意if后面 ...
- python的requests模块功能_python中requests模块的使用方法
本文实例讲述了python中requests模块的使用方法.分享给大家供大家参考.具体分析如下: 在HTTP相关处理中使用python是不必要的麻烦,这包括urllib2模块以巨大的复杂性代价获取综合 ...
- 《大型网站技术架构:核心原理与案例分析》笔记05
<大型网站技术架构:核心原理与案例分析>笔记05 网站的课扩展性架构: 扩展性:指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力.表现在系统基础设施稳定不需要经常变更,应用之间 ...
- 肖然:DDD分层架构的代码结构实战
不同于其它的架构方法,领域驱动设计DDD(Domain Driven Design)提出了从业务设计到代码实现一致性的要求,不再对分析模型和实现模型进行区分.也就是说从代码的结构中我们可以直接理解业务 ...
- 黑马程序员之ASP.NET学习笔记:Http状态代码及其含义
-----------------------------------2345王牌技术员联盟.2345王牌技术员联盟.期待与您交流!---------------------------------- ...
- 系统架构设计模块拆分维度和原则
在我们从零开始做一个新系统的时候,会首先进行系统功能模块架构设计,那么是直接做一个大而全的垂直的MVC系统,使用一个war包进行发布管理,还是需要按一些规则进行模块拆分,设计成SOA或者微服务系统比较 ...
- Python模块和包:导入制作模块、name、模块定位顺序(文件名与模块名重复、功能名与功能名重复、函数名与功能名重复、变量名与模块名重复)、from 模块名 import *__all__列表、包
一.模块 Python 模块(Module),是⼀个 Python ⽂件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块能定义函数,类和变量,模块⾥也能包含可执⾏的代码. ...
- WiFi选型_主设备WiFi模块,从设备WiFi模块功能介绍
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.主设备WiFi模块 主设备WiFi模块功能介绍 二.从设备WiFi模块 从设备WiFi模块功能介绍 前言 在物联网 ...
最新文章
- esxi 6.7 7.0 区别_摩托车国产车和合资车有什么区别?
- javascript如何判断变量的数据类型
- android布局layout,Android布局(FrameLayout、GridLayout)
- Django框架(20.Django的视图函数的request参数以及QueryDict对象)
- python200行代码_如何用200行Python代码“换脸”
- html图片宽度高度等比例绽放,css图片自动绽放大小,左右,上下居中
- 数据结构 - 队列(非环形队列,以及优化成环形队列)
- java kcp,重新认识KCP - osc_rreaoxa0的个人空间 - OSCHINA - 中文开源技术交流社区
- 红橙Darren视频笔记 界面优化与屏幕适配(下)
- Unity,UDK,Unreal Engine4或者CryENGINE——我应该选择哪一个游戏引擎
- 环境配置:Qt5.5+VS2013+OpenCv3.1.0+Win7(64bit)
- (重磅)最快的Hadoop完全分布式运行
- 解决图片三像素的问题
- Qt之QSS(白色靓丽)
- 浏览器怎么置顶_Windows 10 窗口置顶 bug 解决方案汇总
- fatal: empty string is not a valid pathspec, please use . instead if you meant to match all paths
- OpenCV(0)---机器学习库
- Windows下如何正确清理C盘?
- 惠普服务器如何选择光驱启动不了系统,惠普笔记本bios设置光盘启动方法
- 应届生web前端面试题_前端开发应届生面试指南(含各大公司具体指南及面试真题)...
热门文章
- sql特殊字符转义,oracle中将字符 ‘ 转义
- 2022-2028年中国安防行业研究及前瞻分析报告
- 2022-2028年中国自动化设备市场研究及前瞻分析报告
- Git 常用操作(3)- 本地分之显示、创建、切换、合并和删除操作
- 【JavaScript总结】JavaScript语法基础:DOM
- RuntimeError: Assertion cur_target 0 cur_target n_classes failed
- 卷积神经网络(CNN)张量(图像)的尺寸和参数计算(深度学习)
- 全文翻译(四) TVM An Automated End-to-End Optimizing Compiler
- 国内操作系统OS分析(上)
- CVPR2020论文解读:CNN合成的图片鉴别