【问题标题】:Ordering of Mnesia eventsMnesia 事件的排序
【发布时间】:2011-05-18 09:56:20
【问题描述】:

我们正在开发一个应用程序,其中分布式系统中不同节点上的多个进程订阅 mnesia 事件。该表是从其中一个节点上的一个进程写入的。

但是,我们是否可以确保按照与桌面上的操作相同的顺序接收事件,却产生了不确定性。

例如:

mnesia:delete(tab1, SomeRec),
mnesia:write(tab1, SomeOtherRec)

如果我们有时在写入事件之后得到删除事件,我们的设计将无法正常工作,我们将不得不创建一些其他类型的通知机制。

另外,对不同表(来自同一进程)的操作怎么样?

mnesia:write(tab1, SomeRec),
mnesia:write(tab2, SomeOtherRec)

我们能否确保总是先从 tab1 获取事件,然后再从 tab2 获取事件?在所有进程和所有节点上?

【问题讨论】:

  • 不知何故,我觉得您正在尝试使用 mnesia 事件来更好地完成不同的事情。但是,我不能说为什么。你能详细说明你想对这些表事件做什么吗?
  • 完全有可能。但无论如何解决这个问题会很有趣。

标签: events erlang mnesia subscribe


【解决方案1】:

Paxos 是您正在寻找的解决方案。使接受值的选择是先前接受的提案的最大值。这将创建一个序列,您可以使用它来订购您的说明。

【讨论】:

    【解决方案2】:

    我不知道默认情况下 mnesia 是否会做你想做的事,但假设它不会做,那么也许你需要开始研究分布式共识算法的使用,例如Paxos?有一个lib_paxos 形式的实现,这是一个 GPL 许可的开源库。

    不用说,这会影响您的表现,但要确保一致性。

    【讨论】:

    • 不幸的是,这不是一个选项。要么是 mnesia 正常运行,要么我们必须创建自己的通知机制。
    • 是的 - 我(有点)暗示 Paxos 是一种在分布式环境中实现这一目标的稳健方式......
    【解决方案3】:

    对于整个 Erlang,从进程 A 到进程 B 的消息发送保证始终是有序的。

    但是,对于两个以上进程之间的消息,你不能保证从A发送到B的消息会在从C发送到B的消息之前到达,即使A的消息是全球最先发送的。调度程序、网络延迟或网络问题(尤其是如果AC 不在同一个节点上)可能是很难提供此类保证的好例子。

    如果您的所有事件都是从同一个进程发送的,那么排序是肯定的。否则,你不能相信事件的顺序。

    至于 mnesia 事件,它们都在mnesia_subscr.erl 中进行管理,这是一个单独的 gen_server 负责转发节点的所有事件,无论表如何。因此,这应该遵守AB 的原则并保证事件有序。

    【讨论】:

    • 我了解进程之间的消息总是有序的。但是,mnesia 是否总是按照操作在调用进程上发生的顺序发送消息?例如。如果在调用 mnesia:write 时锁定表以进行写入,这会导致事件延迟并首先发送其他事件吗?
    • 这取决于您如何实现事件发送。它是在交易中完成的,一旦完成,等等?据我所知,你永远不应该在事务内部做有副作用的事情,因为它可能会被重试几次。
    • @IGTA:Lii 说的是 mnmesia 表事件,所以关于这些是如何实现的也是一个问题。这些是由单个内部进程发送的(每个节点?每个表?)
    • 啊抱歉,我没听明白。订阅者事件在 'mnesia_subscr.erl' 中管理,它被实现为 gen_server。所以是的,所有消息都来自该给定节点的同一进程,无论是什么表。我将编辑我的答案以添加此信息。
    • 这听起来有点让人放心。 “这应该因此坚持......”大约只要我们遇到问题,但很高兴听到其他人做出同样的分析。
    猜你喜欢
    • 2010-12-26
    • 2022-06-16
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多