8.3.1 注册服务中心Etcd

etcd是什么

etcd 是一个分布式键值对存储,设计用来可靠而快速的保存关键数据并提供访问。通过分布式锁, leader选举保障可靠的分布式协同。

etcd 特点

  1. 完全复制,集群中的每个节点均拥有全量数据

  2. 强一致性,etcd通过raft共识算法保证集群数据的一致性

  3. 数据结构简单,仅字符串格式

  4. 可存储的数据量较少

  5. 每个节点支持1000次/秒的写操作,2000次/秒的读操作

使用场景

  1. 服务注册与服务发现

  2. 分布式配置中心

  3. 分布式锁

  4. 分布式选主

  5. 读多写少的场景

架构图

  1. Leader:Raft算法中通过竞选而产生的处理所有数据提交的节点

  2. Follower:竞选失败的节点作为Raft中的从属节点,为算法提供强一致性保证

  3. Candidate:当Follower超过一定时间接收不到Leader的心跳时转变为Candidate开始竞选

  4. Learner:etcd集群中的只读节点,拥有全量数据,不参与Leader的竞选

  5. BoltDB:一个支持事务的KV存储引擎,用于对ETCD数据的持久化,支持并发读事务,串行写事务

  6. WAL 预写式日志:etcd中的数据提交都会先记录到日志,日志成功后才会做数据持久化

  7. Snapshot,快照:防止WAL日志过多,用于存储某一时刻etcd的所有数据,可用于节点故障恢复

  8. gRPC Server:节点与节点,节点与客户端通过gRPC 通信和信息同步,每个节点都是一个gRPC 服 务器

  9. Raft:共识算法,etcd数据强一致性的保障

  10. Client:etcd客户端,可以是命令行客户端 etcdctl ,也可以是各个语言版本的client库,可通过 grpc与http与server端通信

基本原理

MVCC(多版本并发控制)

  1. 作用

MVCC即在对数据修改时,不是去改变数据的值,而是新增一条数据记录,数据的版本号递增1。在读取 数据时实际上是读取到当前版本的数据记录。MVCC旨在提高数据库的并发性能,更好的解决读写之间的 冲突,从而实现读写冲突的情况下,不加锁并发读。

  1. 数据版本号:

revision:etcd键空间版本号,key发生变更,则revision加1;全局单调递增,64bits

create_revision: 创建数据时,对应的revision

mod_revision: 数据修改时,对应的revision

version: 表示当前key被修改的次数

分布式锁

  1. 锁的持有者为:前缀为 mymutex 且创建时间最早的key,即根据create version 正序第一个key值

  2. etcd中任何数据变化都会导致全局的revision发生递增

  3. 客户端向etcd发送事务,事务内容:1.向etcd添加当前客户端的键值对,并获得结果;2.向etcd中 获取目前的锁持有者。

  4. 如果不存在锁持有者,则自身即为持有者;如果锁持有者的create version 等于当前自身的create version则自身即为持有者

  5. 如果自身不是持有者,则监听前缀为 mymutex 且 create version 比自身小一个版本号的key的删除事件,一旦删除,则自身获取到锁

数据写流程

  1. 只有leader节点能处理写流程,当follower节点收到写请求后会转发到leader

  2. 将请求提案广播到各个follower节点,并记录WAL,当大多数节点成功记录WAL之后,该请求提案 的状态将变成已提交状态。

  3. 由各个节点根据WAL应用数据,对数据进行持久化

  4. 响应写请求,返回处理结果

读流程

线性读:

  1. etcd 默认读模式是线性读,在延时和吞吐量上相比串行读略差一点,适用于对数据一致性要求高的场景。

  2. 当收到一个线性读请求时,首先会从 Leader 获取集群最新的已提交的日志索引。

  3. Leader 收到 ReadIndex 请求时,为防止脑裂等异常场景,会向 Follower 节点发送心跳确认,一半 以上节点确认 Leader 身份后才能将已提交的索引 (committed index) 返回给节点。

  4. 节点则会等待,直到状态机已应用索引 (applied index) 大于等于 Leader 的已提交索引时 (committed Index),然后去通知读请求。

串行读:

节点数据返回、无需通过 Raft 协议与集群进行交互。它具有低延时、高吞吐量的特点,适合对数据 一致性要求不高的场景

ETCD选项说明

  1. etcd 集群运行时会同时监听2个端口,一个是客户端端口(如:2379)用于给客户端连接,一个是 集群成员之间(或伙伴,或 peer)通讯的端口(如:2380)。

  2. etcd 集群配置的参数名称有一定规则,一般 --initial 前缀标记用于静态部署时启动集群,-- discovery 前缀标记在使用发现服务的方式启动集群

  3. etcd 集群的安全从两个方面维护,一个是服务端集群成员(peer)之间通信使用 TLS 安全认证, 另一个是客户端(etcdctl)访问 etcd 集群使用 TLS 安全认证。

  4. TLS 安全认证有一下几个文件组成

  • CA 证书:ca-file

  • 私钥文件: key-file

  • 证书文件: cert-file

  • 证书吊销列表: crl-file

etcdctl命令行

注意事项

1、容器化部署后,需要通过docker exec 在容器中执行命令,使用容器内部的etcdctl命令行客户端

# 通过docker exec 在容器内部执行命令 
docker exec etcd0 /usr/local/bin/etcdctl put key1 value1

2、etcdctl 默认访问当前节点2379端口,如果当前节点的etcd服务没有监听2379端口,那么需要指定- -endpoints,可以指定某一个节点,或者集群所有节点

# etcdctl客户端访问监听了默认端口的节点 
docker exec etcd0 /usr/local/bin/etcdctl put key1 value1 
# etcdctl客户端访问某一个节点 
docker exec etcd1 /usr/local/bin/etcdctl put key1 value1 -- endpoints=192.168.239.149:22379 
# etcdctl客户端访问集群,指定所有节点列表 
docker exec etcd1 /usr/local/bin/etcdctl put key1 value1 --endpoints= [192.168.239.149:2379,192.168.239.149:12379,192.168.239.149:22379] 

3、容器化部署后,需要与终端保持连接的命令需要启用docker 虚拟终端交互(指定 -it 选项),例 如:lock、elect、txn等

# 分布式锁,需要再多个终端执行 
docker exec -it etcd0 /usr/local/bin/etcdctl lock mutex1 # 分布式选主,需要在多个终端推选不同的候选人 
docker exec -it etcd0 /usr/local/bin/etcdctl elect myelect node1 
docker exec -it etcd0 /usr/local/bin/etcdctl elect myelect node2 
docker exec -it etcd0 /usr/local/bin/etcdctl elect myelect node3

全局参数

--cacert="" #验证启用TLS的安全服务器的证书 
--cert="" # TLS证书文件 --command-timeout=5s # 运行命令超时时间 
--debug[=false] # 启用客户端调试日志记录 
--dial-timeout=2s # 客户端连接的拨号超时 
-d, --discovery-srv="" # 用于查询描述群集端点的SRV记录的域名 
--discovery-srv-name="" # 使用DNS发现时要查询的服务名称 
--endpoints=[127.0.0.1:2379] # gRPC 端点 
--hex[=false] # 将字节字符串打印为十六进制编码字符串 
--insecure-discovery[=true] # 接受描述群集端点的不安全SRV记录 
--insecure-skip-tls-verify[=false] # 跳过服务器证书验证(注意:此选项应仅用于测试目的) 
--insecure-transport[=true] # 禁用客户端连接的传输安全 
--keepalive-time=2s # 客户端连接的保持生存时间 
--keepalive-timeout=6s # 客户端连接的保持活动超时
--key="" # TLS密钥文件 
--password="" # 密码 
--user="" # 用户名 
-w, --write-out="simple" #设置输出格式 (fields, json, protobuf, simple, table) 

数据操作

put/get/del(数据读写)

put #将给定的key写入到存储 --ignore-lease[=false] #使用当前租约更新key --ignore-value[=false] #使用当前值更新key --lease="0" # 要附加到key的租约ID(十六进制) --prev-kv[=false] # 返回修改前的上一个键值对 
del #删除指定的键或键范围 --from-key[=false] # 删除大于等于给定key的所有key(按byte值比较) --prefix[=false] # 按前缀匹配删除 --prev-kv[=false] # 删除后是否返回被删除的键值对 
get #获取给定key或给定范围的key --consistency="l" # 'l' 代表线性读(执行raft), 's' 代表串行化读 --count-only[=false] # 仅获取计数 --from-key[=false] #使用byte值比较获取大于或等于给定键的键,类似*key*,但不等于 --keys-only[=false] # 仅获取key --limit=0 #最大结果数 --order="" #结果排序,ASCEND 或 DESCEND (默认 ASCEND) --prefix[=false] # 获取具有匹配前缀的key,key* --print-value-only[=false] #用“simple”输出格式时仅打印值 --rev=0 #指定kv版本 --sort-by="" # 指定排序字段,CREATE, KEY, MODIFY, VALUE, or VERSION

示例:

docker exec etcd0 /usr/local/bin/etcdctl put key1 value1 
docker exec etcd0 /usr/local/bin/etcdctl put key2 value2 
docker exec etcd0 /usr/local/bin/etcdctl put key3 value2 # 根据指定key获取 
docker exec etcd0 /usr/local/bin/etcdctl get key1 
# 根据前缀获取 docker 
exec etcd0 /usr/local/bin/etcdctl get key --prefix docker exec etcd0 /usr/local/bin/etcdctl put a valuea 
docker exec etcd0 /usr/local/bin/etcdctl put b valueb 
docker exec etcd0 /usr/local/bin/etcdctl put c valuec # 根据key值byte值比较,获取大于等于指定key值的所有key 
docker exec etcd0 /usr/local/bin/etcdctl get b --from-key

lease(租约)

lease grant # 创建租约 
lease keep-alive # 开启线程,自动续约 --once[=false] # 仅续约一次 lease list #列出所有活动的租约 
lease revoke #撤销租约 
lease timetolive # 获取租约信息 --keys[=false] #获取附加到此租约的key 

示例:

# 创建租约,有效时长20s 
docker exec etcd0 /usr/local/bin/etcdctl lease grant 20 
# 获取租约列表 
docker exec etcd0 /usr/local/bin/etcdctl lease list 
# 根据leaseID 撤销租约 
docker exec etcd0 /usr/local/bin/etcdctl lease revoke 694d869b526b302a 
# 查询指定租约的有效时长信息 
docker exec etcd0 /usr/local/bin/etcdctl lease timetolive 694d869b526b30c0 
# 开启线程为指定租约自动续租 
docker exec etcd0 /usr/local/bin/etcdctl lease keep-alive 694d869b526b30c2 

lock(锁)

lock # 获取命名锁 --ttl=10 #session 超时时间 

示例:

# 分布式锁,需要再多个终端执行 
# 终端1 
docker exec -it etcd0 /usr/local/bin/etcdctl lock mutex1 
# 终端2 
docker exec -it etcd0 /usr/local/bin/etcdctl lock mutex1

elect (选举)

选举逻辑与锁逻辑类似,前一个leader卸任之后,后续竞选者才能选出新的leader

elect #观察并参与领导人选举 -l, --listen[=false] # 观察模式

txn(事务)

txn # 在一个事务中处理所有请求 -i, --interactive[=false] # 交互模式下的输入事务

事务API由 if 语句、then语句、else语句组成。基本逻辑:在 If 语句中,可以添加一系列的条件表达式, 若条件表达式全部通过检查,则执行 Then 语句的 get/put/delete 等操作,否则执行 Else 的 get/put/delete 等操作,支持比较运算符 (>、<、=、!=)

if语句支持项:

  1. key 的最近一次修改版本号 mod_revision,简称 mod,可以用于检查 key 最近一次被修改时的版 本号是否符合你的预期。例如:mod("key1") = "111902",检查key1最近一次修改版本号是否等于 111902

  2. key 的创建版本号 create_revision,简称 create,可以用于检测 key 是否已存在。例如: create("key") = "0",来判断key1是否存在,不存在的话 create_revision 版本号就是0。

  3. key 的修改次数 version;可以用于检查 key 的修改次数是否符合预期。例如:version("key1") > "3",来判断key1的修改次数是否大于3次

  4. key 的值,可以用于检查 key 的 value 值是否符合预期。例如:value("key1") = "value1",来判断 key1 的值是否等于 value1

watch(事件监听)

watch #监听键值或前缀的事件流 -i, --interactive[=false] # 交互式模式 --prefix[=false] # 监听前缀 --prev-kv[=false] # 获取事件发生前的上一个键值对 --progress-notify[=false] # 从服务器获取定期监视进度通知 --rev=0 # 从指定版本开始监听 
# 终端1-监听key2 
docker exec etcd0 /usr/local/bin/etcdctl watch key2 
# 终端2-对key2做操作 
docker exec etcd0 /usr/local/bin/etcdctl put key2 value3 
docker exec etcd0 /usr/local/bin/etcdctl put key2 value4 
docker exec etcd0 /usr/local/bin/etcdctl del key2 

参考连接:https://github.com/0voice

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

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

相关文章

异或循环冗余

异或代码CRC8-ITU例程比较计算CRC16异或改进测试重点代码 def fun_crc(datas):crc 0xFF poly 0x07 for i in range(len(datas)):for j in range(7, -1, -1):if (crc & 0x80) 0x80: crc (crc << 1) ^ polyelse:crc (crc << 1)if (datas[i] & 2**j):#值…

一款轻量、免费、无广告,强大的演示工具,支持屏幕放大、涂鸦、截图、录屏

软件介绍 ZoomIt&#xff0c;是一款轻量、免费、无广告&#xff0c;强大的演示工具&#xff0c;支持屏幕放大、涂鸦、截图、录屏等。在系统托盘中不显示的运行&#xff0c;可自定义快捷键&#xff0c;使用方面。 软件基础功能 屏幕放大&#xff1a;按下快捷键“Ctrl1”可进入…

从街亭失守看管理

最近看了《三国演义》&#xff0c;重温了街亭失守事件&#xff0c;从马谡最耀眼的登场来看就是&#xff0c;火烧藤甲兵计策和诸葛亮不谋而合&#xff0c;说明马谡确实是有真材实料的&#xff0c;但在守街亭的任务上&#xff0c;诸葛亮也踌躇过又对先帝的遗言“马谡不可重用”记…

全面解析 URL 重定向原理:从协议、实现到安全实践

一、什么是 URL 重定向&#xff1f; URL 重定向&#xff08;URL Redirection&#xff09;是 Web 技术中一种将用户请求的 URL 自动转向另一个目标 URL 的机制。用户可能完全不会察觉跳转发生&#xff0c;因为浏览器在幕后完成了一切。 重定向通常用于以下场景&#xff1a; 网…

多任务 Transformer 模型的高效任务间注意力

抽象 在计算机视觉和更广泛的深度学习领域&#xff0c;Transformer 架构已被公认为许多应用程序的最先进技术。然而&#xff0c;对于多任务学习&#xff0c;与单任务模型相比&#xff0c;可能需要更多的查询&#xff0c;考虑到实际的硬件限制&#xff0c;它的多头注意力通常接近…

QT的常用控件说明

文章目录基本的代码的模板Label控件font字体相关Button 控件CheckBox 控件Radio控件ComboBox控件LineEdit 控件基本的代码的模板 class MainWindow(QWidget):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs) # 调用父类初始化方法# 声明窗口实例# 代…

5Python异常处理与模块导入全指南

目录 什么是异常&#xff1f; 异常的捕获方法&#xff1a; 为什么要捕获异常&#xff1f; 捕获异常的语法&#xff1a; 异常的else和finally语法&#xff1a; 什么是异常&#xff1f; 异常就是程序运行过程中出现了错误&#xff0c;也就是我们常说的出bug了-。- 异常的捕…

区块链密码学简介

区块链密码学简介 一、对称密码算法 概述 对称密码算法的主要特点是使用相同的密钥进行加密和解密。这类算法根据其加密方式大致可以分为两类:流密码和分组密码。区块链技术主要采用分组密码。流密码以数据流的形式逐位或逐字节加密,而分组密码则将数据分成固定大小的块进行…

GridKernalGateway

GridKernalGateway 是 Apache Ignite 架构中一个关键的安全与状态管理组件&#xff0c;它的作用是 “在公共 API 和内部内核&#xff08;kernal&#xff09;之间建立安全、可控的访问通道”。 我们可以把它理解为一个 “门卫 状态哨兵”&#xff0c;确保外部调用不会在 Ignite…

MySQL索引、B+树相关知识总结

MySQL索引、B树相关知识汇总一、有一个查询需求&#xff0c;MySQL中有两个表&#xff0c;一个表1000W数据&#xff0c;另一个表只有几千数据&#xff0c;要做一个关联查询&#xff0c;如何优化&#xff1f;1、为关联字段建立索引2、小表驱动大表二、b树和b树的区别1、更高的查询…

Java学习进阶 -- 泛型的继承和通配符及综合练习

首先&#xff0c;泛型不具备继承性&#xff0c;但是数据具备继承性1.核心概念解析泛型不具备继承性即使类型A是类型B的子类&#xff0c;Generic<A>也不是Generic<B>的子类这是Java泛型的类型安全设计&#xff0c;防止不安全的类型转换数据具备继承性泛型容器中的元…

如何实现在多跳UDP传输场景,保证单文件和多文件完整传输的成功率?

如何实现在多跳UDP传输场景&#xff0c;保证单文件和多文件完整传输的成功率&#xff1f; 一、前言 UDP&#xff08;User Datagram Protocol&#xff09;是一个轻量、无连接的传输协议&#xff0c;广泛用于低延迟、高吞吐的应用中&#xff0c;如视频流、实时游戏等。然而&…

【Spring IoC 核心实现类详解:DefaultListableBeanFactory】

Spring IoC 核心实现类详解&#xff08;源码原理&#xff09;作为 Spring 的灵魂&#xff0c;IoC 容器&#xff08;Inversion of Control&#xff09;是整个框架的核心。 那么 IoC 的“心脏”到底是哪个类&#xff1f;它是怎么管理和装配 Bean 的&#xff1f;本文将从源码层面深…

为什么开启JWT全局认证后,CSRF失败会消失?

这是因为 JWT认证与CSRF校验的设计逻辑完全不同&#xff0c;当全局启用JWT认证后&#xff0c;Django的CSRF校验会被“绕过”或不再生效&#xff0c;具体原因如下&#xff1a; 核心原因&#xff1a;JWT认证不依赖Cookie&#xff0c;无需CSRF保护 1. CSRF的作用场景 CSRF攻击的前…

宝龙地产债务化解解决方案二:基于资产代币化与轻资产转型的战略重构

一、行业背景与代币化创新趋势1.1 房地产债务危机现状宝龙地产&#xff08;01238.HK&#xff09;截至2024年中债务总额达584亿元&#xff0c;其中50.7%为一年内到期债务&#xff0c;但现金储备仅89.47亿元&#xff0c;短期偿债覆盖率不足30%。2025年2月境外债务重组计划因债权人…

深信服GO面试题及参考答案(下)

Kubernetes 与容器 Kubernetes(简称 K8s)是容器编排平台,而容器是轻量级的虚拟化技术,两者紧密关联但定位不同,容器是 K8s 管理的核心对象,K8s 为容器提供了完整的生命周期管理、扩展和运维能力。 容器技术(如 Docker)通过 Linux 命名空间(Namespace)、控制组(CGro…

RAGFoundry:面向检索增强生成的模块化增强框架

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; 1. 背景与动机 大型语言模型&#xff08;LLMs&#xff09;存在 知识静…

(第十期)HTML基础教程:文档类型声明与字符编码详解

&#xff08;第十期&#xff09;HTML基础教程&#xff1a;文档类型声明与字符编码详解 前言 在使用VS Code等现代编辑器生成HTML页面时&#xff0c;你会发现自动生成的代码中多了一些看似陌生但又非常重要的标签。这些标签不是多余的&#xff0c;而是现代Web开发的标准配置。…

OpenAPI(Swagger3)接口文档自定义排序(万能大法,支持任意swagger版本)

前置参考文档 基于OpenAPI(Swagger3)使用AOP技术&#xff0c;进行日志记录 使用SpringAOP的方式修改controller接口返回的数据 SpringBoot3集成OpenAPI3(解决Boot2升级Boot3) 总结一句话&#xff1a;既然没办法去通过各种方法或者官方的接口去修改接口顺序&#xff0c;那我们就…

vue3上传的文件在线查看

1、npm install vue-office/pdf vue-demi 安装依赖2、npm install vue-office/excel vue-demi 安装依赖3、npm install vue-office/docx vue-demi 安装依赖4、编写一个通用组件&#xff0c;现在只支持 .docx,.xlsx,.pdf 格式的文件&#xff0c;其他文件渲染不成功<temp…