文章目录
- leader选举
- 日志复制
- 安全性
- preVote 阶段
- preVote 投票阶段
- preVote阶段的作用
- 集群成员变更
- etcd raft实践
- etcd raft写流程时序图
- 问题
- 如何保障消息的幂等性,不能重复提交
- 如何保障消息的原子性,不能提交一半
- raft wal日志的作用是
- MVCC方式的作用
- etcd 中如何实现读读并发的
- etcd中ACID的特性
- 要区分etcd中的事务以及boltdb中的事务的区别
leader选举
日志复制
安全性
- leader只能commit当前的term的日志,不能提交其他term的日志
- leader只能增加当前的日志,不能删除以前item提交的日志
- 只能选择日志最新的节点为leader
- 匹配特性,通俗来讲,就是要保证日志序列要一致
preVote 阶段
preVote 投票阶段
- 投票节点需要判断leader是否存在,并且心跳并没有超时
- 投票节点的时候需要判断被投票的节点的日志要大于本节点
- 被投票节点是否能够获得一半以上的点然后才能新增 term 然后再发起leader 选举
preVote阶段的作用
-
防止某个节点因为出现分区后,恢复后,再次发起leader选举,这样会影响到集群的稳定性(因为有新的term的话,那么leader就会退化为follow状态),此处因为他会先进入prevote阶段,因为此时该阶段回去判断是否日志索引记录多少,因此该节点不能进入leader选举流程(禁止进入leader选举,新增term)
-
如果出现网络分区(注意分区后节点数还是和分区前是一样的)
如果新分区的节点需要经过preVote
因为此时其他节点大概率还是保持和leader通信的 -
集群成员变更的时候,下线C-old节点的时候,可能会因为暂时失联再发起leader选举
集群成员变更
参考连接
etcd raft实践
etcd raft写流程时序图
问题
如何保障消息的幂等性,不能重复提交
- etcd中状态机(持久化数据库)中会存储“一致性索引consistent index”,这个是raft index(已提交日志索引) 的持久化,可以对比两个index可以防止重复提交情况,
- 如果说写入WAL日志成功了,然后写入状态机(持久化数据库)失败了,客户端返回失败了,客户端发起新的提交怎么办?这个就需要客户端也要保重幂等性,判断改请求是否已提交
如何保障消息的原子性,不能提交一半
- 如果宕机后,也可以重建日志(通过重放WAL日志),保障原子性
- 持久化数据库也会保障 “日志条目写入”以及“一致性索引consistent index”的原子性的写入(保证不会只写入其中一个),原理是通过 shading page 的方式实现,可自己查阅 资料
raft wal日志的作用是
- 如果宕机后,也可以重建日志(通过重放WAL日志),保障原子性
- 提高写入性能(顺序写入)
MVCC方式的作用
- 提高性能,可以实现并发的写,因为有不同的版本
- 可以实现查询历史版本
- 可以实现事务操作,每个事务都会有一个版本(大版本,小版本(事务中不同的操作都会有一个小版本))
etcd 中如何实现读读并发的
- etcd 中只会从buffer中读取,如果buffer中没有的话,再从状态机(持久化数据库)中查询
- buffer的查询不会阻碍到更新,因为更新是直接更新(持久化数据库),更新成功后 再进行buffer的更新
etcd中ACID的特性
- 原子性和持久性
- 如果宕机后,也可以重建日志(通过重放WAL日志),保障原子性
- 持久化数据库也会保障 “日志条目写入”以及“一致性索引consistent index”的原子性的写入(保证不会只写入其中一个),原理是通过 shading page 的方式实现,可自己查阅 资料
- 隔离性
- etcd 保证提交读的级别,都是当前读,不可保证可重复读,etcd 不会读到未提交读的部分
- 如果要保证可重复读,需要业务逻辑自己版本,cas操作
- 一致性
- 如果业务需要保证可重复读级别,就需要业务逻辑保证一致性
要区分etcd中的事务以及boltdb中的事务的区别
- etcd中的事务,可以实现读读、读写、写写并发,提高性能,不需要加锁
- 但是boltdb的事务,写写并发是需要加锁的,并且要根据版本号顺序的提交(提交和写入是异步的),写入只是写入内存,提交才需要写入日志中,并且写入和提交是要互斥的(防止写入一半就提交了)