数据检索吞吐量 - ETS查找与进程间消息传递

时间:2013-04-19 09:08:26

标签: erlang mnesia ets

假设我们有一个涉及数千个进程的erlang应用程序。假设有一个资源X可能是元组,列表或任何erlang术语,所有这些进程可能需要随时从中读取/提取某些内容。

这种情况的一个例子是API系统,其中客户端进程可能需要在远程机器上进行读写。对于每个读/写请求,您不希望创建新的连接。那么,你做了什么,你创建了一个连接池,将它们视为一个开放的管道/插座/通道池。

现在,这个资源池将由数千个进程共享,这样对于每个读取或写入请求,您希望该进程检索任何可用的开放通道/资源。

问题是,如果我有一个进程(单个进程)保存此信息,无论是在其进程字典中还是在其接收循环中。这意味着,只要需要免费资源,所有流程都必须向此流程发送消息。由于对这一单一资源的高需求,这个单一进程随时都会有一个庞大的邮箱。
左或我可以使用ETS表,只有一行,比如#resources{key=pool,value= List_of_openSockets_or_channels} 。但这意味着,我们所有的过程都会尝试在(高概率)相同的瞬时时间从ETS表读取同一行。

如果10,000进程在同一时间/几乎同一时间处理相同的行/记录,ETS表如何处理?然而,如果我使用一个进程,它的邮箱,如果10,000个进程同时向它发送一条消息,同一资源(并且它需要回复每个请求者)。请记住,此操作可能会频繁发生。什么选择(关于流程的可用性问题等等)会提供更高的吞吐量,以便流程可以更快地获得他们需要的东西?

还有其他更好的方法,能够以一种能够快速访问数百万个进程的方式处理Erlang VM中的高需求数据结构,即使它们都需要同时使用该资源?

2 个答案:

答案 0 :(得分:3)

简短回答:个人资料。尝试不同的方法并验证系统的行为方式。

首先,我会看看ETS'{read_concurrency, true}选项。来自the documentation

  

{read_concurrency,boolean()} 性能调优。默认值为false。   设置为true时,表格针对并发读取进行了优化   操作。在具有SMP的运行时系统上启用此选项时   支持,阅读操作变得便宜得多;特别是在系统上   有多个物理处理器。但是,在read和之间切换   写操作变得更加昂贵。您通常想要启用   当并发读取操作更频繁时,此选项   比写操作,或并发读写时   大量读写突发(即大量读取不被中断)   写道,许多写入没有被读取中断)。你通常这样做   当公共访问模式很少时,不希望启用此选项   读操作重复与几个写操作交错。在   在这种情况下,启用此功能会降低性能   选项。 read_concurrency选项可以与   write_concurrency选项。您通常希望在何时将它们组合起来   大并发读突发和大并发写突发   常见的。

其次,我会看一下缓存的可能性。进程只读取一次或多次?如果他们多次访问它,您可以阅读一次并将其存储在您的过程状态中。

第三,您可以尝试在整个系统中复制和分发该信息。划分et impera。

答案 1 :(得分:2)

如果您使用流程方法,为了避免在“服务器”流程的邮件队列中序列化所有读取请求,您必须复制。

使用带有read_concurrency的ETS表感觉更自然,这是我在开发Dialyzer的并行版本时使用的。但是,在这种情况下,ETS访问从来就不是瓶颈。