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

Saving large map in GenServer, is this a valid use case?

这是否是 GenServer 的有效用途:

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

因此,在询问地图时,我将检查是否存在带有 user_id 的进程(即进程 ID),然后抓取它并将其反馈给用户,如果没有,则我创建并将其置于新状态

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

感谢您的指导

如果您的 genserver 除了存储地图并通过 API 返回它之外什么都不做,也许不值得创建很多进程。

您可以仅使用 ets table 或使用 Agent 模块(key=user id,value=map)。

正如有人在 Elixir forum 的某处提到的那样 - 对于纯状态存储使用 Agent,对于纯计算使用 Task - 对于介于两者之间的一切 - GenServers! ;)

即使您目前不需要任何计算,但您可能很快就会需要它,正因为如此,我会坚持使用 GenServer。

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

处理

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

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

值得注意的是,Elixir 为此目的提供了 Agent 模块,但我从未使用过它,因为普通的老式好 GenServer 恕我直言,是一个更简洁的概念。