本篇内容主要来源于自己学习的视频,如有侵权,请联系删除,谢谢。上一节我们学习了 etcd 读请求执行流程,这一节,我们来学习 etcd 写请求执行流程。
流程二Quota 模块主要用于检查下当前 etcd db 大小加上你请求的 key-value 大小之和是否超过 了配额(quota-backend-bytes)。 如果超过了配额,它会产生一个告警(Alarm)请求,告警类型是 NO SPACE,并通过 Raft 日志同步给其它节点,告知 db 无空间了,并将告警持久化存储到 db 中。最终,无论 是 API 层 gRPC 模块还是负责将 Raft 侧已提交的日志条目应用到状态机的 Apply 模块, 都拒绝写入,集群只读。
如果填的是个小于 0 的数,就会禁用配额功能,这可能会让db 大小处于失控,导致性能下降,不建议你禁用配额。2、检查 etcd 的压缩(compact)配置是否开启、配置是否合理。
压缩时只会给旧版本Key打上空闲(Free)标记,后续新的数据写入的时候可复用这块空间,db大小并不会减小。
如果需要回收空间,减少 db 大小,得使用碎片整理 (defrag), 它会遍历旧的 db 文件数据,写入到一个新的 db 文 件。但是它对服务性能有较大影响,不建议你在生产集群频繁使 用。调整后还需要手动发送一个取消告警(etcdctl alarm disarm)的命令,以消除所有告警, 否则因为告警的存在,集群还是无法写入。
这个注意别忘记了!!!
流程3通过流程二的配额检查后,请求就从 API 层转发到了流程三的 KVServer 模块的 put 方 法。
流程4通过检查后会生成一个唯一的 ID,将此请求关联到一个对应的消息通知 channel(用于接收结果),然后向 Raft 模块发起(Propose)一个提案(Proposal)。 Raft 模块发起提案后,KVServer 模块会等待此 put 请求,等待写入结果通过消息通知 channel 返回或者超时。
流程5Raft 模块收到提案后,如果当前节点是 Follower,它会转发给 Leader,只有 Leader 才能 处理写请求。
流程 7Apply 模块主要用于执行处于 已提交状态的提案,将其更新到状态机。
主要依赖 WAL 日志,因为提交给 Apply 模块执行的提案已获得多数节点确认、持久化, etcd 重启时,会从 WAL 中解析出 Raft 日志条目内容,追加到 Raft 日志的存储中,并重 放已提交的日志提案给 Apply 模块执行。
etcd 通过引入一个 consistent index 的字段,来存储系统当前已经执行过的日志条目索 引,实现幂等性。2.6、MVCC 模块
因为 Raft 日志条目中的索引(index)字段,而且是全局单调递增的,每个日志条目索引 对应一个提案。 如果一个命令执行后,我们在 db 里面也记录下当前已经执行过的日志条 目索引,就可以解决幂等性问题了。当然还需要将执行命令和记录index这两个操作作为原子性事务提交,才能实现幂等。
流程 8 和 9MVCC 主要由两部分组成,一个是内存索引模块 treeIndex,保存 key 的历史版本号信 息,另一个是 boltdb 模块,用来持久化存储 key-value 数据。
hello: revision{2,0}2.6.2、boltdb
这里的 2,0 具体指的是什么呢?
这里不太懂,有清楚的朋友,请不吝赐教。
写入 boltdb 的 value, 并不是简单的"world",如果只存一个用户 value,索引又是保存 在易失的内存上,那重启 etcd 后,我们就丢失了用户的 key 名,无法构建 treeIndex 模块 了。因此为了构建索引和支持 Lease(租约) 等特性,etcd 会持久化以下信息:
注意: 在以上流程中,etcd 并未提交事务(commit),因此数据只更新在 boltdb 所管理 的内存数据结构中。如果我们每次更新都提交事务,etcd写性能就会较差。
事务提交的过程,包含 B+tree 的平衡、分裂,将 boltdb 的脏数据(dirty page)、元数 据信息刷新到磁盘,因此事务提交的开销是昂贵的。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |