具有大型状态的erlang gen_服务器

具有大型状态的erlang gen_服务器,erlang,Erlang,我有一个trie(用元组和列表实现),有几千个条目,我想支持并发读取。数据的内存占用在10-20 MB范围内。trie只构建一次,之后为只读 建议使用什么方法来维护状态并允许客户端并发访问? 以下是我尝试过的: 1) 创建了以trie作为状态的gen_服务器。这很好,但显然,所有调用都是序列化的 2) 修改(1)为每个调用生成一个新进程,该进程从获取状态、请求和。每个新进程都遍历trie并调用gen\u server:reply/2,并给出结果。这个解决方案似乎不起作用,因为内存和CPU使用量激

我有一个trie(用元组和列表实现),有几千个条目,我想支持并发读取。数据的内存占用在10-20 MB范围内。trie只构建一次,之后为只读

建议使用什么方法来维护状态并允许客户端并发访问?

以下是我尝试过的:

1) 创建了以trie作为状态的gen_服务器。这很好,但显然,所有调用都是序列化的


2) 修改(1)为每个调用生成一个新进程,该进程从获取状态、请求和
。每个新进程都遍历trie并调用
gen\u server:reply/2
,并给出结果。这个解决方案似乎不起作用,因为内存和CPU使用量激增。我假设发生这种情况是因为状态被复制到每个调用的派生进程中。

mochiweb中的mochiglobal就是为这种用例而设计的。基本上,它会将您的数据结构编译成一个模块,因此数据是共享的(模块常量的零拷贝)。只有在不经常更改的数据结构上才能很好地工作,但听起来这就是您所拥有的


如果您的州在变化,请经常通过ETS实施您的型号/结构


您可以创建具有并发读/写选项的ETS表,这将提高性能

另一种方法是创建一个gen_服务器池(带监控),然后将传入连接分配给池中的服务器。这缓解了与第一种方法相关的gen_服务器瓶颈。这种方法还允许通过调整池中进程的数量进行一些调优。LearnyYouSomerlang有一章介绍这一点。

这也是我第一次下意识地实现。请记住,从ETS表中读取数据会将术语复制到调用过程的内存中。因此,在做这件事时,考虑结构是很重要的。我在很多项目中都这样使用过ETS表格。在这种情况下它不起作用,因为trie不能被打碎。另一方面,当您在创建表时使用新的
{read\u concurrency,true}
选项时,似乎存在一个错误。透析器发疯了,告诉我所有打到
ets:new/2
的电话都没有本地回音。