概述
etcd是用Go语言编写的,具有高度一致性的分布式键值存储开源项目。目前的公司etcd主要为公司janus使用的etcd,版本为3.5。
为了规范etcd的部署和运维工作监控工作,制定了公司etcd标准使用规范。
本文档的面向对象:公司内,使用了etcd的系统相关研发、测试、运维人员,以及etcd的运维人员。
一、ETCD介绍
-
ETCD简介
etcd 是一个分布式键值对存储系统,由coreos 开发,内部采用 raft 协议作为一致性算法,用于可靠、快速地保存关键数据,并提供访问。通过分布式锁、leader选举和写屏障(write barriers),来实现可靠的分布式协作。etcd集群是为高可用、持久化数据存储和检索而准备。
etcd 以一致和容错的方式存储元数据。分布式系统使用 etcd 作为一致性键值存储系统,用于配置管理、服务发现和协调分布式工作。使用 etcd 的通用分布式模式包括领导选举、分布式锁和监控机器活动。
虽然 etcd 也支持单点部署,但是在生产环境中推荐集群方式部署。由于etcd内部使用投票机制,一般 etcd 节点数会选择 3、5、7等奇数。etcd 会保证所有的节点都会保存数据,并保证数据的一致性和正确性。
etcd目前默认使用2379端口提供HTTP API服务,2380端口用作peer通信。
-
概念词汇
Raft:etcd所采用的保证分布式系统强一致性的算法。
Node:一个Raft状态机实例。
Member: 一个etcd实例。它管理着一个Node,并且可以为客户端请求提供服务。
Cluster:由多个Member构成、可以协同工作的etcd集群。
Peer:对同一个etcd集群中另外一个Member的称呼。
Client: 向etcd集群发送HTTP请求的客户端。
WAL:预写式日志,etcd用于持久化存储的日志格式。
snapshot:etcd防止WAL文件过多而设置的快照,存储etcd数据状态。
Proxy:etcd的一种模式,为etcd集群提供反向代理服务。
Leader:Raft算法中,通过竞选而产生的、处理所有数据提交的节点。
Follower:竞选失败的节点作为Raft中的从属节点,为算法提供强一致性保证。
Candidate:当Follower超过一定时间接收不到Leader的心跳时转变为Candidate开始竞选。
Term:某个节点成为Leader到下一次竞选时间,称为一个Term。
Index:数据项编号。Raft中通过Term和Index来定位数据。
-
适用场景
场景一:服务注册与发现,作为集群管理的组件使用
场景二:用于K-V存储,作为数据库使用。
公司的etcd主要是k8s集群用作服务注册和发现,janus用作k-v数据库。
二、技术规范
a. 版本规范
目前公司运维团队支持如下etcd版本交付及运维工作(其他版本需求,麻烦联系运维团队):
- etcd 3.5(janus定制版)
b. etcd功能
公司的etcd集群,主要作为Janus的配置中心,用于保存Janus的各种配置,同时etcd集群为去中心化集群,可靠性较高。
c. 架构规范
公司ETCD现阶段采用高可用模式客户端连接入口可扩展性故障恢复情况集群+镜像备份节点+数据备份的部署架构。提供奇数(推荐3-7)节点集群,加上异地机房实时备份节点,以及延迟备份的策略备份保障可用性。
无法复制加载中的内容
d. 部署架构
无法复制加载中的内容
e. 推荐配置
4C8G50G(数据盘/data) * 3+ 4C8G100G(数据盘/data)
三、资源规划
etcd资源推荐配置
四、运维场景
a. 半数以下节点异常且不可恢复(包括挂掉过长时间)
半数以下节点异常,此时集群时可用的,在尝试异常的etcd服务不可行后,可以替换节点(此替换支持修改地址或地址不变,在修复逻辑上一致)
操作流程:
1.集群中删除member(如果是原机器,删除/data目录下所有内容)
2.启动新member
3.增加新member到集群中
4.修改集群及备份节点member配置
5.重启备份节点
此操作,可以通过 jenkins job:apisix_replace_member_3.5_etcd 完成
b. 半数以上节点异常且不可恢复
半数以上节点异常,此时集群已不可用。如果此时备份节点正常,可以使用备份节点的数据,恢复集群。如果备份节点异常,可以使用延迟备份的数据恢复数据。具体操作:
1.新建集群(jenkins job: apisix_install_3.5_etcd)
2.获取备份数据
使用备份节点数据,通过命令获取备份数据:etcdctl snapshot save {$XXX}
使用延迟备份数据,延迟备份地址:/data/bak/。可取最新日期的数据
3.使用备份数据,恢复集群:etcdctl snapshot restore {$XXX}
4.新集群会有新的备份,将原资源释放即可
c. 性能不足
我们的应用场景,对性能要求不高,故此配置不高。etcd的性能主要受网络IO延迟和磁盘IO延迟影响。
1.磁盘IO延迟较为严重,可以更换SSD盘(进一步优化可以将/data/yumc_etcd/no1.etcd/member/snap和/data/yumc_etcd/no1.etcd/member/wal分盘,提高IO效率)
2.网络IO延迟较为严重,可以针对网络做优化
etcd性能官方数据(仅供参考)
参考配置:
- Google Cloud Compute Engine
- 3 台机器, 8 vCPUs + 16GB Memory + 50GB SSD
- 1 台机器(客户端),16 vCPUs + 30GB Memory + 50GB SSD
- Ubuntu 15.10
- etcd v3 master 分支 (commit SHA d8f325d), Go 1.6.2
写入性能如下:
| key的数量 | Key的大小 | Value的大小 | 连接数量 | 客户端数量 | 目标 etcd 服务器 | 平均写入 QPS | 每请求平均延迟 | 内存 |
|---|---|---|---|---|---|---|---|---|
| 10,000 | 8 | 256 | 1 | 1 | leader only | 525 | 2ms | 35 MB |
| 100,000 | 8 | 256 | 100 | 1000 | leader only | 25,000 | 30ms | 35 MB |
| 100,000 | 8 | 256 | 100 | 1000 | all members | 33,000 | 25ms | 35 MB |
读取性能如下:
| 请求数量 | Key 大小 | Value 大小 | 连接数量 | 客户端数量 | 一致性 | 每请求平均延迟 | 平均读取 QPS |
|---|---|---|---|---|---|---|---|
| 10,000 | 8 | 256 | 1 | 1 | Linearizable | 2ms | 560 |
| 10,000 | 8 | 256 | 1 | 1 | Serializable | 0.4ms | 7,500 |
| 100,000 | 8 | 256 | 100 | 1000 | Linearizable | 15ms | 43,000 |
| 100,000 | 8 | 256 | 100 | 1000 | Serializable | 9ms | 93,000 |
备注:Linearizable表示,所有集群成员都读写。Serializable表示只一个成员读写,此种情况,数据一致性会降低
d. 内存、snapshot大小异常
情况一:频繁更新key/value会使得版本增加过快
开启自动数据压缩,单位为小时:启动参数增加--auto-compaction-retention={$value}
情况二:内存过高
方法1:减少内存中的raft条目:调小--snapshot-count={$value}(过大的raft条目,会降低etcd性能)
方法2:扩大集群机器内存
e. etcd自身磁盘空间不足
etcd自身容量不足,如收到告警,或者通过命令:ETCDCTL_API=3 ./etcdctl --endpoints={$endpoints} alarm list看到 NOSPACE的告警。或看到:mvcc: database space exceeded报错
方法一:增加etcd容量。上限为8g
启动参数中增加:--quota-backend-bytes=8589934592(8g)
方法二:压缩老数据,操作命令如下
// 获取当前数据版本
rev=ip:$port endpoint status --write-out="json" | egrep -o '"revision":[0-9]' | egrep -o '[0-9].')
// 压缩数据
ETCDCTL_API=3 etcdctl --endpoints=port compact $rev
// 碎片整理
ETCDCTL_API=3 etcdctl --endpoints=port defrag
f. 单条数据过大导致的数据无法写入(默认值为1.5m)
启动参数增加:--max-request-bytes={$value}
五、监控告警
etcd通过2379端口metrics暴露监控数据
监控维度
- 主机资源监控:cpu、内存、磁盘、网络
- etcd服务指标:节点存活状况(半数以上)、leader情况、etcd调用频率、etcd网络通信延迟、选举
附录
-
etcdctl常用命令
运维命令
查看集群状态:
etcdctl --write-out=table --endpoints=$ENDPOINTS endpoint status
查看集群成员:
etcdctl --write-out=table --endpoints=$ENDPOINTS member list
删除集群成员:
etcdctl --endpoints=$ENDPOINTS member remove ${MEMBER_ID}
增加集群成员:
etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379 member add ${NAME_3} --peer-urls=http://${HOST_3}:2380
defrang(磁盘碎片整理):
etcdctl --endpoints=$ENDPOINTS defrag
save命令:
etcdctl snapshot save snapshot.db
restore命令:
etcdctl snapshot restore snapshot.db
status命令:
etcdctl snapshot status snapshot.db -w table
查看endpoints的status:
etcdctl endpoint --cluster=true status -w table
切换leader:
etcdctl --endpoints 192.168.5.45:2379 move-leader d6414a7c7c550d29
增加用户:
etcdctl user add zs
增加role:
etcdctl role add relo1
用户赋予角色:
etcdctl user grant-role zs role1
角色赋权:
etcdctl role grant-permission role1 read /testkey
开启用户认证:
etcdctl --endpoints=$ENDPOINTS auth enable
增删改查
得到所有Key:
etcdctl --endpoints=$ENDPOINTS --prefix --keys-only=true get /
得到对应key的值:
etcdctl --endpoints=$ENDPOINTS get /testkey
put操作:
etcdctl --endpoints=$ENDPOINTS put /testkey_1 "test_1"
del操作:
etcdctl --endpoints=$ENDPOINTS del /testkey_1
watch操作:
etcdctl --endpoints=$ENDPOINTS watch /testkey
设置目录:./etcdctl mkdir testdir2
-
etcd参数清单
成员标记
--name:
成员可读性名称
默认:"default"
--data-dir:
数据目录路径
默认: “${name}.etcd”
--wal-dir:
专用wal目录路径
默认:""
--snapshot-count:
触发快照到磁盘的已提交事务的数量
默认:"10000"
--heartbeat-interval
心跳间隔时间(单位 毫秒)
默认:"100"
--election-timeout:
选举的超时时间(单位 毫秒)
默认:"1000"
--listen-peer-urls:
监听伙伴通讯的URL列表
--listen-client-urls
监听客户端通讯的URL列表
--max-snapshots
保持的快照文件的最大数量 (0 表示不限制)
默认:5
--max-wals
保持的wal文件的最大数量(0 表示不限制)
默认:5
--cors
逗号分割的 origin 白名单,用于 CORS (cross-origin resource sharing/跨 origin 资源共享)
默认:none
集群标记
--initial
前缀标记用于启动(static bootstrap, [discovery-service bootstrap])(clustering.md#discovery) 或 runtime reconfiguration) 新成员, 然后当重新启动一个已有的成员时被忽略
--discovery
前缀标记在使用发现服务需要设置.
--initial-advertise-peer-urls
这个成员的伙伴 URL
--initial-cluster
启动初始化集群配置
--initial-cluster-state
初始化集群状态(new 或 existing)
--initial-cluster-token
在启动期间用于 etcd 集群的初始化集群记号(cluster token)
--advertise-client-urls
列出这个成员的客户端URL
--discovery
用于启动集群的发现URL
--discovery-srv
用于启动集群的 DNS srv 域名
--discovery-fallback
当发现服务失败时的期待行为(“exit” 或 “proxy”)
--discovery-proxy
用于请求到发现服务的 HTTP 代理
--strict-reconfig-check
拒绝将导致法定人数丢失的重配置请求
--auto-compaction-retention
自动压缩用于 mvcc 键值存储的保持力(注:应该指多版本保存),单位小时。 0 表示关闭自动压缩
安全标记
--cert-file
客户端服务器 TLS 证书文件的路径
--key-file
客户端服务器 TLS key 文件的路径
client-cert-auth
客户端证书认证是否开启
默认:false
--trusted-ca-file
客户端服务器 TLS 信任证书文件的路径
--auto-tls
使用生成证书的客户端TLS
--peer-cert-file
peer server TLS 证书文件的路径
--peer-key-file
peer server TLS key 文件的路径
--peer-client-cert-auth
开启 peer client 证书验证
--peer-trusted-ca-file
peer server TLS 信任证书文件路径
--peer-auto-tls
使用生成证书的peer TLS
日志标记
--debug
设置所有子包的默认日志级别为DEBUG
--log-package-levels
设置个人 etcd 子包为指定日志级别。例如etcdserver=WARNING,security=DEBUG
--force-new-cluster
强制创建新的单一成员的集群。它提交配置修改来强制移除集群中的所有现有成员然后添加自身