在GenServer中保存大型地图,这是一个有效的用例吗?

时间:2017-11-16 11:00:26

标签: elixir gen-server

这可能是GenServer的有效用途:

如果process_id是user_id且它是唯一的。进程包含通过DB生成的大数据映射的查询结果。现在,如果100位用户登录系统并询问他们的数据地图,他们全部都保存在user_id引用的自己的进程中,这是唯一的

因此,在询问地图时,我将检查是否有一个带有user_id的进程(这是进程ID)并抓住它并将其反馈给用户,如果没有,那么我创建它并将其放入新州

现在,如果用户更新了他的地图,在更新时,我确保更新状态或创建一个新地图。

感谢您的指导

3 个答案:

答案 0 :(得分:3)

除非您有一百万用户登录,否则这是完全有效的。这通常在Erlang生态系统中使用所谓的进行处理。

主要原则是:您将进程池的大小限制为100(5000,无论如何,它主要取决于您的硬件容量)并为新手使用任何抢占式存储(如果容量为超过限制。)

您可以考虑序列化这些替换数据,或者生成新节点等等。通常,保持状态的进程是OTP中的首选解决方案,除非您达到内存限制。在这种情况下,您可能会选择使用某些持久性存储,例如DETS或(更好)mnesia

值得注意的是,Elixir为此目的提供了Agent模块,但我从不使用它,因为普通的旧GenServer是IMHO更清洁的概念。

答案 1 :(得分:1)

如果您的genserver只是存储地图并通过API返回它,那么可能不值得创建大量进程。

您只能为此目的使用ets表或使用Agent模块(key = user id,value = map)。

答案 2 :(得分:0)

正如有人在Elixir forum上某处提到的那样 - 对于纯粹的状态存储使用Agent,对于纯计算使用任务 - 用于其间的所有内容 - GenServers!

即使你现在不需要任何计算,你可能会在不久的将来需要一个计算 - 正因为如此,我会坚持使用GenServer。