在 OTP/Erlang 中将 ID 映射到进程的惯用方式是啥?

Posted

技术标签:

【中文标题】在 OTP/Erlang 中将 ID 映射到进程的惯用方式是啥?【英文标题】:What is the idiomatic way of mapping IDs to processes in OTP/Erlang?在 OTP/Erlang 中将 ID 映射到进程的惯用方式是什么? 【发布时间】:2012-06-17 03:48:58 【问题描述】:

我有一个托管多个游戏实例的游戏服务器。玩家可以输入一个 ID 来加入当前正在运行的游戏。为了将客户端与他们想要的游戏实例配对,我有一个 ETS 表,它将游戏 ID 映射到处理该特定游戏实例的 Erlang 进程的 PID。虽然这可行,但我不太喜欢使用 ETS,因为它会创建不受任何进程控制的全局数据。

我想知道的是:在 Erlang/OTP 中是否有惯用的方式将标识符映射到进程?在这种情况下使用 ETS 可以吗,因为数据本质上是全局的?或者我应该有一个进程来存储所有 ID 的字典来处理映射?我觉得这更像是 Erlang 风格,但可能不如高性能或并发。我在查看其他 SO 答案时也遇到了gproc,这似乎是一个改进的流程字典。但是,我的印象是使用进程字典是不受欢迎的 (according to the erlang.org web page)。

【问题讨论】:

gproc (rustyklophaus.com/articles/…) 很好。与内置的 Process Dictionary 相比,它已知更稳定/改进。您也可以使用mnesia ram 表,但我认为ETS 也可以。 看看这个问题***.com/questions/5319553/… 【参考方案1】:

ETS tables 可以由给定的进程/gen_server 控制,并且它们的所有权可以在出现问题时通过 ets:give_away/3heir option 在表创建期间从进程转移到进程。 许多游戏开发者都依赖memcached 之类的东西,它与ETS 没有(故意)不同。但是,mnesia 是一个非常稳定的 OTP 应用程序,与ETS 相比,它可以处理更多的并发更新。我们在非常繁忙的应用程序中使用了 mnesia,并且它从未停止过,除非整个 VM 由于其他问题而停止运行。实际上,大多数用 erlang 构建的可用系统确实依赖 mnesiaETS 在冗余组件之间共享状态,以便当一个故障转移到另一个时,内存中的数据可用。gproc 是一个非常方便的工具,尤其适用于游戏之类的东西。这是因为,一个进程依赖于它自己易于访问的数据。没有其他进程可以查找其他进程的数据。因此,您也可以使用gproc,而不是将游戏状态保持在ETS。 无论如何,如果您有时间,您可以尝试每个选项并进行一些负载测试,看看哪一个表现更好。

【讨论】:

也不推荐在全局模式下运行gproc 是的,然而:通过负载测试,你会发现gproc相当稳定。 不相信,在进行负载测试时,我遇到了gen_leader 崩溃的问题,因为 gproc 中有许多全局注册的进程。 这个答案给出了您所听过的最惯用的 erlang 响应:“尝试每个选项,然后......看看哪个选项表现更好”。除此之外,ETS 表(可选地包含在gen_servers 中)相当普遍。对于非分布式情况,gproc 也可以很好地工作。有关 gproc 使用的示例,请参见 jlouis 的 etorrent 项目。 Mnesia 在其工作方式上几乎是一个分布式 ETS 表,因此请检查一下。

以上是关于在 OTP/Erlang 中将 ID 映射到进程的惯用方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 OTP/Erlang 作为 Web 应用程序基于组件的架构的一部分

如何在 Java 中将双向实体映射到 DTO

在python sqlite中将结果行映射到namedtuple

在主机上具有进程ID的docker容器上映射应用程序的进程ID

在 Spring Boot jpa 中将多个外键映射到同一个主键

如何在 C++ 中将字节数组发送到另一个进程