问题描述: Hasor-RSF 需要一个注册中心。而这个注册中心我想把它设计可以支持集群部署的,这就来带了分布式下服务注册状态一致性的问题。
好了下面开始正文,写的比较潦草。
----------------
ZooKeeper 作为数据中心问题。后来发现单纯使用 ZK 有这么几个问题:
-
ZK 配置繁琐,整个 Center 所有配置加起来 90% 都是在配置 ZK。 这让以后维护管理 Center 配置会变的复杂,不符合 最简化 的设计初衷。
-
开发者在使用 RSF 作为 RPC 框架时并不会引入 ZK 。使用 ZK 的目的是为了同步 Center 的服务数据,因为 ZK 的设计是让开发者以 Client 形式使用它。 这就造成了如果采用 ZK 作为分布式协调者。一个基于 RSF 的 RPC 场景需要(APP、Center、zkServer)三个角色。这样会复杂化部署环境。
-
因为 问题 2 的存在,RSF-Center 采用 内置 ZK Server 的方案,结果发现。 内置 ZK ,相当于 ZK 版本固定死。这对 center lib 化是一个沉痛打击。这又印证了 zk 建议 Client 形式使用它,这一特性。
-
Hasor 对于外部依赖的看法一直是(只用,不扩展,拒绝改写),实际情况中发现,在这个原则下 ZK 经常会有一些小问题。这使得使用 ZK 不得不做很多额外的保障工作。小问题例如:启动选举过程中异常、链接断开之后 Watcher 需要重新注册。
-
于是计划放弃 ZK另寻它路。
数据库作为数据中心载体的问题:
- 需要部署数据库,会产生(APP、Center、DB)三个角色,会复杂化部署环境。
- 需要解决双写覆盖问题。
- 当服务的规模达到,万级别时,双向的订阅关系就会超过数据库承载上限。进而需要引进分表分库,架构演进上会变得复杂。
- 于是放弃 DB 方案。
使用外部分布式缓存
- 和前两个方案一样,会产生(APP、Center、xxx)三个角色,这样会复杂化部署环境。
- 同样会遇到 DB 上出现的双写覆盖问题。
- 于是放弃 分布式缓存方案。
经典 “Paxos算法”,寻找分布式系统数据存储的最终方案尝试。
-
不得不说Paxos算法,确实是预想中的一样,比较晦涩难懂。也充分印证了是一个 难者不会会者不难的东西。它的经典在于:1 二阶段递交、2 半数投票通过即可确认数据被写入。
-
算法本身并没有给出工程样例,这在实现上让人比较难以下手。如果仅实现写入功能,对于 Center 来说 数据的一致性问题并没有彻底解决,因为还有读的问题。
-
为了保证数据一致性,还要额外引入数据同步机制。同样需要通过 Paxos 选出半数一致的最大 number 然后去增量同步数据。
-
数据增量问题,同样也有困惑不好解决。即便增量同步完成了,也无法保证如果节点处于少数派,增量同步并不能保证数据是最新的问题。
-
此外还有活锁问题。
-
最终放弃 经典Paxos 的原因是,虽然算法可以保证集群对数据的写入的连贯性,但是任意节点读数据无法保证最新。
Raft,这货是在2013年提出的,比起老大哥Paxos晚了将近 25年,先进性自然而言会比 Paxos 好一些。
- 值得推荐的链接:
- Raft 的经典在于强化了 Leader 的地位,Leader 负责写。这个算法解决了数据一致性问题。
- 工程实践上也十分方便。到目前为止,已经有很多 raft 的库可以选择。
- 单点问题:所有写操作都要通过 Leader 进行,那么 Leader 的稳定性尤为重要。因为 Leader 的写变成了单点。
- 鲁棒性:当 Leader 选举过程中整个集群无法提供写服务。这个是个大问题,对于大量写的场景 Raft 一旦从新选举 Leader 会 block 整个集群的服务。
- 基于单点问题,Raft 被放弃。
经典 “Paxos算法”,的演进 “Multi-Paxos”
-
这货在 经典Paxos 之上 增加了一个 Leader 的概念。Leader 负责递交提案。比起 Raft 好处是 Multi-Paxos 允许某一个时间出现多个主,因此不用担心 重新选举Leader 会导致集群block 的问题。
-
多个主争抢递交提案,理论上会存在冲突。但是 Paxos 的经典在于,任意一个值的确定都要经过半数同意。因此,即便是在多两个主。整个集群的写入依然会保证一致性。
-
这个算法虽然出现了 Leader 角色,但是并没有像 Raft 那样特别强调 Leader 的地位。
-
另外 Multi-Paxos 和 Paxos 一样,允许日志的连续性出现空洞。 这一点 Center 是可以接受的必经,我只要最终一致性,不要连续一致性。
-
写到这里似乎 Multi-Paxos 就是理想中的伊甸园了。但是,这货实现起来好想没有那么简单。
-
另外活锁、读、增量数据同步。这些问题也是需要在仔细考虑的。
JGroups 意外的收获。
- 复杂,JGroups 是为了解决 组播,等网络传输问题的。并不是被设计用来解决 分布式一致性问题。 引入 JGroups 显得过重。
- 协议栈虽然是亮点,但是 Center 的核心问题是 “分布式一致性”。
- 如果放弃 ZK 那么 ,RSF-Center 计划,一切数据传输都基于 RSF 传输协议。JGroups 传输层上的扩展又回让人重新陷入,内置 ZK Server 的老路。
- 放弃 JGroups
最后最后: 看样子需要自己结合 Paxos 和 Raft,重新设计一个新的算法了,似乎工程量巨大。
欢迎大家一起探讨,有没有更好的办法