简介
etcd是一个采用Raft协议实现强一致性的分布式键值数据库,它提供了一种可靠的方式存储需要被分布式系统或机器集群访问的数据。
常见使用场景:服务注册与发现、键值对存储、消息发布和订阅、分布式锁。
特点
- 简单:安装配置简单,提供HTTP API进行交互
- 安全:支持SSL认证
- 键值对存储:将数据存储在分层组织的目录中,如同在标准文件系统中
- 监测变更:监测特定的键或目录以进行更改,并对值的更改做出反应
- 性能:性能良好,根据官方压测结果,单实例支持每秒两千次以上的读操作
- 可靠:基于raft算法,分布式数据的一致性和可用性有保证
常见相关术语
术语 | 描述 | 备注 |
---|---|---|
raft | raft算法,etcd实现一致性的核心 | etcd有etcd-raft模块 |
follower | 集群中的从节点 | nil |
leader | 集群中的主节点 | leader节点协调整个集群 |
candidate | 候选节点 | 当follower接收leader的消息超时,就会转变为candidate |
node | raft状态机的实例 | nil |
member | etcd实例,管理对应的node节点 | 可处理客户端请求 |
peer | 同一个集群中的另一个member | nil |
cluster | etcd集群 | nil |
lease | 租期 | 键值对设置的过期时间,过期后删除 |
watch | 监测机制 | 监控键值对的变化 |
term | 任期 | 某个节点成为leader,到下一次竞选的时间 |
WAL | 预写式日志 | 用于持久化存储的日志格式 |
单机部署
二进制包方式
- 从 github 仓库的 release 下载二进制包
- 解压后得到 etcd 和 etcdctl。将两个二进制可执行文件放到
/usr/local/bin
目录 - 验证
etcd --version
etcdctl version
- 安装完成
单机启动脚本
#!/bin/bash
set -u
scriptDir=$(cd $(dirname $0) && pwd)
baseDir=$(cd ${scriptDir}/.. && pwd)
function startApp() {
nohup etcd \
--listen-client-urls http://127.0.0.1:12379 \
--advertise-client-urls http://127.0.0.1:12379 \
--enable-pprof \
--logger 'zap' \
--log-outputs=stderr \
--data-dir="${baseDir}/data" > ${baseDir}/logs/app.log 2>&1 &
}
function main(){
startApp
}
main
集群部署
etcd集群一般由奇数个节点组成,多个节点通过raft算法相互协作。raft算法会选择其中一个主节点作为leader,负责数据同步和分发。当leader发生故障时,系统会自动选择另一个节点作为leader。
静态集群
如果集群成员的一些信息,比如IP、端口是已知的,则可以静态方式部署etcd集群。
单机三实例的启动脚本示例,注意修改IP、端口号等信息
#!/bin/bash
set -u
script_dir=$(cd $(dirname $0) && pwd)
etcd1IP='192.168.0.41'
etcd2IP='192.168.0.41'
etcd3IP='192.168.0.41'
etcdClusterToken='etcd-cluster-1'
function startNode1() {
nohup etcd --name etcd1 \
--listen-client-urls http://${etcd1IP}:12379 \
--advertise-client-urls http://${etcd1IP}:12379 \
--listen-peer-urls http://${etcd1IP}:12380 \
--initial-advertise-peer-urls http://${etcd1IP}:12380 \
--initial-cluster-token ${etcdClusterToken} \
--initial-cluster="etcd1=http://${etcd1IP}:12380,etcd2=http://${etcd2IP}:22380,etcd3=http://${etcd3IP}:32380" \
--initial-cluster-state 'new' \
--enable-pprof \
--logger 'zap' \
--log-outputs=stderr \
--data-dir="${script_dir}/node1/data" > ${script_dir}/node1/logs/app.log 2>&1 &
}
function startNode2() {
nohup etcd --name etcd2 \
--listen-client-urls http://${etcd2IP}:22379 \
--advertise-client-urls http://${etcd2IP}:22379 \
--listen-peer-urls http://${etcd2IP}:22380 \
--initial-advertise-peer-urls http://${etcd2IP}:22380 \
--initial-cluster-token ${etcdClusterToken} \
--initial-cluster="etcd1=http://${etcd1IP}:12380,etcd2=http://${etcd2IP}:22380,etcd3=http://${etcd3IP}:32380" \
--initial-cluster-state 'new' \
--enable-pprof \
--logger 'zap' \
--log-outputs=stderr \
--data-dir="${script_dir}/node2/data" > ${script_dir}/node1/logs/app.log 2>&1 &
}
function startNode3() {
nohup etcd --name etcd3 \
--listen-client-urls http://${etcd3IP}:32379 \
--advertise-client-urls http://${etcd3IP}:32379 \
--listen-peer-urls http://${etcd3IP}:32380 \
--initial-advertise-peer-urls http://${etcd3IP}:32380 \
--initial-cluster-token ${etcdClusterToken} \
--initial-cluster="etcd1=http://${etcd1IP}:12380,etcd2=http://${etcd2IP}:22380,etcd3=http://${etcd3IP}:32380" \
--initial-cluster-state 'new' \
--enable-pprof \
--logger 'zap' \
--log-outputs=stderr \
--data-dir="${script_dir}/node3/data" > ${script_dir}/node1/logs/app.log 2>&1 &
}
function main() {
mkdir -p ./node{1,2,3}/{data,logs}
startNode1
startNode2
startNode3
}
main
测试:etcdctl --endpoints=http://192.168.0.41:12379 member list -w table
18681a1499dc680b, started, etcd2, http://192.168.0.41:22380, http://192.168.0.41:22379, false
8d715e240221ff02, started, etcd1, http://192.168.0.41:12380, http://192.168.0.41:12379, false
b0fec1f33e425704, started, etcd3, http://192.168.0.41:32380, http://192.168.0.41:32379, false
主要参数说明,其它参数可执行etcd --help
查看。
--name
:etcd集群中的实例名,不重复即可--listen-client-urls
:监听的用于客户端通信的url,可监听多个--advertise-client-urls
:建议使用的客户端通信url,用于etcd代理或etcd成员与etcd节点通信--listen-peer-urls
:节点之间通信的url,可监听多个,集群内布通过这些url进行数据交互--initial-advertise-peer-urls
:同样用于节点之间通信--initial-cluster-token
:根据该token生成集群唯一id--initial-cluster
:集群中其它节点的--initial-advertise-peer-urls
合集--initial-cluster-state
:new,新建集群的标志
动态发现集群
nil
基于dns的动态发现集群
nil
参考
-
朱荣鑫、刘峰 - 《etcd工作笔记》