Mnesia 中安全、顺序且可扩展的计数器

发布于 2024-07-15 19:46:58 字数 467 浏览 9 评论 0原文

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

我首先用

mnesia:dirty_update_counter
but the experience of using it drove out these hard requirements:

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

  • 严格顺序 - 后面跟着 1 2 后跟 3 等等 该序列在一组分布式系统之间共享,如果我 把你打成“3”然后你就来了 在“5”中我需要知道我们输了 一些通信应该重新同步

  • 与分布式数据库安全

mnesia:dirty_update_counter
meets neither of these requirements.

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

I am writing an application in Erlang/OTP and want to use sequential counters on a version recording system.

I first implemented them with

mnesia:dirty_update_counter

but the experience of using it drove out these hard requirements:

The counters must have the following properties:

  • be strictly sequential - 1 followed
    by 2 followed by 3 etc, etc
    the sequence is shared across a distributed set of systems and if I
    have you down as a '3' and you come
    in a '5' I need to know we have lost
    some comms and should resync

  • safe with a distributed database

mnesia:dirty_update_counter

meets neither of these requirements.

How could I implement a sequential database counter?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

<逆流佳人身旁 2024-07-22 19:46:58

好吧,由于 Mnesia 数据不能保证以原子方式复制,因此您必须以某种方式手动锁定。 我看到三种替代方案(两种带锁定,一种不带锁定):


  • 当您请求新版本时表
    数字。 这意味着交易
    不过。

  • 使用中央服务器进行跟踪
    版本号和增量
    他们原子地,例如通过
    在你的一个节点上有一个进程
    您要求提供版本号。

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

Well, since Mnesia data is not guaranteed to replicate atomicly you have to manually lock somehow. I see three alternatives (two with locking and one without):

  • Using read locks on the
    table as you request a new version
    number. That implies transactions
    though.

  • Use a central server that keeps track
    of the version numbers and increment
    them atomically, for example by
    having a process on one of your nodes
    which you ask for version numbers.

  • Synchronize your servers
    with NTP and use timestamps.

合约呢 2024-07-22 19:46:58

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

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

Have you though about a Message Broker? You could keep it in Erlang by loading up RabbitMQ and setting up a durable queue and persistent messages. Build a consumer that increments a number in the message body by 1 then publishes that new number back to the queue in a new message as it acks the original one.

Not sure it would work for you but it seems like once you manually publish the first message with 1 in the body you would be off and running.

岁月如刀 2024-07-22 19:46:58

我打算推荐一个为你提供数字的 erlang 进程。 由于 erlang 按顺序处理消息,因此可以保证按顺序获取它们。 无论如何,坚持它们是必要的。 上面的 RabbitMQ 建议是一种方法,但如果您觉得它太过分了,那么只需定期将进程存储到文件中就足够了。 gen_server 应该足以满足您的目的。

I was going to suggest an erlang process that serves up numbers for you. Since erlang processes messages sequentially you would be guaranteed of getting them in order. Persisting them would be necessary somewhow. The RabbitMQ suggestion above is one way but if you feel like it's overkill then just having the process store to a file periodically should be sufficient. A gen_server should be sufficient for your purposes.

等风来 2024-07-22 19:46:58

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

Perhaps the simplest answer is what you are looking for, simply by getting a write lock (for replicated syncing) and making a transactional function that gets the current value of the counter, increments it and saves it back to the DB. Certainly you will get increased overhead as the system scales, but I would recommend writing a server that does this for you and run that on a subset of the nodes, so the lock contention is not directly linked with the cluster size.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文