Database design Mnesia中的安全、顺序和可扩展计数器

Database design Mnesia中的安全、顺序和可扩展计数器,database-design,erlang,mnesia,Database Design,Erlang,Mnesia,我正在用Erlang/OTP编写一个应用程序,希望在版本记录系统上使用顺序计数器 我首先用mnesia:dirty_update_counter实现了它们,但使用它的经验排除了这些硬要求: mnesia:dirty_update_counter 计数器必须具有以下属性: 严格按顺序执行-1 2后面跟着3等等 序列在一组分布式系统中共享,如果 你是以“3”的成绩来的吗 在“5”中,我需要知道我们输了 一些命令和命令应该重新同步 分布式数据库的安全性 mnesia:脏_更新_计数器不满足这两个要

我正在用Erlang/OTP编写一个应用程序,希望在版本记录系统上使用顺序计数器

我首先用mnesia:dirty_update_counter实现了它们,但使用它的经验排除了这些硬要求:

mnesia:dirty_update_counter 计数器必须具有以下属性:

  • 严格按顺序执行-1 2后面跟着3等等 序列在一组分布式系统中共享,如果 你是以“3”的成绩来的吗 在“5”中,我需要知道我们输了 一些命令和命令应该重新同步

  • 分布式数据库的安全性

mnesia:脏_更新_计数器不满足这两个要求


如何实现顺序数据库计数器?

好吧,既然Mnesia数据不能保证以原子方式复制,那么您必须以某种方式手动锁定。我看到三个备选方案(两个带锁,一个不带锁):

  • 在服务器上使用读锁 当您请求新版本时,返回表 号码。这意味着交易 不过

  • 使用中央服务器跟踪 版本号和增量的定义 它们是原子的,例如 在一个节点上有一个进程 你要的是版本号

  • 同步服务器 使用NTP并使用时间戳


你想过消息代理吗?通过加载和设置持久队列和持久消息,可以将其保存在Erlang中。构建一个消费者,将消息正文中的数字增加1,然后在确认原始数字时,将该新数字发布回新消息中的队列


不确定它是否适合您,但似乎一旦您手动发布正文中包含1的第一条消息,您就可以关机并运行了。

我打算建议使用一个erlang进程为您提供数字。由于erlang按顺序处理消息,因此可以保证将消息按顺序处理。坚持下去是必要的。上面的RabbitMQ建议是一种方法,但是如果您觉得这太过了,那么周期性地将进程存储到文件就足够了。gen_服务器应该足以满足您的需要。

也许最简单的答案就是您所要寻找的,只需获得一个写锁(用于复制同步)并生成一个事务函数,该函数获取计数器的当前值,将其递增并保存回数据库。当然,随着系统的扩展,您的开销会增加,但我建议您编写一个服务器,为您这样做,并在节点的子集上运行,这样锁争用就不会与集群大小直接关联。

只有一个问题:您到底需要这个数字还是只需要顺序?在后一种情况下,您可以使用时间戳作为订单标准。当我得到一个消息,然后另一个消息,我需要知道我是否应该有一个在中间-所以它必须严格顺序。所以你有消息到达不同的物理机器,你想识别他们,所以你绝对确定他们的顺序是什么?你确定你不会遇到这样的问题:尝试否定,只是想知道您的可用性要求是什么,等等。我应该在我的评论中更清楚-计数器需要在分布式(即2/3节点)中安全数据库,它是一个大型分区数据库的子分区的实例-所以我打算避免您指出的那样的问题。时间戳是不好的,因为它们不像我上面所说的那样严格按顺序排列。如果我有2个时间戳的事务,我不知道中间是否有一个缺失… mnesia:dirty_update_counter