共计 2781 个字符,预计需要花费 7 分钟才能阅读完成。
背景
2022 年,37 手游实现了业务双云架构的部署
2023 年,通过故障注入,确认任一单云故障下,都能够逃生到另外一朵云
此刻,尽管业务具备了双云双活能力,但也发现了一些边缘组件不具备,其中 cicd 依赖 nacos 就是其中之一
利用场景?
那么咱们在 nacos 的应用场景是什么呢?其实次要用在 CICD 编译这个环节
面临的问题
一旦腾讯云整体故障,那么咱们的 cicd 平台就无奈应用,即便业务逃生到另外一朵云,无论是利用公布、重启,都将受到影响,如下构图,cicd 单云
于是,咱们做了 cicd 双云 v1 版本
后期没有关注度到 nacos 的强依赖,在理论应用上,任然是单点(nacos 单云)
cicd v2 版本
一开始,将 nacos 当做无状态服务,间接双云部署,而后烟囱式拜访
cicd v2 版本存在的问题:批改配置后,配置数据不统一
在理论的故障注入演练中,咱们发现,在一朵云的 nacos 批改了配置后,尽管它们都是用的雷同的数据库,无奈同步到另外一朵云,如下架构
nacos 双云不能同步的起因
Nacos 利用会将数据库的配置数据缓存在本地内存,而后每 6 小时去全量 dump 更新一次,所以比方咱们从腾讯云 nacos 集群入口批改配置,批改了 nacos 数据库,然而阿里云 nacos 容器集群因为不晓得数据库配置已被批改,因而就导致,腾讯云是新批改的配置,阿里云还是旧的缓存数据,须要 6 小时后才会同步更新
那么腾讯云 nacos 容器集群内的所有 Pod 为什么是都是新的呢
nacos 集群内,是有一个横向告诉机制的,要搞明确这个问题,要先搞清楚,nacos 集群运作的以下几个原理
nacos 数据一致性原理:raft 算法
1.raft 算法选举 Leader 过程
1.1 如一个 nacos 集群有 3 个节点,节点一开始启动时都是 Follow 跟随者状态,会进入一个选举超时工夫,期待 Leader 或者 Candidate 发送心跳包
1.2 如果期待超时,如第一个节点期待超时就会变为 Candidate 候选者,向其余节点发动投票选举本人为 Leader
1.3 其余 Follow 节点收到 Candidate 发动的投票批准后,第一个节点节点成为 Leader
2.raft 算法的选举超时机制
在 raft 算法中,选举超时工夫(Election Timeout)是用来定义 Follower 在主动转化为 Candidate 前的等待时间
默认的选举超时工夫是在固定值(1000ms)的根底上,减少 150ms 到 300ms 随机值的值。这个工夫设置是为了避免集群中的所有节点同时发动投票,导致选举无奈进行
例如,如果集群由 3 个节点组成,每个节点的选举超时工夫别离为 168ms、210ms 和 200ms。在这个过程中,最先达到选举超时工夫的节点会最先成为 Candidate,并向其余两个节点发动投票申请。如果其余节点收到投票申请并且返回了投票,那么最先成为 Candidate 的节点会因为取得了过半数节点的投票而从 Candidate 状态转变为 Leader 状态
每个节点的选举超时工夫是随机调配的,这个随机工夫范畴是 150ms 到 300ms,能够无效地避免所有节点同时发动投票。如果一个节点在选举超时工夫内没有收到来自 Leader 的心跳音讯,它会从 Follower 状态主动转化为 Candidate 状态,并发动选举
nacos 数据一致性原理:读写申请
nacos 集群为了保证数据一致性,无论读写申请都会通过 Leader 节点,架构如下
如上图,第一步:客户端申请 nacos 的入口 LB,随机申请到 Follower2,第二步:Follower2 会将读写申请都转给 Leader 节点,第三步:如果是一个读申请,那么 Leader 节点会将读申请解决后再返回给 Follower2,第四步:再由 Follower2 节点返回给客户端数据
通过下面 4 个步骤,能够保障所有的写申请都由 Leader 节点解决,从而保证数据的一致性
nacos 数据一致性原理:Leader 节点故障期间
如果 Leader 节点挂掉了,那么集群会进行新的选举产生新的 Leader,之前挂掉的 Leader 重启后作为 Follower 退出集群,并同步新选举的 Leader 上的数据。这样能够保障即便在 Leader 节点故障的状况下,也能保证数据的可靠性和一致性
那么 Leader 故障或者失联期间,Follower 是否单独解决呢?答案是必定的,见架构图
如上图,如果 Leader 故障,且又没有新的的 Leader 产生时,Follower 接到申请后,还是依照原门路申请 Leader,但此时是不通的,所以这个中央 Follower 就有个超时机制,毫秒级,如果拿不到 Leader 的返回,就将缓存的数据返回给客户端
nacos 数据一致性原理:节点数据同步
Nacos 通过发送心跳的形式来放弃 Leader 和 Follower 之间的数据同步,Leader 节点会定期向每个 Follower 节点发送心跳,这个心跳的默认工夫是 30 秒,也就是 30 秒同步一次,并带上所有的 key 和 key 对应的工夫戳。Follower 节点收到心跳后,会查看其中的 key 是否存在或者工夫戳是否较小,如果不满足条件,则会向 Leader 发送申请拿取最新的数据。这样能够保障各个节点数据的实时性和一致性
基于 Nacos 的原理,37 手游的 nacos 双云双活设计
已知,Nacos 能够在集群节点内,Follower 节点都会从 Leader 节点同步数据,但问题是不同集群间,Nacos 是无奈做到同步的,也就是说,Nacos 是有肯定状态的,并非齐全无状态,看看新旧架构比照
老的架构做法
从上图能够看到,老的架构因为是 2 个集群,尽管他们都读取了同一个数据库,但当任一一朵云的 Nacos 有写操作,都不会及时同步到另外一朵云,此时两朵云读取的配置信息是有差别的,起因是因为 nacos 有一层缓存存在,这个缓存工夫默认 6 小时,每隔 6 小时,Leader 会全量 dump 数据库的信息到本地缓存
新的架构做法
如上图,将 2 集群合并成一个集群,双云之间通过专线买通网络,拜访和读取还是烟囱式,只是数据库还是单边,这样做的益处是,在任一一朵云批改数据,都会将腾讯云和阿里云所有节点都同步到,因为他们是同一个集群,应用原生的 nacos 集群同步形式
总结
在 nacos 集群的应用上,咱们的业务场景次要还是 cicd 公布时须要读取配置,是一个读多写少的场景,基本上能够认为,只有读胜利,咱们的 cicd 就能残缺运行,因而在设计上,咱们优先思考读场景的可用性,无论哪一朵云故障,咱们的 cicd 零碎都能失常运行,因为在个别故障状况下,咱们也很少会写 nacos
因而从架构上看,在腾讯云故障下,写是无奈在阿里云进行的,因为阿里云只有 2 个节点,无奈投票成为 Leader,也就无奈实现写入,因而失常状况下,是读写 nacos 双云双活,极其状况下,阿里云故障,腾讯云读写 nacos 无异样,腾讯云故障,阿里云能够读,但无奈写