Golang Go语言中基于 Gossip,新节点加入集群如何同步集群中现有数据和同步过程收到的新数据更新?

Golang Go语言中基于 Gossip,新节点加入集群如何同步集群中现有数据和同步过程收到的新数据更新?

  • 项目简介: 一个分布式的 mqtt 的服务

  • 场景描述: 基于 Gossip,使用的 memberlist 库,新节点加入集群,需要同步集群中已连接的客户端信息和订阅信息,同时新节点可能还会收到集群中其他节点的广播数据更新。

  • 问题:

    1. 新节点如何保证数据的一致性,当其他节点已经存储了百万的客户端信息。新节点同步时如何处理?
    2. 同步现有数据时,收到的更新通知如何处理。
  • 我的思路: 新节点加入后,将收到的更新数据暂时缓存直到和其他节点同步完成再开始处理更新。同步信息过大只能分批次同步。但是 gossip 协议中的推拉模式下。一定时间推拉一次,如果数据量非常大的时候网络开销太大。不说百万,即使几万的客户端信息,一次推拉也是很大的开销。如果分批次处理代码就会变复杂。所以想和大家讨论一下如何解决。


更多关于Golang Go语言中基于 Gossip,新节点加入集群如何同步集群中现有数据和同步过程收到的新数据更新?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

你这个需求上 raft 呀, gossip 适合 eventually consistent.

更多关于Golang Go语言中基于 Gossip,新节点加入集群如何同步集群中现有数据和同步过程收到的新数据更新?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


raft 的强一致性,但是新的节点进入还是必须同步之前已经存在的数据吧 ? 我选 gossip 的原因是我更看重可用性和分区性。我刚才想了一下决定不同步订阅和客户端信息了。像 redis 集群一样直接广播收到的消息,让各个节点自行检查自己是否要要处理。

个人感觉解法是,将状态放到专门的地方( redis 等等),或自己设计一个增量同步的协议,自己保证最终一致性,后者感觉会比较多坑。memberlist 基于那篇 SWIM 的论文,其 boardcast 是用于少量事件的同步的,最初应该就不是设计用来广播大量数据的。

哥们最终是怎么实现的呢?可以分享一下吗

直接用的别人的 raft 库,只要自己实现状态机就好了。https://github.com/lni/dragonboat

在Golang中,基于Gossip协议实现新节点加入集群后的数据同步,是一个涉及分布式系统一致性的关键问题。以下是对该过程的详细解答:

一、同步集群中现有数据

  1. 当新节点加入集群时,它会通过Gossip协议向集群中的其他节点发送请求,以获取现有数据。
  2. 集群中的其他节点会响应这些请求,并将它们所掌握的数据部分地发送给新节点。
  3. 新节点在接收到这些数据后,会进行合并和整理,以形成完整的集群状态视图。

二、同步过程收到的新数据更新

  1. 在新节点加入并同步完现有数据后,它会继续通过Gossip协议与其他节点进行通信。
  2. 当集群中有新数据产生或更新时,这些变化会通过Gossip协议在集群中传播。
  3. 新节点会接收到这些更新的数据,并更新其本地状态,以保持与集群的一致性。

Gossip协议通过其高效的传播机制和去中心化的结构,能够确保新节点在加入集群后能够迅速同步现有数据,并在后续过程中实时更新其本地状态,从而维持整个集群的数据一致性。

回到顶部