我正在进入一个现有的(游戏)项目,其服务器组件完全用erlang编写。有时,从拥有它的过程中获取该系统的一部分数据(我对玩家56有多少个小部件感兴趣)可能会令人难以忍受。假设我可以找到拥有数据的进程,我可以将消息传递给该进程并等待它传回消息,但这不能很好地扩展到多台计算机并且它会导致响应时间。
我一直在考虑用一个系统替换游戏中存在的许多任务,在这个系统中,多个进程经常访问的信息将存储在受保护的ets表中。表的所有者除了接收更新消息(玩家刚刚花了五个小部件)之外什么都不做,并相应地更新表。它会捕获所有异常,然后继续下一个更新消息。任何想知道玩家是否有足够的小部件来购买虚构的过程都只需要偷看桌子。 (是的,我知道缓冲区中可能会有一条消息可以减少小部件的数量,但我可以控制该问题。)
我担心我的问题不是问题,而是更多的评论请求。我会推荐任何有用且充分解释或引用的内容。
此类实施的可能缺点是什么?我对锁定争用的细节很感兴趣,我可能会看到有一个作者 - 多个读者,我将在多台机器上分发这种问题,特别是:来自已经完成的人的输入这之前。
答案 0 :(得分:7)
首先,默认的ETS行为是一致的,您可以通过文档看到:Erlang ETS。 它提供原子性和隔离,如果在同一个函数中完成多次更新/读取(请记住,在Erlang中,函数调用大致相当于减少,Erlang调度程序用于在进程之间共享时间的度量单位,因此多功能ETS操作可能会分成更多部分,从而产生可能的竞争条件。)
如果您对多节点ETS架构感兴趣,如果您想要使用ETS的OOTB多节点并发,那么您应该查看mnesia:Mnesia。 (提示:我说的是ram_copies表,add_table_copy和change_config方法)。
话虽如此,我不理解进程的问题(可能由未命名的ets表备份)。 我解释得更好:你的项目的主要问题是第一个基本假设。 这很简单:你没有一个写作过程!
每当玩家拿到一个物体,击中一个玩家等等,它就会调用一个非副作用的免费功能更新游戏状态,所以即使你有一个进程管理游戏状态,他也必须告诉其他玩家客户'嘿,你还记得那个物体吗?把它忘了吧!';这就是为什么许多多人游戏的主要问题是滞后:当网络不是主要问题时,滞后很多次是由于阻止发送/接收例程。
从这个角度来看,直接使用ETS表,使用持久表,进程字典(BAD !!!)等是一回事,因为你必须考虑同步问题,比如在面向对象的编程中使用共享内存的语言(Java,每个人?)。
最后,您应该考虑开发应用程序的一个主要问题:一致性。 在开发了一致的应用程序之后,您才应该关注性能调整。
希望它有所帮助!
注意:我已经谈过像MMORPG服务器这样的东西,因为我以为你在谈论类似的东西。
答案 1 :(得分:6)
在这方面,ETS表无法解决您的问题。您的代码(想要获取或设置播放器窗口小部件计数)将始终在进程中运行,并且必须在那里复制数据。
这是来自进程堆还是ETS表几乎没有区别(也就是说,从ETS读取通常更快,因为它经过了很好的优化,并且除了获取和设置数据之外不执行任何其他工作)。特别是从远程节点获取数据时。对于多读者来说,ETS很可能更快,因为一个过程会按顺序处理请求。
但是,如果数据是否缓存在本地节点上,会产生什么影响。这就是自我复制数据库系统(如Mnesia,Riak或CouchDB)的用武之地.Mnesia实际上是使用ETS表实现的。
至于锁定,最新版本的Erlang附带了对ETS的增强功能,使多个读者可以同时从一个表中读取一个写入的写入器。唯一被锁定的元素是正在写入的行(因此,如果您希望对一个数据点进行多次同时读取,则比正常进程具有更好的并发性能)。
但请注意,与ETS表的所有交互都是非事务性的!这意味着您不能依赖于基于先前读取的值来编写值,因为该值可能在此期间已更改。 Mnesia使用事务处理它。如果你知道自己在做什么,你仍然可以使用Mneisa中的dirty_*
函数来挤出大多数操作中的近ETS性能。
答案 2 :(得分:4)
听起来你有很多事情可以在任何时候发生,你需要以安全,统一的方式聚合数据。看一下Generic Event行为。我建议使用它来创建一个事件服务器,并让所有这些进程通过事件将这些信息共享到您的服务器,此时您可以选择将其记录或存储在某个地方(如ETS表)。顺便说一句,ETS表不适合于持久数据,例如玩家拥有多少“小工具” - 考虑Mnesia,或者只有像CouchDB这样的优秀崩溃数据库。这两种方法在机器间都能很好地复制。
你提出了锁争用 - 你不应该有锁。消息在每个进程接收时以同步顺序处理。事实上,语言中内置于语言中的消息传递的整个要点是避免共享状态并发。
总而言之,通常您会在处理过程中与消息进行通信。这对您来说很麻烦,因为您需要来自分散在各处的流程的信息,因此我对您的建议是基于将原始流程之外“有趣”的所有信息集中到单个实时源中的想法