首页 > 首页 > 应用服务 > 分布式协调 > Etcd > [ etcd ] 重要知识点备忘录
2024
05-23

[ etcd ] 重要知识点备忘录

kubernetes为什么使用etcd而不用zookeeper?

ZooKeeper 是一款与 etcd 十分类似的键值对存储数据库,都是分布式系统协调和元数据存储。但是, etcd 踩在前人的肩膀上,其参考了 ZooKeeper 的设计和实现经验。从 Zookeeper 汲取的经验教训无疑为 etcd 的设计提供了支撑,从而帮助其支持 Kubernetes 等大型系统。对 Zookeeper 进行的 etcd 改进包括:

  • 动态重新配置集群成员
  • 高负载下稳定的读写
  • 多版本并发控制数据模型
  • 可靠的键值监控
  • 用于分布式共享锁的 API

etcd是go语言编写的,天然契合kubernetes集群(亲儿子嘛),并且etcd 开箱即用地支持多种语言和框架。Zookeeper 拥有自己的自定义Jute RPC 协议,该协议对于 Zookeeper 而言是完全唯一的,并限制了其受支持的语言绑定,而 etcd 的客户端协议则是基于 gRPC 构建的,gRP 是一种流行的 RPC 框架,具有 go,C ++,Java 等语言支持。同样,gRPC 可以通过 HTTP 序列化为 JSON,因此即使是通用命令行实用程序(例如curl)也可以与之通信。由于系统可以从多种选择中进行选择,因此它们是基于具有本机工具的 etcd 构建的,而不是基于一组固定的技术围绕 etcd 构建的。

在综合考虑功能,支持和稳定性时,etcd 相比于 Zookeeper,更加适合用作一致性的键值存储的组件。总结一句话,etcd的功能和性能以及对其它语言的支持友好度方面etcd是有明显优势的。

etcd集群节点数量的相关说明

etcd 是基于 raft算法的分布式键值数据库,生来就为集群化而设计的,由于Raft算法在做决策时需要超半数节点的投票,所以etcd集群一般推荐奇数节点,如3、5或者7个节点构成一个集群。

etcd官方推荐3、5、7个节点,虽然raft算法也是半数以上投票才能有 leader,但奇数只是推荐,其实偶数也是可以的。如 2、4、8个节点。下面分情况说明:

  • 1 个节点:就是单实例,没有集群概念,不做讨论
  • 2 个节点:是集群,但没人会这么配,这里说点废话:双节点的etcd能启动,启动时也能有主,可以正常提供服务,但是一台挂掉之后,就选不出主了,因为他只能拿到1票,剩下的那台也无法提供服务,也就是双节点无容错能力,不要使用。
  • 3 节点:标准的3 节点etcd 集群只能容忍1台机器宕机,挂掉 1 台此时等于2个节点的情况,如果再挂 1 台,就和 2节点的情形一致了,一直选,一直增加任期,但就是选不出来,服务也就不可用了
  • 4 节点:最大容忍1 台 服务器宕机
  • 5 节点:最大容忍 2 台 服务器宕机
  • 6 节点:最大容忍 2 台 服务器宕机
  • 7和8个节点,最大容忍3台 服务器宕机

以此类推,9和10个节点,最大容忍4台 服务器宕机,总结以上可以得出结论:偶数节点虽然多了一台机器,但是容错能力是一样的,也就是说,你可以设置偶数节点,但没增加什么能力,还浪费了一台机器。同时etcd 是通过复制数据给所有节点来达到一致性,因此偶数的多一台机器增加不了性能,反而会拉低写入速度。

etcd集群节点数越多越好吗?

那可能有同学会说,我搞个几十上百台服务器做etcd集群,那集群的整体性能不是屌炸了,etcd集群永不会停止嘛。有这个想法那就大错特错了,etcd 集群是一个 Raft Group,没有 shared。所以它的极限有两部分,一是单机的容量限制,内存和磁盘;二是网络开销,每次 Raft 操作需要所有节点参与,每一次写操作需要集群中大多数节点将日志落盘成功后,Leader 节点才能修改内部状态机,并将结果返回给客户端

因此节点越多性能越低,并且出错的概率会直线上升,并且是呈现线性的性能下降,所以扩展很多 etcd 节点是没有意义的,其次,如果etcd集群超过7个达到十几个几十个,那么,对运维来说也是一个不小的压力了,并且集群的配置什么的也会更加的复杂,而不是简单易用了。因此,etcd集群的数量一般是 3、5、7, 3 个是最低标准,7个也就是最高了。

etcd 数据压缩与磁盘清理

etcd 集群在频繁写入的场景下运行一段时间,就会发现数据占用的空间达到上限,默认上限为 2GB,当达到 2GB 时写入就会报错,需要进行数据的压缩与清理,默认 2GB 的上限可通过参数 --quota-backend-bytes 进行调整。

查看 etcd 节点空间占用

# etcdctl --endpoints=127.0.0.1:2379 -w table --user=user:password endpoint status

在输出结果中,DB SIZE 字段显示了 etcd 节点占用的空间大小。

获取当前版本 revision

# rev=$(etcdctl --endpoints=127.0.0.1:2379 -w json --user=user:password endpoint status | egrep -o '"revision":[0-9]' | egrep -o '[0-9].')

revision 是 etcd 全局修订编号,每次数据修改(put, del)都会导致 revision 加 1。etcd mvcc 机制,导致同一个 key,在多次变更后,会存在多个版本,实际上很多时候,我们只需要最新的那个版本,其他旧版本都是可以清除的,这样能够减少内存和磁盘空间占用。etcd 快照备份也会对应一个 revision 编号,相当于是备份某个特定 revision 编号时的快照。

压缩所有旧版本

压缩旧版本,并不会立刻释放空间。

# etcdctl --endpoints=127.0.0.1:2379 --user=user:password compact $rev

整理多余的空间,释放空间

# etcdctl --endpoints=127.0.0.1:2379 --user=user:password defrag

注意:
在启动 etcd 服务时,通常会设置 --auto-compaction-retention 参数,实现自动压缩。根据实践发现该参数只会做碎片整理,不会实际释放空间,还是需要使用 etcdctl compact 和 etcdctl defrag 清理空间。

[ etcd ] 重要知识点备忘录 - 第1张  | 架构迷
最后编辑:
作者:摘星怪
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。