go语言 | etcd源码导读(一)

参考

本文参考https://zhuanlan.zhihu.com/p/600893553
https://www.topgoer.com/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C/go%E6%93%8D%E4%BD%9Cetcd/etcd%E4%BB%8B%E7%BB%8D.html


前沿etcd 与 raft

etcd是使用Go语言开发的一个开源的、高可用的分布式key-value存储系统,可以用于配置共享和服务的注册和发现。

类似项目有zookeeper和consul。

etcd具有以下特点:

  • 完全复制:集群中的每个节点都可以使用完整的存档
  • 高可用性:Etcd可用于避免硬件的单点故障或网络问题
  • 一致性:每次读取都会返回跨多主机的最新写入
  • 简单:包括一个定义良好、面向用户的API(gRPC)
  • 安全:实现了带有可选的客户端证书身份验证的自动化TLS
  • 快速:每秒10000次写入的基准速度
  • 可靠:使用Raft算法实现了强一致、高可用的服务存储目录

etcd 基于 golang 编写,github 开源地址:https://github.com/etcd-io/etcd . 本文走读的源码版本为 tag: v3.1.10.

在这里插入图片描述
etcd 中关于 raft 算法的实现具有很高的还原性,项目中与 raft 有关的代码主要位于:

模块目录
raft 算法层./raft/*
raft 应用层示例./contrib/raftexample/*
raft 数据结构定义./raft/raftpb

在这里插入图片描述


etcd应用场景

服务发现

服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 udp 或 tcp 端口,并且通过名字就可以查找和连接。

在这里插入图片描述

配置中心

将一些配置信息放到 etcd 上进行集中管理。

这类场景的使用方式通常是这样:应用在启动的时候主动从 etcd 获取一次配置信息,同时,在 etcd 节点上注册一个 Watcher 并等待,以后每次配置有更新的时候,etcd 都会实时通知订阅者,以此达到获取最新配置信息的目的。

分布式锁

因为 etcd 使用 Raft 算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。

  • 保持独占即所有获取锁的用户最终只有一个可以得到。etcd 为此提供了一套实现分布式锁原子操作 CAS(CompareAndSwap)的 API。通过设置prevExist值,可以保证在多个节点同时去创建某个目录时,只有一个成功。而创建成功的用户就可以认为是获得了锁。
  • 控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd 为此也提供了一套 API(自动创建有序键),对一个目录建值时指定为POST动作,这样 etcd 会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用 API 按顺序列出所有当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值可以是代表客户端的编号。

在这里插入图片描述

为什么用 etcd 而不用ZooKeeper?

etcd 实现的这些功能,ZooKeeper都能实现。那么为什么要用 etcd 而非直接使用ZooKeeper呢?

为什么不选择ZooKeeper?

  • 部署维护复杂,其使用的Paxos强一致性算法复杂难懂。官方只提供了Java和C两种语言的接口。
  • 使用Java编写引入大量的依赖。运维人员维护起来比较麻烦。
  • 最近几年发展缓慢,不如etcd和consul等后起之秀。

为什么选择etcd?

  • 简单。使用 Go 语言编写部署简单;支持HTTP/JSON API,使用简单;使用 Raft 算法保证强一致性让用户易于理解。
  • etcd 默认数据一更新就进行持久化。
  • etcd 支持 SSL 客户端安全认证。
    最后,etcd 作为一个年轻的项目,正在高速迭代和开发中,这既是一个优点,也是一个缺点。优点是它的未来具有无限的可能性,缺点是无法得到大项目长时间使用的检验。然而,目前 CoreOS、Kubernetes和CloudFoundry等知名项目均在生产环境中使用了etcd,所以总的来说,etcd值得你去尝试。

术语表

中文名英文名说明
算法层algorithm module内聚了 raft 共识机制的核心模块.代码层面以 sdk 的形式被应用层引入,启动时以独立 goroutine 的形式存在,与应用层通过 channel 通信.
应用层application module聚合了 etcd 存储、通信能力的模块.启动时是 raft 节点的主 goroutine,既要负责与客户端通信,又要负责和算法层交互,承上启下.
算法层节点Node/node是 raft 节点在算法层中的抽象,也是应用层与算法层交互的唯一入口.
应用层节点raftNode是 raft 节点在应用层中的抽象,内部持有算法层节点 Node 的引用,同时提供处理客户端请求以及与集群内其他节点通信的能力.
通信模块transportetcd 中的网络通信模块,为 raft 节点间通信提供服务.
提议proposal两阶段提交中的第一阶段:提议.
提交commit两阶段提交中的第二阶段:提交.
应用apply将已提交的日志应用到数据状态机,使得写请求真正生效.
数据状态机data state machineraft 节点用于存储数据的介质. 为避免与 raft 节点状态机产生歧义,统一命名为数据状态机.
节点状态机node state machineetcd 实现中,raft 节点本质是个大的状态机. 任何操作如选举、提交数据等,最后都会封装成一则消息输入节点状态机中,驱动节点状态发生变化.

宏观架构梳理

算法层

算法层是 raft 算法的核心实现模块,负责根据共识机制进行请求内容的正确性校验,预写日志状态的维护和管理,可提交日志的进度推进.

简单来看,算法层本质上类似于一台“拼图机器”. 我们把输入的日志比喻成一块块“拼图碎片”,提交拼图碎片的应用层则像个捣蛋的小孩,他将拼图顺序打乱并在其中掺入一些错误的碎片,然后依次将“碎片”提交给拼图机器(算法层).

拼图机器(算法层)则依照对图案轮廓的把握和碎片纹理的观察(raft 共识机制),依次纠正碎片的顺序和内容之后进行归还.

在这个比喻中,算法层可以被视为一台高效且精准的“拼图机器”,专门负责处理和组装日志数据,这些数据类似于一系列的拼图碎片。这台机器的核心是基于 raft 共识机制,一个复杂而强大的算法,设计用来确保分布式系统中数据的一致性和可靠性。当应用层(象征着一个调皮的小孩)生成和提交日志时,它可能会不按顺序提交,甚至夹杂一些错误或无效的数据碎片。这种无序和错误的数据代表了分布式系统中的节点可能出现的不一致或故障情况。

算法层的工作就是要从这些混乱和可能错误的输入中恢复出正确和有序的数据。通过对每个“碎片”(即日志条目)的内容进行仔细的审查和比对,算法层根据 raft 协议的规则来决定哪些碎片是有效的,哪些应该被丢弃或修正。它通过投票和日志复制机制确保所有节点上的数据保持一致。每个节点的算法层都会参与这个过程,从而确保整个系统在面对网络分区、节点故障等问题时仍能保持数据的一致性和完整性。

此外,算法层还需要管理数据碎片的正确顺序。在分布式系统中,维持操作的顺序是至关重要的,因为这直接影响到系统状态的正确性。算法层通过维护一个严格的日志序列,确保所有操作都按照一定的顺序执行。这就像是在解决拼图时,需要找到正确的碎片,并按照特定的顺序将它们放到恰当的位置。

总而言之,算法层(拼图机器)在这个系统中扮演了核心角色,负责处理来自应用层(捣蛋小孩)的混乱和不完整的输入,通过 raft 协议的精妙设计,它能够高效地校正和组织这些数据,最终形成一个完整且一致的数据结构,保证整个系统的稳定运行和数据的准确性。

在这里插入图片描述

应用层

在 etcd 的实现中,算法层只聚焦于 raft 共识机制部分的内容,其中涉及网络通信、预写日志持久化、数据状态机管理的工作均在应用层进行实现;

应用层是 raft 节点中承上启下的主干模块,既扮演了与外部客户端通信的服务端角色,也是下层算法库的使用者,还要负责与各模块交互,串联 raft 节点运行的整体流程.

由于本文探讨的重点集中 raft 共识机制部分,因此应用层不是我们所研究的重点,更多的笔墨会集中在算法层的内容中.

宏观架构

在这里插入图片描述
etcd 在实现 raft 时,将内容依据职责边界拆分为应用层和算法层两个模块,在引用关系上,算法层是一个被应用层引用的静态库,但在节点启动时,最终应用层和算法层的内容会内聚于两个独立的 goroutine 当中,依据几个 channel 进行模块间的异步通信,两个模块的核心职责点展示如上图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/203052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android--Jetpack--Databinding详解

不经一番寒彻骨,怎得梅花扑鼻香 一,定义 DataBinding, 又名数据绑定,是Android开发中非常重要的基础技术,它可以将UI组件和数据模型连接起来,使得在数据模型发生变化时,UI组件自动更新。是 MVVM 模式在 An…

Linux-centos上如何配置管理NFS服务器?

Linux/centos上如何配置管理NFS服务器? 1 NFS基础了解 NFS(Network File System)即文件操作系统;NFS允许网络中不同计算机相互之间共享资源。 1.1 NFS概述 1980年由SUN发展出来的在UNIX&Linux系统间实现文件共享的一种方法…

计算机组成原理-数据寻址-(相对寻址 基址寻址 变址寻址 )

文章目录 指令寻址vs数据寻址总览偏移寻址基址寻址基址寻址的作用变址寻址变址寻址的作用基址&变址复合寻址相对寻址相对寻址的作用 总结硬件如何实现数的比较 指令寻址vs数据寻址 总览 偏移寻址 变址寄存器:IX 基址寄存器:BR 基址寻址 没有基址…

YashanDB练习SQL

查询当前实例的信息: SELECT * FROM v$instance;查询数据库的信息: SELECT * FROM v$database;查询数据库名称: SELECT database_name FROM v$database;创建用户sales并授予DBA角色: CREATE USER sales IDENTIFIED BY "S…

【Flink on k8s】- 7 - 在本地运行第一个 flink wordcount job

目录 1、环境准备 2、代码开发 3、启动运行 4、在控制台找到 web ui,查看监控

Pair<T, U>

Pair<T, U> 表示一个包含两个元素的有序对&#xff08;pair&#xff09;。这是一种泛型类型&#xff0c;其中 T 和 U 分别表示有序对中第一个和第二个元素的类型。通常&#xff0c;Pair 类型用于表示两个相关联的值&#xff0c;例如一对坐标、一对键值等。 在 TypeScrip…

Django大回顾 - 9 Auth模块的使用、缓存

【1】Auth模块 auth就是django 的一个app&#xff0c;做用户管理。 Django作为一个完美主义者的终极框架&#xff0c;当然也会想到用户的这些痛点。它内置了强大的用户认证系统–auth&#xff0c;它默认使用 auth_user 表来存储用户数据 默认的用户表示auth_user # 创建一个用…

GitHub工业级开源软件:基于网络的过程可视化(SCADA/HMI/仪表板)

GitHub工业级开源软件:基于网络的过程可视化(SCADA/HMI/仪表板)  作者:本站编辑  2023-11-25 06:52:35  117 大家好,我是 Fun-Fun君,每天介绍github上最有价值的开源项目 今天介绍 FUXA 基于网络的过程可视化(SCADA/HMI/仪表板)软件 github地址:…

ChatGPT能帮助--掌握各种AI绘图工具,随意生成各类型性图像

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

Camunda 7.x 系列【60】流程分类

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 案例演示2.1 后端2.2 前端2.3 测试1. 前言 钉钉中的OA审批分类: 企业级的业务…

UDP多人群聊

一.创建类 二.类 1.Liao类 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.IOException; import java.lang.String;public class Liao extends JFrame{private static final int DEFAULT_PORT8899;private JLabel st…

QT使用http通信的同步和异步

在Qt与Http通信的时候&#xff0c;会根据不同的情况使用同步或者异步的方式进行数据请求。 同步&#xff0c;即发送Http请求之后&#xff0c;会一直等待服务器返回的数据&#xff0c;接收到数据之前&#xff0c;程序一直阻塞。 异步&#xff0c;即发送Http请求之后&#xff0…

【musl-pwn】msul-pwn 刷题记录 -- musl libc 1.2.2

前言 本文不分析 musl libc 相关源码&#xff0c;仅仅为刷题记录&#xff0c;请读者自行学习相关知识&#xff08;看看源码就行了&#xff0c;代码量也不大&#xff09; starCTF2022_babynote 保护&#xff1a;保护全开 程序与漏洞分析&#xff1a; 程序实现了一个菜单堆&…

自适应局部降噪滤波器的python实现-------冈萨雷斯数字图像处理

自适应局部降噪滤波器 自适应局部降噪滤波器是一种信号处理技术&#xff0c;用于降低图像或信号中的噪声水平&#xff0c;同时保留图像或信号的细节。其原理基于局部区域内信号的统计特性和噪声的特征&#xff0c;通过动态调整滤波器的参数来适应不同区域的信号和噪声属性。 自…

Mac系统升级node.js版本和npm版本

升级node.js版本 第一步&#xff1a;查询当前node.js版本 node -v 第二步&#xff1a;清除node.js的缓存 sudo npm cache clean -f 第三步&#xff1a;验证缓存是否清空 npm cache verify 第四步&#xff1a;安装n工具&#xff0c;n工具是专门用于管理node.js版本的工具…

Day52力扣打卡

打卡记录 Collapsing Strings&#xff08;Trie树&#xff09; 链接 #include <iostream> #include <algorithm> using namespace std; const int N 2e6 10; int son[N][26], idx, cnt1[N], cnt2[N]; int main() {auto insert [&](string& str, int* c…

【Qt】在表格QTableWidget或者QTableView中,当主键Id存在时更新数据,不存在时添加数据解决方案

问题 有时在开发中&#xff0c;表格需要显示数据&#xff0c;每一行呢&#xff0c;需要记录对应的id。 当更新表格数据时&#xff0c;会根据id进行更新&#xff0c;id存在就更新行数据&#xff0c;不存在就添加一行新数据。 解决方案 如何知道id存在还是不存在呢&#xff1f…

记一次CDH集群迁移产生的问题——HIVE

背景 生产环境CDH集群迁移到新的环境&#xff0c;迁移之后使用Hive Client方执行任务一直失败。 问题1&#xff1a;metadata.SessionHiveMetaStoreClient 产生报错&#xff1a; FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.Ru…

AOP操作日志记录

AOP操作日志记录 1.创建注解 Retention(RetentionPolicy.RUNTIME) Target(ElementType.METHOD) public interface PassportLog {String operatePage();String operateType();ClassTypEnum classType();}2.创建切面 对于字典&#xff0c;可以通过注解属性去转换&#xff0c;枚举…

车联网架构设计(二)_消息缓存

在上一篇博客车联网架构设计(一)_消息平台的搭建-CSDN博客中&#xff0c;我介绍了车联网平台需要实现的一些功能&#xff0c;并介绍了如何用EMQXHAPROXY来搭建一个MQTT消息平台。车联网平台的应用需要消费车辆发布的消息&#xff0c;同时也会下发消息给车辆&#xff0c;以实现车…