【问题标题】:Implement master-slave实现主从
【发布时间】:2012-09-14 17:47:52
【问题描述】:

在 Ubuntu 上运行。程序是用 C++ 编写的。 我有 2 个进程在不同的主机上运行,​​一个是主进程,一个是从属进程(它们之间没有任何优先级,只有一个处理请求。)。 只有一个进程可以成为主进程并处理请求。 两个进程始终启动,万一它们崩溃,有一个看门狗会重新启动它们。

主机通过网线连接。

我的计划是要求从一个到另一个保持活动状态,如果奴隶停止从主人那里获得保持活动状态,它需要将其状态更改为主人。 当 master 再次启动时,它首先等待保持活动状态,以防不将其设置为 master。如果将其设置为从属角色。

我很乐意听取您的意见:

如何防止两者同时成为大师?这是我最关心的问题。启动和连接失败时,如何防止2个master同时出现?

您认为查询keep alive 好还是发送keep alive 好? (在我看来,最好是要求保持活力而不是推动)

欢迎任何其他好的建议和陷阱。

【问题讨论】:

    标签: c++ linux master-slave stability


    【解决方案1】:

    我这样做的方法是让每个进程产生一个心跳线程,该线程每秒发送一次 UDP 数据包,并侦听来自其他进程的传入 UDP 数据包。如果心跳线程在指定的时间(例如 5 秒)内没有收到来自其他进程的任何 UDP 数据包,则假定其他进程已关闭并通知父线程它现在应该成为主线程。

    心跳发送/监听之所以在专用线程中完成是因为这样如果主线程忙于进行冗长的计算,就不会导致心跳UDP数据包暂时不发送。这样一来,主线程中的算法就不需要是实时的,以避免触发虚假的故障转移。

    这里还有一个问题要考虑...如果网络问题暂时中断了两台主机之间的通信会发生什么? (例如,一些小丑或 QA 测试人员将以太网电缆拔掉 1 分钟,然后将其重新插入)在这种情况下,两个进程都将停止接收来自另一个进程的 UDP 数据包,因此两个进程都会认为另一个进程已经消失,并且两者都将成为主进程。然后当重新连接网线时,你有两个主进程同时运行,这不是你想要的。因此,您需要一些方法让两个主进程决定两个主进程中的哪一个应该将自己降级为从属状态,以满足汉兰达原则(“只能有一个!”)。这可以像“IP 地址最小的主机应该保持主控”一样简单,或者您可以让每个心跳包包含发送进程的正常运行时间,而正常运行时间较大的主机应该保持主控,等等。

    【讨论】:

    • 我见过类似的方法。 Master/Slave 的主要问题是确定当有某种中断(例如 LAN 连接)或一个被关闭并重新启动时谁应该是 Master。如果两者之间存在复制的持久数据存储,那么谁应该是 Master 非常重要,并且您必须确定谁在其持久存储副本中拥有最新数据。
    • 另一种方法是,如果有一段时间的心跳丢失,那么每个人将开始主动向另一个人发送查询。这将有助于诊断 LAN 连接问题。
    • 这是我实现它的方式(推送 UDP 的线程),但我仍在考虑更改为查询而不是推送。但是……我最关心的是选择谁是主人?我不明白在 2 个进程同时启动的情况下你是如何克服这个问题的,以及在连接失败时你是如何克服它的?
    • 两个进程同时启动,你可以让每个进程监听传入的数据包几秒钟,然后再决定是否让自己成为主进程——这样它就有时间收集信息关于还有谁,以及其他进程是否更适合成为大师。至于在出现连接故障时解决问题——我不知道一个好的解决方案(除非有一个备用网络可以在主网络出现故障时使用?)
    【解决方案2】:

    解决此问题的典型方法是举行选举。系统中的每个人都共享他们将用作算法输入的数据,以便每个人都能得出相同的结论。

    例如:对等方都(都)相互发送一些唯一标识符(MAC 地址,或 pid,或高精度进程开始时间,例如)。然后每个对等方使用相同的比较来确定获胜者(例如,最大值)。然后他们将结果相互通知。

    有关瞬时连接故障的问题,请参阅Byzantine Generals

    另见:

    【讨论】:

    • 非常感谢。我喜欢给问题起名字。您能否举一个在 2 个节点之间进行简单选择的示例?比起连接性,我更关心同时启动。
    猜你喜欢
    • 2013-01-23
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2019-05-22
    相关资源
    最近更新 更多