• etcd学习笔记 - 入门


    etcd学习笔记 - 入门

    测试环境安装

    1. 安装goreman
    go install github.com/mattn/goreman@latest
    
    • 1
    1. 下载etcd
    2. 添加etcd目录到PATH环境变量中
    3. 下载etcd源码中的Profile文件,并将其启动命令由bin/etcd修改为etcd
    4. 启动集群
    goreman -f Procfile start
    
    • 1

    介绍

    Etcd本质上与一个NoSQL的数据库系统也有几分神似,但更准确的说法说是一个高可用的键值存储系统。
    与一般的NoSQL数据库不同,Etcd在设计的初衷主要用于是共享配置和服务发现,它的灵感来自于ZooKeeper和Doozer。

    其名称来源于unix 的“/etc”文件夹和分布式系统 (“D”istribute system) 的 D,组合在一起表示 etcd 是用于存储分布式配置的信息存储服务。

    基础架构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ujj2hBdb-1659280164565)(assets/image-20220731230756-s22ej6k.png)]

    • Client 层:Client 层包括 client v2 和 v3 两个大版本 API 客户端库,提供了简洁易用的 API,同时支持负载均衡、节点间故障自动转移,可极大降低业务使用 etcd 复杂度,提升开发效率、服务可用性。
    • API 网络层:API 网络层主要包括 client 访问 server 和 server 节点之间的通信协议。一方面,client 访问 etcd server 的 API 分为 v2 和 v3 两个大版本。v2 API 使用 HTTP/1.x 协议,v3 API 使用 gRPC 协议。同时 v3 通过 etcd grpc-gateway 组件也支持 HTTP/1.x 协议,便于各种语言的服务调用。另一方面,server 之间通信协议,是指节点间通过 Raft 算法实现数据复制和 Leader 选举等功能时使用的 HTTP 协议。
    • Raft 算法层:Raft 算法层实现了 Leader 选举、日志复制、ReadIndex 等核心算法特性,用于保障 etcd 多个节点间的数据一致性、提升服务可用性等,是 etcd 的基石和亮点。
    • 功能逻辑层:etcd 核心特性实现层,如典型的 KVServer 模块、MVCC 模块、Auth 鉴权模块、Lease 租约模块、Compactor 压缩模块等,其中 MVCC 模块主要由 treeIndex 模块和 boltdb 模块组成。
    • 存储层:存储层包含预写日志 (WAL) 模块、快照 (Snapshot) 模块、boltdb 模块。其中 WAL 可保障 etcd crash 后数据不丢失,boltdb 则保存了集群元数据和用户写入的数据。

    与zookeeper对比

    zookeeper:高可用性、数据一致性、功能curl、监听数据变化机制

    缺点:

    • 复杂。zookeeper部署维护比较复杂;paxos强一致性算法难懂,使用复杂,需要安装客户端,官方只提供java和C接口
    • java编写,内存占用高
    • 早期:不支持通过API安全变更成员,需要人工一个个节点修改

    与 ZooKeeper 相比,ETCD更简单,安 装、部署和使用更加容易,并且 etcd 的某些功能是 ZooKeeper 所没有的,比如:

    etcd 更加稳定可靠,它的唯一目标就是把分布式一致性 KV 存储做到极 致,所以它更注重稳定性和扩展性
    服务发现,etcd 使用的是节点租约( Lease ),并且支持Group (多 key );而 ZooKeeper 使用的是临时节点,临时节点存在很多问题
    etcd 支持稳定的 watch ,而不是 ZooKeeper 一样简单的单次触发式watch,很多调度系统需要得到完整节点历史记录,etcd 可以存储数十万个历史变更
    etcd 支持 MVCC (多版本并发控制),因为有协同系统需要无锁操作
    etcd 支持更大的数据规模 , 支持存储百万到千万级别的 key
    etcd 的性能更好 。 在 一 个由 3 台 8 核节点组成的云 服务器上, etcd d 版本可以做到每秒数万次的写操作和数十万次的读操作

    与redis对比

    数据复制上Redis是主备异步复制、etcd使用的是Raft,前者可能会丢数据,为了保证读写一致性,etcd读写性能相比Redis差距比较大。

    数据分片上Redis有各种集群版解决方案,可以承载上T数据,存储的一般是用户数据,而etcd定位是个低容量的关键元数据存储,db大小一般不超过8g。

    存储引擎和API上Redis内存实现了各种丰富数据结构,而etcd仅是kv API, 使用的是持久化存储boltdb

    命令介绍

    set命令:设置某个键的值

    etcdctl set /testdir/testkey "Hello world" --ttl '0'
    # 支持的选项包括:
    # --ttl '0'                  该键值的超时时间(单位为秒),不配置(默认为 0)则永不超时
    # --swap-with-value value    若该键现在的值是 value,则进行设置操作
    # --swap-with-index '0'      若该键现在的索引值是指定索引,则进行设置操作
    
    • 1
    • 2
    • 3
    • 4
    • 5

    get命令:获取指定键的值, 当键不存在时,则会报错

    etcdctl get /testdir/testkey
    # 支持的选项包括:
    # --sort          对结果进行排序
    # --consistent    将请求发给主节点,保证获取内容的一致性
    
    • 1
    • 2
    • 3
    • 4

    update命令:当键存在时,更新值内容。 当键不存在时,则会报错

    etcdctl update /testdir/testkey "Hello"
    # 支持的选项包括:
    # --ttl '0'           超时时间(单位为秒),不配置(默认为 0)则永不超时
    
    • 1
    • 2
    • 3

    rm命令:删除某个键值。 当键不存在时,则会报错

    etcdctl update /testdir/testkey "Hello"
    # 支持的选项包括:
    # --dir                如果键是个空目录或者键值对则删除
    # --recursive          删除目录和所有子键
    # --with-value         检查现有的值是否匹配
    # --with-index '0'     检查现有的 index 是否匹配
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    mk命令:如果给定的键不存在,则创建一个新的键值。 当键存在时,则会报错

    etcdctl mk /testdir/testkey "Hello world"
    # 支持的选项包括:
    # --ttl '0'            超时时间(单位为秒),不配置(默认为 0)则永不超时
    
    • 1
    • 2
    • 3

    mkdir命令:如果给定的键目录不存在,则创建一个新的键目录。 当键存在时,则会报错

    etcdctl mkdir testdir2
    # 支持的选项包括:
    # --ttl '0'            超时时间(单位为秒),不配置(默认为 0)则永不超时
    
    • 1
    • 2
    • 3

    setdir:创建一个键目录,无论存在与否。

    # 支持的选项包括:
    # --ttl '0'            超时时间(单位为秒),不配置(默认为 0)则永不超时
    
    • 1
    • 2

    updatedir:更新一个已经存在的目录

    # 支持的选项包括:
    # --ttl '0'            超时时间(单位为秒),不配置(默认为 0)则永不超时
    
    • 1
    • 2

    rmdir:删除一个空目录,或者键值对。若目录不空,会报错

    etcdctl setdir dir1
    etcdctl rmdir dir1
    
    • 1
    • 2

    ls:列出目录(默认为根目录)下的键或者子目录,默认不显示子目录中内容

    etcdctl ls
    etcdctl ls /dir1
    # 支持的选项包括:
    # --sort                将输出结果排序
    # --recursive           如果目录下有子目录,则递归输出其中的内容
    # -p                    对于输出为目录,在最后添加 `/` 进行区分
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    ETCD 命令
    存储:
        curl http://127.0.0.1:4001/v2/keys/testkey -XPUT -d value='testvalue'
        curl -s http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value='hello etcd' -d ttl=5
    获取:
        curl http://127.0.0.1:4001/v2/keys/testkey
    查看版本:
        curl  http://127.0.0.1:4001/version
    删除:
        curl -s http://127.0.0.1:4001/v2/keys/testkey -XDELETE
    监视:
        窗口1:curl -s http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value='hello etcd 1'
              curl -s http://127.0.0.1:4001/v2/keys/message2?wait=true
        窗口2:
              curl -s http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value='hello etcd 2'
    自动创建key:
        curl -s http://127.0.0.1:4001/v2/keys/message3 -XPOST -d value='hello etcd 1'
        curl -s 'http://127.0.0.1:4001/v2/keys/message3?recursive=true&sorted=true'
    创建目录:
        curl -s http://127.0.0.1:4001/v2/keys/message8 -XPUT -d dir=true
    删除目录:
        curl -s 'http://127.0.0.1:4001/v2/keys/message7?dir=true' -XDELETE
        curl -s 'http://127.0.0.1:4001/v2/keys/message7?recursive=true' -XDELETE
    查看所有key:
        curl -s http://127.0.0.1:4001/v2/keys/?recursive=true
    存储数据:
        curl -s http://127.0.0.1:4001/v2/keys/file -XPUT --data-urlencode value@upfile
    使用etcdctl客户端:
    存储:
        etcdctl set /liuyiling/testkey "610" --ttl '100' --swap-with-value value
    获取:
        etcdctl get /liuyiling/testkey
    更新:
        etcdctl update /liuyiling/testkey "world" --ttl '100'
    删除:
        etcdctl rm /liuyiling/testkey
    目录管理:
        etcdctl mk /liuyiling/testkey "hello"    类似set,但是如果key已经存在,报错
        etcdctl mkdir /liuyiling 
        etcdctl setdir /liuyiling  
        etcdctl updatedir /liuyiling      
        etcdctl rmdir /liuyiling    
    查看:
        etcdctl ls --recursive
    监视:
        etcdctl watch mykey  --forever         +    etcdctl update mykey "hehe"
        #监视目录下所有节点的改变
        etcdctl exec-watch --recursive /foo -- sh -c "echo hi"
        etcdctl exec-watch mykey -- sh -c 'ls -al'    +    etcdctl update mykey "hehe"
        etcdctl member list
    集群启动步骤
    1.启动一个etcd,任意机器,如192.168.1.1:2379
    2.curl -X PUT http://192.168.1.1:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0f222/_config/size -d value=3
    3.etcd -name machine1 -initial-advertise-peer-urls http://127.0.0.1:2380 -listen-peer-urls http://127.0.0.1:2380 -discovery http://192.168.1.1:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0f222
    4.如果是在三台不同的服务器上,则重复上面的命令3次,否则重复上面的命令1次+下面的命令2次
    etcd -name machine2 -discovery http://192.168.1.1:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0f222 -addr 127.0.0.1:2389 -bind-addr 127.0.0.1:2389 -peer-addr 127.0.0.1:2390 -peer-bind-addr 127.0.0.1:2390
    etcd -name machine3 -discovery http://192.168.1.1:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0f222 -addr 127.0.0.1:2409 -bind-addr 127.0.0.1:2409 -peer-addr 127.0.0.1:2490 -peer-bind-addr 127.0.0.1:2490
    5.curl -L http://localhost:2379/v2/members | python -m json.tool
    ​
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    非数据库操作

    # backup : 备份etcd的数据命令
    # 支持的选项包括
    # --data-dir         etcd 的数据目录
    # --backup-dir       备份到指定路径
    ​
    # watch : 监测一个键值的变化,一旦键值发生更新,就会输出最新的值并退出。例如,用户更新 testkey 键值为 Hello watch。
    etcdctl get /testdir/testkey
    etcdctl set /testdir/testkey "Hello watch"
    etcdctl watch testdir/testkey
    # 支持的选项包括
    # --forever            一直监测,直到用户按 `CTRL+C` 退出
    # --after-index '0'    在指定 index 之前一直监测
    # --recursive          返回所有的键值和子键值
    ​
    # exec-watch : 监测一个键值的变化,一旦键值发生更新,就执行给定命令。例如,用户更新 testkey 键值。
    etcdctl exec-watch testkey -- sh -c 'ls'
    default.etcd
    Documentation
    etcd
    etcdctl
    etcd-migrate
    README-etcdctl.md
    README.md
    # 支持的选项包括
    # --after-index '0'    在指定 index 之前一直监测
    # --recursive          返回所有的键值和子键值
    ​
    # member : 通过 list、add、remove 命令列出、添加、删除 etcd 实例到 etcd 集群中。例如本地启动一个 etcd 服务实例后,可以用如下命令进行查看。
    etcdctl member list
    # 命令选项
    # --debug 输出 cURL 命令,显示执行命令的时候发起的请求
    # --no-sync 发出请求之前不同步集群信息
    # --output, -o 'simple' 输出内容的格式 (simple 为原始信息,json 为进行json格式解码,易读性好一些)
    # --peers, -C 指定集群中的同伴信息,用逗号隔开 (默认为: "127.0.0.1:4001")
    # --cert-file HTTPS 下客户端使用的 SSL 证书文件
    # --key-file HTTPS 下客户端使用的 SSL 密钥文件
    # --ca-file 服务端使用 HTTPS 时,使用 CA 文件进行验证
    # --help, -h 显示帮助命令信息
    # --version, -v 打印版本信息
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    参考资料

    1. [零声学院免费公开课]](https://course.0voice.com/v1/course/intro?courseId=3&agentId=0)
    2. 极客时间-etcd实战课
    3. 官方文档
    4. 《云原生分布式存储基石 etcd深入解析》
    5. 《etcd技术内幕》
  • 相关阅读:
    第二次pta认证P测试C++
    代码随想录二刷day55
    Linux防火墙配置
    oracle创建数据库,导入dmp操作全家桶
    Spring之AOP
    java计算机毕业设计ssm教师贴心宝的设计与实现
    vmware安装centos7
    OpenAI的GPT-4.5 Turbo:意外曝光且可能在六月份推出
    无病呻吟之高三回忆随笔@_@
    为什么软件公司很少用Python开发Web项目?
  • 原文地址:https://blog.csdn.net/hzb869168467/article/details/126092227