(不够详细)etcd:key-value式存储系统
etcd介绍
etcd是基于go语言开发的一个开源的、高可用的key-value式存储系统,可以用于配置共享和服务的注册与发现。
可能etcd此刻你不是很熟悉,但你应该知道zookeeper,etcd和zookeeper比较类似。
etcd都具有哪些特点呢?
完全复制:集群中每个节点都可以使用完整的存档。
高可用性:etcd可用于避免硬件的单店故障或网络问题。
一致性:每次读取都会返回跨多主机的最新写入。
简单:包括一个定义良好、面向用户的api(gRPC)
安全:实现了带有可选的客户端证书身份验证的自动化TLS。
快速:每秒10000次写入的基准速度。
可靠:使用Raft算法实现了强一致、高可用的服务存储目录。
etcd应用场景
服务发现
服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程和服务,要如何才能找到对方并建立连接。本质上来讲,服务发现就是想要了解集群中是否有进程正在监听相应的tcp或udp端口,并且通过名字就可以查找和连接。
图上有三个角色,分别是服务请求方、服务提供方、服务注册方。假设有三台机器:A、B、C,用于提供邮件发送服务,这个时候服务请求方如果想要使用邮件发送服务,那么就会去找服务提供方。但是服务请求方并不是直接寻找服务提供方,因为它不知道,寻找的是服务注册方,然后服务注册方将服务提供方的信息返回给服务请求方,比如:返回A、B、C,表示这三台机器是用来提供服务的。
但是服务注册方如何才能准确返回服务提供方的信息呢?显然服务提供方是要先进行注册的,服务注册方保存了提供方的信息。并且提供方还要不断地向注册方发送心跳信息,表示自己还活着。假设B机器挂掉了,那么请求方向注册方寻找服务方的时候,注册方就不会再返回B机器的信息了。所以服务请求方首先找的是服务注册方
而我们etcd充当的就是服务注册方这一角色,当然zookeeper也是类似。以上便是服务发现
配置中心
将一些配置信息放到etcd上进行集中管理,这类场景的使用方式通常是这样:应用在启动的时候主动从etcd获取一次配置信息,同时在etcd节点上注册一个Watcher并等待,以后每次配置有更新的时候,etcd都会实时地通知订阅者,以此达到获取最新配置信息的目的。
分布式锁
因为etcd使用Raft算法保证了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。
- 保持独占,即所有获取锁的用户最终只有一个用户可以获得锁。etcd为此提供了一套实现分布式锁原子操作的api。通过设置
prevExist
的值,可以保证在多个节点同时创建某个目录时,只有一个可以成功,而创建成功的用户就可以认为是获得了锁。 - 控制时序,即所有想要获得锁的用户都会被安排,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd为此也提供了一套api(自动创建有序键),对一个目录创建值时指定为
POST
动作,这样etcd会在目录下自动生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用api按顺序列出所有当前目录下的键值,此时这些键就是客户端的时序,键对应的值可以是代表客户端的编号。
三个人同时获取锁,但是只有Competitor 2成功了,于是另外两个直接返回失败。每次获取的时候都会看这把锁有没有人用,有的话直接返回失败。
为什么使用etcd而不是zookeeper
我们上面也提到了zookeeper,其实etcd能实现的这些功能,zookeeper也可以实现,那么为什么不使用zookeeper呢?
1. zookeeper的部署和维护比较复杂,管理员需要掌握一系列的知识和技能。而zookeeper所使用的Paxos强一致性算法也素来是以复杂难懂而闻名于世;并且,zookeeper的使用也比较复杂。
2. java编写,由于java偏向于重型应用,会引入大量的依赖。而运维人员则希望保持强一致、高可用的机器集群尽可能简单,维护起来也不容易出错。
3. 发展缓慢,Apache基金会庞大的结构以及松散的管理导致项目发展缓慢
而etcd作为后期之秀,其优点也很明显。
1. 简单,使用go语言编写部署简单,使用HTTP作为接口使用简单,使用Raft强一致性算法使用户易于理解
2. 数据持久化,etcd默认数据一更新就进行持久化
3. 安全,etcd支持ssl客户端安全认证
最后,etcd是一个很年轻的项目,这既是一个优点、也是一个缺点。优点是:它的未来拥有无限的可能性,缺点则是无法得到大项目长时间使用的检验。但是目前CoreOS、k8s、CloudFoundry等知名项目均在生产环境使用了etcd。所以总的来说,etcd值得你去尝试。
etcd架构
关于etcd的架构,我们可以看一张图。
从图中我们可以看到,etcd主要分为四个部分。
HTTP Server:用于处理用户发送的api请求,以及其它etcd节点的同步与心跳信息请求。
Store:用于处理etcd支持的各类功能的事务,包括数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是etcd对用户提供的大多数API功能的具体实现。
Raft:Raft强一致性算法的具体实现,是etcd的核心。
WAL:Write Ahead Log(预写式日志),是etcd的数据存储方式。除了在内存中存有所有数据的状态以及节点的索引以外,etcd就通过WAL进行持久化存储。WAL中,所有的数据提交前都会事先记录日志。Snapshot是为了防止数据过多而进行的状态快照;Entry表示存储的具体日志内容。
通常,一个用户的请求发送过来,会经由HTTP Server转发给Store进行具体的事务处理。如果涉及到节点的修改,则交给Raft模块进行状态的变更、日志的记录,然后再同步给别的etcd节点以确认数据提交。最后进行数据的提交,再次同步。
etcd环境搭建
直接通过以下命令进行下载即可
wget https://github.com/etcd-io/etcd/releases/download/v3.4.7/etcd-v3.4.7-linux-amd64.tar.gz
里面是二进制文件,我们可以直接使用。etcd默认监听的端口是2379,这个端口是和外界进行rpc通信。除此之外还有一个2380,这是用来集群内部之间通信的端口。因为etcd作为一个高可用键值存储系统,天生就是为集群化而设计的。并且由于Raft在做决策时需要多数节点的投票,所以etcd部署集群一般推荐奇数个节点,推荐的节点数量为3、5、7。
我们目前先以单节点来进行演示:
etcd安装完之后非常简单,我们直接执行etcd就可以启动服务了。或者我们使用docker安装也可以:docker pull quay.io/coreos/etcd
此时我们的etcd服务就已经启动了,然后我们再起一个终端,进行操作。
我们在看目录的时候,看到除了etcd还有一个etcdctl,这个etcdctl就相当于客户端。
客户端操作
那么我们可以使用etcdctl进行哪些操作呢?我们说etcd是一个键值对存储系统,那么它肯定支持key-value的设置、查询、删除等操作,我们来看一下。
设置:etcdctl endpoints=http://127.0.0.1:2379 put key "value"
查找:etcdctl endpoints=http://127.0.0.1:2379 get key
删除:etcdctl endpoints=http://127.0.0.1:2379 del key
继续看几个例子
[~]# etcdctl --endpoints=http://127.0.0.1:2379 put hanser "憨八嘎" OK [~]# etcdctl --endpoints=http://127.0.0.1:2379 put hanser "憨八嘎1" OK [~]# etcdctl --endpoints=http://127.0.0.1:2379 put hanser "憨八嘎2" OK # 即使键已经存在,也可以多次设置,只不过会覆盖 [~]# etcdctl --endpoints=http://127.0.0.1:2379 get hanser hanser 憨八嘎2 [~]# [~]# [~]# etcdctl --endpoints=http://127.0.0.1:2379 del hanser 1 [~]# etcdctl --endpoints=http://127.0.0.1:2379 del hanser 0 [~]# etcdctl --endpoints=http://127.0.0.1:2379 del hanser 0 # 对不存在的key也可以删除,只是会返回0。存在的话,删除成功返回1
相关推荐
###host字段指定授权使用该证书的etcd节点IP或子网列表,需要将etcd集群的3个节点都添加其中。cp etcd-v3.3.13-linux-amd64/etcd* /opt/k8s/bin/