ETCD系列之三:网络层实现

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
PolarDB Agent Express,2核4GB
RDS Agent(兼容OpenClaw),2核4GB
简介: ETCD系列之三:网络层实现 1. 概述 在理清ETCD的各个模块的实现细节后,方便线上运维,理解各种参数组合的意义。本文先从网络层入手,后续文章会依次介绍各个模块的实现。 本文将着重介绍ETCD服务的网络层实现细节。在目前的实现中,ETCD通过HTTP协议对外提供服务,同样通过HTTP协议实

ETCD系列之三:网络层实现

1. 概述

在理清ETCD的各个模块的实现细节后,方便线上运维,理解各种参数组合的意义。本文先从网络层入手,后续文章会依次介绍各个模块的实现。

本文将着重介绍ETCD服务的网络层实现细节。在目前的实现中,ETCD通过HTTP协议对外提供服务,同样通过HTTP协议实现集群节点间数据交互。

网络层的主要功能是实现了服务器与客户端(能发出HTTP请求的各种程序)消息交互,以及集群内部各节点之间的消息交互。

2. ETCD-SERVER整体架构

ETCD-SERVER 大体上可以分为网络层,Raft模块,复制状态机,存储模块,架构图如图1所示。
thread_local_impl_2_
图1 ETCD-SERVER架构图

  • 网络层:提供网络数据读写功能,监听服务端口,完成集群节点之间数据通信,收发客户端数据;
  • Raft模块:完整实现了Raft协议;
  • 存储模块:KV存储,WAL文件,SNAPSHOT管理
  • 复制状态机:这个是一个抽象的模块,状态机的数据维护在内存中,定期持久化到磁盘,每次写请求会持久化到WAL文件,并根据写请求的内容修改状态机数据。

3. 节点之间网络拓扑结构

ETCD集群的各个节点之间需要通过HTTP协议来传递数据,表现在:

  • Leader 向Follower发送心跳包, Follower向Leader回复消息;
  • Leader向Follower发送日志追加信息;
  • Leader向Follower发送Snapshot数据;
  • Candidate节点发起选举,向其他节点发起投票请求;
  • Follower将收的写操作转发给Leader;

各个节点在任何时候都有可能变成Leader, Follower, Candidate等角色,同时为了减少创建链接开销,ETCD节点在启动之初就创建了和集群其他节点之间的链接。

因此,ETCD集群节点之间的网络拓扑是一个任意2个节点之间均有长链接相互连接的网状结构。如图2所示。
thread_local_impl
图2 ETCD集群节点网络拓扑图

需要注意的是,每一个节点都会创建到其他各个节点之间的长链接。每个节点会向其他节点宣告自己监听的端口,该端口只接受来自其他节点创建链接的请求。

4. 节点之间消息交互

在ETCD实现中,根据不同用途,定义了各种不同的消息类型。各种不同的消息,最终都通过google protocol buffer协议进行封装。这些消息携带的数据大小可能不尽相同。例如 传输SNAPSHOT数据的消息数据量就比较大,甚至超过1GB, 而leader到follower节点之间的心跳消息可能只有几十个字节。

因此,网络层必须能够高效地处理不同数据量的消息。ETCD在实现中,对这些消息采取了分类处理,抽象出了2种类型消息传输通道:Stream类型通道和Pipeline类型通道。这两种消息传输通道都使用HTTP协议传输数据。
thread_local_impl_1_
图3 节点之间建立消息传输通道

集群启动之初,就创建了这两种传输通道,各自特点:

  • Stream类型通道:点到点之间维护HTTP长链接,主要用于传输数据量较小的消息,例如追加日志,心跳等;
  • Pipeline类型通道:点到点之间不维护HTTP长链接,短链接传输数据,用完即关闭。用于传输数据量大的消息,例如snapshot数据。

如果非要做做一个类别的话,Stream就向点与点之间维护了双向传输带,消息打包后,放到传输带上,传到对方,对方将回复消息打包放到反向传输带上;而Pipeline就像拥有N辆汽车,大消息打包放到汽车上,开到对端,然后在回来,最多可以同时发送N个消息。

Stream类型通道
Stream类型通道处理数据量少的消息,例如心跳,日志追加消息。点到点之间只维护1个HTTP长链接,交替向链接中写入数据,读取数据。

Stream 类型通道是节点启动后主动与其他每一个节点建立。Stream类型通道通过Channel 与Raft模块传递消息。每一个Stream类型通道关联2个Goroutines, 其中一个用于建立HTTP链接,并从链接上读取数据, decode成message, 通过Channel传给Raft模块中,另外一个通过Channel 从Raft模块中收取消息,然后写入通道。

具体点,ETCD使用golang的http包实现Stream类型通道:

  • 1)被动发起方监听端口, 并在对应的url上挂载相应的handler(当前请求来领时,handler的ServeHTTP方法会被调用)
  • 2)主动发起方发送HTTP GET请求;
  • 3)监听方的Handler的ServeHTTP访问被调用(框架层传入http.ResponseWriter和http.Request对象),其中http.ResponseWriter对象作为参数传入Writter-Goroutine(就这么称呼吧),该Goroutine的主循环就是将Raft模块传出的message写入到这个responseWriter对象里;http.Request的成员变量Body传入到Reader-Gorouting(就这么称呼吧),该Gorutine的主循环就是不断读取Body上的数据,decode成message 通过Channel传给Raft模块。

Pipeline类型通道
Pipeline类型通道处理数量大消息,例如SNAPSHOT消息。这种类型消息需要和心跳等消息分开处理,否则会阻塞心跳。

Pipeline类型通道也可以传输小数据量的消息,当且仅当Stream类型链接不可用时。

Pipeline类型通道可用并行发出多个消息,维护一组Goroutines, 每一个Goroutines都可向对端发出POST请求(携带数据),收到回复后,链接关闭。

具体地,ETCD使用golang的http包实现的:

  • 1)根据参数配置,启动N个Goroutines;
  • 2)每一个Goroutines的主循环阻塞在消息Channel上,当收到消息后,通过POST请求发出数据,并等待回复。

5. 网络层与Raft模块之间的交互

在ETCD中,Raft协议被抽象为Raft模块。按照Raft协议,节点之间需要交互数据。在ETCD中,通过Raft模块中抽象的RaftNode拥有一个message box, RaftNode将各种类型消息放入到messagebox中,有专门Goroutine将box里的消息写入管道,而管道的另外一端就链接在网络层的不同类型的传输通道上,有专门的Goroutine在等待(select)。

而网络层收到的消息,也通过管道传给RaftNode。RaftNode中有专门的Goroutine在等待消息。

也就是说,网络层与Raft模块之间通过Golang Channel完成数据通信。这个比较容易理解。

6 ETCD-SERVER处理请求(与客户端的信息交互)

在ETCD-SERVER启动之初,会监听服务端口,当服务端口收到请求后,解析出message后,通过管道传入给Raft模块,当Raft模块按照Raft协议完成操作后,回复该请求(或者请求超时关闭了)。

7 主要数据结构

网络层抽象为Transport类,该类完成网络数据收发。对Raft模块提供Send/SendSnapshot接口,提供数据读写的Channel,对外监听指定端口。

thread_local_impl_3_

8. 结束

本文整理了ETCD节点网络层的实现,为分析其他模块打下基础。

目录
相关文章
|
运维
ETCD系列之一:简介
本文介绍etcd使用场景,工作原理。
77873 160
|
存储 关系型数据库 数据库
用Patroni配置PostgreSQL高可用集群
Patroni是Zalando开发的数据库高可用管理软件,用于编排和自动化PostgreSQL集群的管理过程。Patroni 需要一系列其他组件的支持,通过利用第三方分布式一致性软件,组建并实现数据库高可用方案。
用Patroni配置PostgreSQL高可用集群
|
机器学习/深度学习 编解码 计算机视觉
【APFN】从大佬论文中探索如何分析改进金字塔网络
【APFN】从大佬论文中探索如何分析改进金字塔网络
568 0
|
SQL 关系型数据库 分布式数据库
Communications link failure
Communications link failure
1086 1
|
关系型数据库 MySQL
pt-table-checksum原理详解
环境 MySQL: MySQL 5.6.27 OS: centos 6.6 tool: pt-table-checksum 2.2.15 它能做什么 业界最流行的MySQL主从数据对比工具,数据一致性检测最好的的工具,没有之一 如何使用 ./pt-table-che
7970 0
|
人工智能 运维 关系型数据库
|
人工智能 运维 关系型数据库
云服务API与MCP深度集成,RDS MCP最佳实践
近日,阿里云数据库RDS发布开源RDS MCP Server,将复杂的技术操作转化为自然语言交互,实现"对话即运维"的流畅体验。通过将RDS OpenAPI能力封装为MCP协议工具,用户只需像聊天一样描述需求,即可完成数据库实例创建、性能调优、故障排查等专业操作。本文介绍了RDS MCP(Model Context Protocol)的最佳实践及其应用,0代码,两步即可轻松完成RDS实例选型与创建,快来体验!
云服务API与MCP深度集成,RDS MCP最佳实践
|
11月前
|
文字识别 监控 Java
顺丰同城抢单辅助脚本,顺丰骑士抢单辅助免封号,自动抢单神器【java版开源】
这是一套OCR实时检测订单列表并自动右滑的完整代码方案,适用于学习研究。代码包含四个主要模块:OCR处理(文字识别)、价格分析
|
NoSQL 关系型数据库 MySQL
Redis私有云平台-Cachecloud安装和部署手册
Redis私有云平台-Cachecloud安装和部署手册
|
存储 Prometheus NoSQL
Redis 内存突增时,如何定量分析其内存使用情况
【9月更文挑战第21天】当Redis内存突增时,可采用多种方法分析内存使用情况:1)使用`INFO memory`命令查看详细内存信息;2)借助`redis-cli --bigkeys`和RMA工具定位大键;3)利用Prometheus和Grafana监控内存变化;4)优化数据类型和存储结构;5)检查并调整内存碎片率。通过这些方法,可有效定位并解决内存问题,保障Redis稳定运行。
1241 4