Skip to content

Commit e2e8f71

Browse files
author
yangjingjing
committed
init blog
1 parent ae57cb6 commit e2e8f71

13 files changed

+2556
-1015
lines changed

_posts/2017-04-01-分布式Raft算法.md

Lines changed: 277 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 78 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ categories: etcd
44
description: none
55
keywords: etcd
66
---
7-
# Etcd简介
8-
ETCD是一个分布式、开源的、可靠的key-value存储的分布式系统,用于存储分布式系统中的关键数据;提供共享配置、服务的注册和发现;基于Go语言实现 。
7+
# etcd入门
8+
etcd是一个分布式、开源的、可靠的key-value存储的分布式系统,用于存储分布式系统中的关键数据;提供共享配置、服务的注册和发现;基于Go语言实现 。
99

10-
## etcd介绍
11-
ectd是CoreOS公司发起的一个开源项目,是用于共享配置和服务发现的分布式,一致性的KV存储系统,它的目标是提供了一种可靠的方法来存储分布式系统或机器集群需要访问的数据。
12-
类似项目有zookeeper和consul。
10+
## etcd简介
11+
etcd是一个可靠的分布式KV存储,其底层使用Raft算法保证一致性,主要用于共享配置和服务发现。etcd是CoreOS公司发起的一个开源项目,授权协议为Apache,其源代码地址为https://github.com/coreos/etcd。
12+
13+
ectd是用于共享配置和服务发现的分布式,一致性的KV存储系统,它的目标是提供了一种可靠的方法来存储分布式系统或机器集群需要访问的数据。 类似项目有zookeeper和consul。
1314

1415
具有以下特点:
1516
- 简单:安装配置简单,且提供HTTP API进行交互,使用也简单;
@@ -21,6 +22,76 @@ ectd是CoreOS公司发起的一个开源项目,是用于共享配置和服务
2122
- Revision 机制:每个 Key 带有一个 Revision 号,每进行一次事务便加一,因此它是全局唯一的,如初始值为 0,进行一次 Put 操作,Key 的 Revision 变为 1,同样的操作,再进行一次,Revision 变为 2;换成 Key1 进行 Put 操作,Revision 将变为 3。这种机制有一个作用,即通过 Revision 的大小就可知道写操作的顺序,这对于实现公平锁,队列十分有益;
2223
- Lease 机制:即租约机制(TTL,Time To Live),Etcd 可以为存储的 Key-Value 对设置租约,当租约到期,Key-Value 将失效删除;同时也支持续约,通过客户端可以在租约到期之前续约,以避免 Key-Value 对过期失效;此外,还支持解约,一旦解约,与该租约绑定的 Key-Value 将失效删除;
2324

25+
目前提供配置共享和服务发现功能的组件还是比较多的,其中应用最为广泛、大家最为熟悉的应该就是ZooKeeper了,很多开源项目也都在不同程度上依赖了ZooKeeper,例如,Dubbo、Kafka等。
26+
27+
这里简单介绍一下“服务发现”和“共享配置”两个概念。随着一个系统的不断迭代,功能模块会不断增加,对整个系统进行服务的拆分是必然的,这就会出现多个服务之间的相互调用,而在出现服务发现组件之前,一般是通过读取配置文件中预先设置的IP来获取服务的地址,然后进行调用。这会导致很多问题,例如,某些服务已经不可用时,调用方不能及时感知,负载均衡比较复杂,等等。使用服务发现组件之后,我们可以将服务提供方的信息注册到服务发现组件,例如,注册到ZooKeeper中,然后定期发送心跳等信息,让服务发现组件知晓服务提供方是可用的。当调用方进行服务调用时,会先请求服务发现组件,由服务发现组件来保证返回可用的服务地址及负载均衡等功能。
28+
29+
在一个系统的不同模块中有很多配置信息,例如,数据库地址、连接配置信息等都差不多,如果使用静态配置文件的方式实现,则需要将相同的信息写多份,每次更新配置时也需要更新多次。如果将这些配置信息注册到共享配置组件中,则系统的不同模块在启动时可从共享配置组件中获取配置,同时会监听配置信息的更改,当配置信息发生变更时,可以自动将配置值替换成新值。
30+
31+
在Golang社区中,etcd则是唯一一个可以媲美ZooKeeper的组件,在有些方面,etcd甚至超越了 ZooKeeper,给开发者眼前一亮的感觉。下面简单列举一下 etcd 相较于 ZooKeeper的优势。
32+
33+
- 一致性协议:一致性协议是配置共享和服务发现组件的核心,etcd底层采用了Raft协议,而ZooKeeper使用ZAB协议,ZAB协议是一种类Paxos的一致性协议。目前公认的是Raft比Paxos协议易于理解,工程化也较为容易。
34+
- API接口:etcd v2版本中提供了HTTP+JSON的调用方式,在etcd v3版本的客户端中则使用GRPC与服务端进行交互,而GRPC本身就是跨平台的。
35+
- 性能:在官方提供的基准测试数据中,etcd集群可以支持每秒10000+次的写入,性能相当可观,优于ZooKeeper。
36+
- 安全性:etcd支持TLS访问,而ZooKeeper在权限控制这方面做得略显粗糙。
37+
38+
etcd也有很多成功的案例,最为大家熟知的就是Kubernetes,其底层就依赖于etcd实现集群状态和配置的管理。除了Kubernetes,Cloud Foundry等500+个GitHub项目都使用了etcd。
39+
40+
## 数据模型
41+
etcd 支持可靠的键值对存储并且提供了可靠的 Watcher 机制,其中的键值对存储支持多版本,并且具备能够“Watch”历史事件的功能。这里简单介绍多版本存储的含义,假设键K1对应的值为V1,当我们将K1对应的值修改成V2时,etcd并不会直接将V1修改成V2,而是同时记录V1和V2两个值,并通过不同的版本号进行区分。另外,Watch历史事件的含义是,我们可以向一个 Key 添加 Watcher,同时可以指定一个历史版本,从该版本开始的所有事件都会触发该Watcher。
42+
43+
随着应用不断运行,键值对不断修改,每个Key都在etcd中保存了多个版本,数据量也会越来越大。为了缓解压力,etcd会定期进行压缩,清理过旧的数据。
44+
45+
在很多现代数据库系统中,都用了B树索引加速查询,etcd也是如此,其存储中会维护一个字段序的B树索引。在B树索引的每个索引项中,都存储了一个Key值,这样可以快速定位指定的Key或是进行范围查询。而每个Key值对应了多个版本号,etcd中维护了一个全局自增的版本号,为每次事务分配一个全局唯一的版本号(main revision),事务中的每个操作也有唯一的编号(sub revision),通过这两部分可以确定一个唯一的Value值。
46+
47+
每个Key会对应多个generation,当Key首次创建时,会同时创建一个与之关联的generation实例,当该Key被修改时,会将对应的版本记录到generation中,当Key被删除时,会向generation中添加tombstone,并创建新的generation,会向新generation中写入后续的版本信息。
48+
49+
在查询时,先在内存索引中通过用户指定的Key值,查找到该Key值对应的全部版本号,然后根据用户指定的版本号,从底层存储中查找到具体的 Value 值。当然,如果指定的版本号已经被etcd压缩删除,则无法再查询到该版本的Value值。
50+
51+
在etcd v3版本中,底层存储使用的是BoltDB,其中的Key是版本信息(main revision+sub revision)。这样,在查询时先通过上述B树索引查找到对应的版本信息,然后在BoltDB中通过版本信息查找相应的Value值。
52+
53+
## 环境搭建
54+
首先需要从 Golang 官方网站上下载最新的 Golang 包,笔者在开始写作时的最新版本是go1.10.darwin-amd64.tar.gz,下载完成后进行解压。
55+
56+
## 代码结构
57+
简单介绍其中各个模块的主要功能,如下所示。
58+
59+
- raft:Raft 协议的核心实现,其中只实现了基本的 Raft 协议,并未提供实现网络层相关的内容。
60+
- raft-http:Raft协议中各个节点发送消息时使用的网络层实现,该模块与raft模块紧密相关。
61+
- wal和snap:WAL日志和快照存储相关的实现。
62+
- store:etcd中的v2版本存储实现,v2版本的存储是完全的内存实现。
63+
- mvcc:etcd中的v3版本存储实现,v3版本的存储底层使用BoltDB实现持久化存储。
64+
- lease:租约相关的实现。
65+
- auth和alarm:权限和报警相关的实现。
66+
- etcdserver:etcd 服务端实现,它会基于上述模块提供的功能,对外提供一个 etcd 节点的完整功能。
67+
- client:v2版本客户端的具体实现,v2版本的客户端是通过HTTP+JSON的方式与服务端进行交互的。
68+
- clientv3:v3版本客户端的具体实现,v3版本的客户端是通过GRPC的方式与服务端进行交互的。
69+
70+
## 运行
71+
etcd 提供了单机模式和集群模式两种模式,单机模式比较简单,直接编译之前下载的源代码得到/bin/etcd二进制文件并运行即可。默认配置运行时,etcd服务端会监听本地的2379和2380两个端口,其中2379端口用于与客户端的交互,2380端口则是用于etcd节点内部交互(主要是发送Raft协议相关的消息等)。当etcd服务端启动时,我们可以使用etcdctl工具进行测试,关于etcdctl命令的使用,这里不再展开介绍,请读者参考官方文档进行学习。
72+
73+
首先介绍静态配置的启动方式,这种方式会预先将集群中各个节点的配置信息分配好,然后将集群中的节点逐个启动,这些节点将根据配置信息组成集群。
74+
75+
这里简单介绍一下上述命令使用的参数。
76+
77+
·--name:etcd集群中的节点名称,在同一个集群中必须是唯一的。
78+
79+
·--listen-peer-urls:用于集群内各个节点之间通信的 URL 地址,每个节点可以监听多个URL地址,集群内部将通过这些URL地址进行数据交互,例如,Leader节点的选举、Message消息传输或是快照传输等。
80+
81+
·--initial-advertise-peer-urls:建议用于集群内部节点之间交互的URL地址,节点间将以该值进行通信。
82+
83+
·--listen-client-urls:用于当前节点与客户端交互的URL地址,每个节点同样可以向客户端提供多个URL地址。
84+
85+
·--advertise-client-urls:建议客户端使用的URL地址,该值用于etcd代理或etcd成员与etcd节点通信。
86+
87+
·--initial-cluster-token etcd-cluster-1:集群的唯一标识。
88+
89+
·--initial-cluster:集群中所有的initial-advertise-peer-urls 的合集。
90+
91+
·--initial-cluster-state new:新建集群的标识。
92+
93+
当集群中各个节点按照上述配置分别启动后,集群会通过Leader选举选出一个Leader节点,另外两个节点将成为Follower节点。我们可以使用etcdctl命令检测当前集群的状态,etcdctl的相关使用方式请读者参考官方文档进行学习。
94+
2495
## 应用场景
2596

2697
etcd 在稳定性、可靠性和可伸缩性上表现极佳,同时也为云原生应用系统提供了协调机制。etcd 经常用于服务注册与发现的场景,此外还有键值对存储、消息发布与订阅、分布式锁等场景。
@@ -87,36 +158,5 @@ etcd 在稳定性、可靠性和可伸缩性上表现极佳,同时也为云原
87158

88159
这个的经典场景是搜索系统中建立全量索引。如果每个机器都进行一遍索引的建立,不但耗时而且建立索引的一致性不能保证。通过在 etcd 的 CAS 机制同时创建一个节点,创建成功的机器作为 Leader,进行索引计算,然后把计算结果分发到其它节点。
89160

90-
常用术语
91-
为了有效提高读者阅读的效率,本小节将总结后续常出现的专用术语,先混个眼熟,后续具体实现过程会继续深入。
92-
93-
术语 描述 备注
94-
Raft Raft算法,etcd实现一致性的核心 ectd-raft 模型
95-
Follower Raft中的从属节点 竞争Leader失败
96-
Leader Raft中的领导节点,处理数据提交 Leader协调集群
97-
Candidate 候选节点 当Follower接收Leader节点的消息超时会转变为Candidate
98-
Node Raft状态机的实例 Raft中涉及多个节点
99-
Member etcd实例,管理对应Node节点 可处理客户端请求
100-
Peer 同一个集群中的另一个Member 其他成员
101-
Cluster etcd集群 拥有多个ectd Member
102-
Lease 租期 关键设置的租期,过期删除
103-
Watch 监测机制 监控键值对的变化
104-
Term 任期 某个节点成为Leader, 到下一次竞选的时间
105-
WAL 预写式日志 持久化存储的日志格式
106-
MVCC 多版本并发控制 事务隔离的手段
107-
revision MVCC中的版本 每一次key-value操作都会有revision
108-
keyIndex Key的生命周期 记录一个key的生命周期中所涉及过的版本
109-
Client 客户端 向etcd发起请求的客户端
110-
111-
参考
112-
【一文入门ETCD】https://juejin.cn/post/6844904031186321416
113-
【etcd:从应用场景到实现原理的全方位解读】https://www.infoq.cn/article/etcd-interpretation-application-scenario-implement-principle
114-
【Etcd 架构与实现解析】http://jolestar.com/etcd-architecture/
115-
【linux单节点和集群的etcd】https://www.jianshu.com/p/07ca88b6ff67
116-
【软负载均衡与硬负载均衡、4层与7层负载均衡】https://cloud.tencent.com/developer/article/1446391
117-
【Etcd Lock详解】https://tangxusc.github.io/blog/2019/05/etcd-lock详解/
118-
【etcd基础与使用】https://zhuyasen.com/post/etcd.html
119-
【ETCD核心机制解析】https://www.cnblogs.com/FG123/p/13632095.html
120-
【etcd watch机制】http://liangjf.top/2019/12/31/110.etcd-watch机制分析/
121-
【ETCD 源码学习--Watch(server)】https://www.codeleading.com/article/15455457381/
122-
【etcdV3—watcher服务端源码解析】https://blog.csdn.net/stayfoolish_yj/article/details/104497233
161+
# 参考资料
162+
etcd技术内幕

_posts/2018-05-02-Etcd组成.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ categories: etcd
44
description: none
55
keywords: etcd
66
---
7+
# etcd架构设计
78

89
## 服务器状态
910
严格来说,ectd节点有三种角色:Leader、Flower、Candidate。

0 commit comments

Comments
 (0)