etcd
是使用Go
语言开发的一个开源、高可用的分布式key-value
存储系统,可以用于:
类似的项目或者说中间件还有zookeeper
和consul
,其中zookeeper
,在java
的技术栈中利用的最多,而在go
语言中更多的是使用etcd
或者consul
,这俩对比,etcd
的文档又比consul
更齐全。
etcd
通过raft
算法实现了强一致、高可用的服务存储目录,集群中每个节点都可以使用完整的存档,集群部署也实现了高可用。
服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 udp
或 tcp
端口,并且通过名字就可以查找和连接。就像查字典一样。etcd
就能充当一个服务字典的角色,服务上线去往etcd
进行注册,etcd
与服务之间维持一个心跳,保证服务是否可用。
将分布式系统中各种各样的配置信息集中放至etcd
上,集中管理。可以减少部署、运维成本。
这类应用场景的使用方式通常是:通过程序写入共享配置信息,其他分布式应用启动的时候主动从etcd
获取一次配置信息,同时,应用程序在etcd
节点上注册一个Watcher
并等待,相当于一个订阅者,只要etcd
配置有更新,就会实时通知这些订阅者,以此获得最新的配置信息。
因为etcd
使用Raft
算法保持了数据的一致性, 因此在操作后存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。实现分布式锁的服务有两种方式:
etcd
提供了一套实现分布式锁原子操作CAS(CompareAndSwap)
的API
.通过设置prevExist
值,可以保证多个节点同时去创建某个目录时,只有一个成功。而创建成功的那一个就可以认为是获得了锁。etcd
提供了一套API
,用于自动创建有序键。总而言之:维护了不同语言不同进程之间访问 etcd
的时序。
etcd
能实现的功能,zookeeper
都能做到。具体为什么选择etcd
?
好吧,其实博主对zookeeper
不甚了解。下面的就算是道听途说吧,说的不对也不要喷博主:
zookeeper
采用的Paxos
强一致性算法素来以复杂难懂闻名于世;Apache
基金会项目特有的Apache Wag
在开源界饱受争议,由于基金会庞大的结构和松散的管理导致项目发展缓慢。etcd
后起之秀,技术上的’后起之秀‘,往往能规避’前辈‘的问题,改良甚至摒弃:
Go
语言编写,部署简单是一个特点;HTTP
作为接口;Raft
算法保证强一致性,易于理解;etcd
默认数据一更新就进行持久化;etcd
支持SSL
客户端安全认证。etcd
分为四个部分:
API
请求以及其他etcd
节点的同步与心跳请求;etcd
所支持的各类功能的事务,包括 数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是etcd
对用户提供的大多数 API
功能的具体实现;Raft
强一致性算法的具体实现,这是etcd
的核心;etcd
的数据存储方式。除了在内存中存放所有数据的状态、节点的索引以外,etcd
还会通过WAL
进行数据持久化存储。WAL
中,所有的数据提交前都会事先记录日志。文档:https://etcd.io/docs/
去官方的github
下载最新版本的etcd
,找到最新的release
https://github.com/etcd-io/etcd/releases
分不清楚adm
与arm
的童鞋参考下面链接:
扩展阅读-x86 x86_64/x64 amd64 arm64/aarch64
博主是先在windows
上下载好,使用的winscp
拷贝至服务器的
cd /home/randyfield/etcd-release/
tar -zxvf etcd-v3.2.32-linux-amd64.tar.gz
查看解压后的目录
cd /home/randyfield/etcd-release/etcd-v3.2.32-linux-amd64
./etcd
端口为2379
不挂断的运行命令,由于在主流的 Linux
发行版中都会默认安装 nohup
命令工具:
#启动
nohup ./etcd &
#查看进程-返回进程 id
ps -ef | grep etcd
所以需要设置环境变量:
export ETCDCTL_API=3
./etcdctl put name "garfield"
./etcdctl get name
如果要指定端点,请带上--endponits
参数
./etcdctl --endpoints=[127.0.01:2379] put name "garfield"
etcd
作为高可用的键值存储系统,从出生那一刻就是为集群化的设计而来,所以实际生产环境中,应该使用集群部署。另外,Raft
算法在做决策时需要多数节点进行投票,所以etcd
集群部署都会推荐奇数个节点,推荐3、5、7构成集群。可以使用物理机、虚拟机、容器搭建集群。
export ETCDCTL_API=3
TOKEN=token-01
CLUSTER_STATE=new
NAME_1=machine-1
NAME_2=machine-2
NAME_3=machine-3
HOST_1=192.168.31.204
HOST_2=192.168.31.205
HOST_3=192.168.31.206
CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
TOKEN
:标识etcd
集群,区分不同集群CLUSTER_STATE
:集群状态,标识此集群是新建CLUSTER
:指定集群具体节点在n1节点中执行命令以启动etcd
etcd --data-dir=data.etcd --name n1 \
--initial-advertise-peer-urls http://192.168.31.204:2380 --listen-peer-urls http://192.168.31.204:2380 \
--advertise-client-urls http://192.168.31.204:2379 --listen-client-urls http://192.168.31.204:2379 \
--initial-cluster ${CLUSTER} \
--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
etcd
:启动etcd
命令--data-dir
:数据存储位置--name
:节点名称--initial-advertise-peer-urls
:用于同一个集群中其他节点的连接,2380端口peer
:翻译同等地位的人,同龄人,所以指代的是节点之间--advertise-client-urls
2379 客户端连接--initial-cluster
:初始化一个集群在n2节点执行命令以启动etcd
etcd --data-dir=data.etcd --name n2 \
--initial-advertise-peer-urls http://192.168.31.205:2380 --listen-peer-urls http://192.168.31.204:2380 \
--advertise-client-urls http://192.168.31.204:2379 --listen-client-urls http://192.168.31.204:2379 \
--initial-cluster ${CLUSTER} \
--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
在n3节点执行命令以启动etcd
etcd --data-dir=data.etcd --name n3 \
--initial-advertise-peer-urls http://192.168.31.206:2380 --listen-peer-urls http://192.168.31.206:2380 \
--advertise-client-urls http://192.168.31.206:2379 --listen-client-urls http://192.168.31.206:2379 \
--initial-cluster ${CLUSTER} \
--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
集群就算搭建好了,集群中的节点通过2380端口彼此通信,通过2379与客户端通信
export ETCDCTL_API=3
HOST_1=192.168.31.204
HOST_2=192.168.31.205
HOST_3=192.168.31.206
ENDPONITS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
etcdctl --endpoints=$ENDPOINTS member list
--endpoints
中指定3个节点的。