ETCD日常使用规范

80 阅读9分钟

概述

etcd是用Go语言编写的,具有高度一致性的分布式键值存储开源项目。目前的公司etcd主要为公司janus使用的etcd,版本为3.5。

为了规范etcd的部署和运维工作监控工作,制定了公司etcd标准使用规范。

本文档的面向对象:公司内,使用了etcd的系统相关研发、测试、运维人员,以及etcd的运维人员。




一、ETCD介绍

  1. ETCD简介

etcd 是一个分布式键值对存储系统,由coreos 开发,内部采用 raft 协议作为一致性算法,用于可靠、快速地保存关键数据,并提供访问。通过分布式锁、leader选举和写屏障(write barriers),来实现可靠的分布式协作。etcd集群是为高可用、持久化数据存储和检索而准备。

etcd 以一致和容错的方式存储元数据。分布式系统使用 etcd 作为一致性键值存储系统,用于配置管理、服务发现和协调分布式工作。使用 etcd 的通用分布式模式包括领导选举、分布式锁和监控机器活动。

虽然 etcd 也支持单点部署,但是在生产环境中推荐集群方式部署。由于etcd内部使用投票机制,一般 etcd 节点数会选择 3、5、7等奇数。etcd 会保证所有的节点都会保存数据,并保证数据的一致性和正确性。

etcd目前默认使用2379端口提供HTTP API服务,2380端口用作peer通信。

  1. 概念词汇

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来定位数据。

  1. 适用场景

场景一:服务注册与发现,作为集群管理的组件使用

场景二:用于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,000825611leader only5252ms35 MB
100,00082561001000leader only25,00030ms35 MB
100,00082561001000all members33,00025ms35 MB

读取性能如下:

请求数量Key 大小Value 大小连接数量客户端数量一致性每请求平均延迟平均读取 QPS
10,000825611Linearizable2ms560
10,000825611Serializable0.4ms7,500
100,00082561001000Linearizable15ms43,000
100,00082561001000Serializable9ms93,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=(ETCDCTLAPI=3etcdctlendpoints=(ETCDCTL_API=3 etcdctl --endpoints=ip:$port endpoint status --write-out="json" | egrep -o '"revision":[0-9]' | egrep -o '[0-9].')

// 压缩数据

ETCDCTL_API=3 etcdctl --endpoints=ip:ip:port compact $rev

// 碎片整理

ETCDCTL_API=3 etcdctl --endpoints=ip:ip:port defrag

f. 单条数据过大导致的数据无法写入(默认值为1.5m)

启动参数增加:--max-request-bytes={$value}




五、监控告警

etcd通过2379端口metrics暴露监控数据

监控维度

  • 主机资源监控:cpu、内存、磁盘、网络
  • etcd服务指标:节点存活状况(半数以上)、leader情况、etcd调用频率、etcd网络通信延迟、选举



附录

  1. 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

  1. etcd参数清单

成员标记

--name:

成员可读性名称

默认:"default"

--data-dir:

数据目录路径

默认: “${name}.etcd”

--wal-dir:

专用wal目录路径

默认:""

--snapshot-count:

触发快照到磁盘的已提交事务的数量

默认:"10000"

--heartbeat-interval

心跳间隔时间(单位 毫秒)

默认:"100"

--election-timeout:

选举的超时时间(单位 毫秒)

默认:"1000"

--listen-peer-urls:

监听伙伴通讯的URL列表

默认:"http://localhost:2380"

--listen-client-urls

监听客户端通讯的URL列表

默认:"http://localhost:2379"

--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

强制创建新的单一成员的集群。它提交配置修改来强制移除集群中的所有现有成员然后添加自身