Etcd分布式存储系统
介绍
etcd是一款高性能的开源的分布式key-value分布式存储系统,可以用于配置共享和服务的注册与发现等功能。类似于zookeeper和consul。
etcd 诞生于 CoreOS 公司,它最初是用于解决集群管理系统中 OS 升级的分布式并发控制以及配置文件的存储与分发等问题。正如etcd官网所说,etcd 被设计为提供高可用、强一致,可靠的的 key-value 分布式数据存储服务。
etcd的官网:https://etcd.io/
etcd的github地址:https://github.com/etcd-io/etcd
使用etcd的项目
1. CoreOS。
2. Kubernetes。
3. CloudFoundry。
4. docker swarm kit。
etcd应用场景
1.服务注册与发现(Service Discovery)。
服务注册发现一般用于微服务中,就是解决在同一个分布式集群中的进程或者一个服务,如何自动确定系统中有哪些服务,如何取找到目标服务或者进程并建立连接。涉及到一个服务有哪些实例,这些服务的地址等信息等是个问题,服务注册与发现就是用于解决该问题。新添加的服务通过注册后可以让服务请求方可以发现。
服务发现的几个关键问题:
1)服务注册中心不仅仅是记录当前有多少个服务提供者,同时服务注册中心还监控每个服务提供者的状态,他们之前有心跳机制,如果其中有一台服务提供者连不上就会让其下线,保证服务请求者连接的服务都是可用的。
2.配置中心。
将一些配置信息放在etcd上进行集中管理。这类场景的使用方式一般是应用在启动的时候主动从etcd获取一次配置信息,同时在etcd节点上注册一个Watcher并等待,以后每次配置有更新的时候,etcd都会实时通知订阅者,以达到获取最新配置信息的目的。
2.分布式锁。
因为 etcd使用 Raft算法保持了数据的强一致性,某次操作存储到集群中的 值就必然是全局一致的,所以 etcd很容易实现分布式锁 。
锁服务包含两种使用方式, 一 是保持独占,二是控制时序 。
1)保持独占
保持独占即所有试图获取锁的用户最终只有一个可以得到 。
etcd 为此 提供了一套实现分布式锁原子操作 CAS ( ComparaAndSwap)的 API。 通过设置 prevExist 值,可以保证在多个节点上同时创建某个目录时,只有一个节点能够成功,而成功的那个即可获得分布式锁 。
. 2)控制时序
试图获取锁的所有用户都会进入等待队列,获得锁的顺序是全局唯一的,同时还能决定 队列的执行顺序 。
etcd 为此也提供了 一套 API (自动创建有序键),它会将一个目录的键值指 定为 POST 动作,这样, etcd 就会在目录下生成一个当前最大的值作为键,并 存储这个新的值(客户端编号) 。
3.负载均衡。
4.分布式通知与协调。
5.消息发布和订阅。。
6.分布式队列。
etcd的特点
1.完全复制:集群中的每个节点都可以使用完整的存档。
2.高可用性:Etcd可用于避免硬件的淡点故障或网络分区问题。当集群中主节点挂了,会选举新的leader主节点。
3.一致性:根据CAP理论,基于Raft算法的Etcd满足CAP中的CP,每次读取都会返回跨多主机的最新写入。
4.简单:相对于其他同类产品适用简单,包括一个定义良好的,面向用户的API(gRPC)。
5.安全:支持客户端SSL安全认证,实现了可选的客户端证书身份验证的自动化TLS。
6.快速:每秒10000次写入的基准速度。
7.可靠:使用Raft分布式算法实现了强一致性,高可用性的服务存储目录。
etcd的架构及内部机制
总体架构
etcd的架构主要分四个部分
1.HTTP Server:用于处理用户发送的API请求以及其他etcd节点的同步与心跳信息的请求。
2.Store:用于处理etcd支持的各类功能的事务,包括数据索引,节点状态的变更,监控与反馈,事件处理与执行等,是etcd对用户提供的大多数API功能的具体实现。
3.Raft:Raft分布式强一致性算法的具体实现,是etcd的核心。
4.WAL:Write Ahead Log(预写式日志),是etcd的数据存储方式,这种技术在mysql中也有用到。除了在内存中存有所有数据的状态及节点的索引以外,etcd就通过WAL进行持久化存储。WAL中所有数据提交前都会实现记录日志。Snapshot是为了防止数据过多而进行的状态快照,Entry表示存储的具体日志内容。
内部机制
一个 etcd 集群,通常会由 3 个或者 5 个节点组成,多个节点之间通过 Raft 一致性算法的完成分布式一致性协同,算法会选举出一个主节点作为 leader,由 leader 负责数据的同步与数据的分发。当 leader 出现故障后系统会自动地选取另一个节点成为 leader,并重新完成数据的同步。客户端在多个节点中,仅需要选择其中的任意一个就可以完成数据的读写,内部的状态及数据协同由 etcd 自身完成。
在 etcd 整个架构中,有一个非常关键的概念叫做 quorum,quorum 的定义是 (n+1)/2,也就是说超过集群中半数节点组成的一个团体,在 3 个节点的集群中,etcd 可以容许 1 个节点故障,也就是只要有任何 2 个节点可用,etcd 就可以继续提供服务。同理,在 5 个节点的集群中,只要有任何 3 个节点可用,etcd 就可以继续提供服务,这也是 etcd 集群高可用的关键。
在允许部分节点故障之后继续提供服务,就需要解决一个非常复杂的问题:分布式一致性。在 etcd 中,该分布式一致性算法由 Raft 一致性算法完成,这个算法本身是比较复杂的有机会再详细展开,这里仅做一个简单的介绍以方便大家对其有一个基本的认知。Raft 一致性算法能够工作的一个关键点是:任意两个 quorum 的成员之间一定会有一个交集(公共成员),也就是说只要有任意一个 quorum 存活,其中一定存在某一个节点(公共成员),它包含着集群中所有的被确认提交的数据。正是基于这一原理,Raft 一致性算法设计了一套数据同步机制,在 Leader 任期切换后能够重新同步上一个 quorum 被提交的所有数据,从而保证整个集群状态向前推进的过程中保持数据的一致。
etcd安装
etcd下载地址:https://github.com/etcd-io/etcd/releases 在这里选择一个版本。
我的环境是Mac系统使用brew安装即可。
安装完毕后查看etcd版本
etcd使用
1. 启动etcd服务:执行etcd命令即可启动服务。
songguojundeMBP:~ songguojun$ etcd [WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead 2020-05-09 19:10:42.606712 I | etcdmain: etcd Version: 3.4.4 2020-05-09 19:10:42.606862 I | etcdmain: Git SHA: Not provided (use ./build instead of go build) 2020-05-09 19:10:42.606872 I | etcdmain: Go Version: go1.13.8 2020-05-09 19:10:42.606877 I | etcdmain: Go OS/Arch: darwin/amd64 2020-05-09 19:10:42.606882 I | etcdmain: setting maximum number of CPUs to 4, total number of available CPUs is 4 2020-05-09 19:10:42.606891 N | etcdmain: failed to detect default host (default host not supported on darwin_amd64) 2020-05-09 19:10:42.606897 W | etcdmain: no data-dir provided, using default data-dir ./default.etcd 2020-05-09 19:10:42.607019 N | etcdmain: the server is already initialized as member before, starting as etcd member... [WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead
可以通过命令查看启动状态
songguojundeMBP:~ songguojun$ lsof -i:2380 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME firefox 471 songguojun 84u IPv4 0xa91ef03152373cdb 0t0 TCP localhost:62070->localhost:2380 (ESTABLISHED) etcd 1428 songguojun 7u IPv4 0xa91ef0314fb65973 0t0 TCP localhost:2380 (LISTEN)
也可以使用brew管理命令启动:brew services run etcd
使用brew services list查看状态。
songguojundeMBP:~ songguojun$ brew services list Name Status User Plist consul stopped etcd started songguojun /usr/local/opt/etcd/homebrew.mxcl.etcd.plist 已经启动了 mysql@5.7 stopped nginx stopped openresty stopped rabbitmq stopped supervisor stopped
etcd默认在2379端口监听客户端通信,默认在2380端口监听节点之间的通信。
etcd集群
etcd作为一个高可用分布式键值存储系统,本身就是为集群而设计的。Raft算法在决策的时候需要多数节点的投票,所以etcd部署集群的节点一般推荐奇数个。
参考资料
https://www.kubernetes.org.cn/6226.html