ETS 条目限制,用作缓存服务器

ETS entry limit, to use as a cache server

我的想法是使用 ETS 作为我的 GenServer 状态的临时缓存。

例如,当我重新启动我的应用程序时,GenServer 状态应该传输到 ETS,当应用程序再次启动时,GenServer 应该能够从那里获取状态。

我想保持简单,所以来自 GenServer 的所有状态(地图)应该采用单个条目。参赛人数有限制吗?

另一种方法是,简单地创建一个文件,并在需要时再次加载它。也许这甚至是 better/simpler,但我不确定 :)

如果是 ETS table,应用程序可以在完全不同的主机上启动,并连接到缓存节点 (ETS)。

这当然可以通过多种方式完成。您可以有一个单独的存储,例如 Mnesia(底层是 ETS)、Redis 或普通数据库。在后两种情况下,您需要将 Genserver 状态转换为字符串并返回:分别执行 :erlang.term_to_binary:erlang.binary_to_term

如果您正在处理需要以这种方式缓存的多个 GenServer 进程,例如例如,每个 GenServer 代表一个唯一的客户购物车,然后该唯一标识符可以用作存储状态的键,稍后可以检索该状态。当您 运行 在负载均衡器后面的多个节点上连接您的购物应用程序时,这特别有用,并且部分客户的每个新请求都可以 'round robin' 连接到任何随机节点。

当请求进来时:

  • 以一种或另一种方式获取属于该客户的唯一标识符,
  • 从任何地方获取存储的内容(Mnesia/Redis/...),
  • 产生一个用存储的内容初始化的新 GenServer 进程,
  • 执行该请求所需的各种操作,
  • 将最新修改的GenServer购物车存入Redis/Mnesia/wherever,
  • 拆除 GenServer 并
  • 使用所需的任何数据响应请求。

根据我在本地所做的 ETSRedis 的基准测试,ETS 是性能更高的方法也就不足为奇了,但 ElastiCache 是如果您不想费心开一家专门的 Mnesia 商店,这是一个很棒的选择。

如果它与需要 运行 的特定 GenServer 相关,那么您很可能会考虑故障转移,而不是管理单个用户请求。

在这种情况下,您可以考虑使用类似的方法:https://hexdocs.pm/elixir/GenServer.html#c:terminate/2 让状态首先保存到某个存储,然后在您的 init 中让 GenServer 首先查看该存储并相应地重用缓存。

这里的复杂问题是在您有多个应用程序的情况下 运行ning,为了让崩溃的应用程序以正确的状态重新初始化 GenServer,您将使用哪个密钥?

这里有几个围绕您的确切用例的开放式问题,但到目前为止所介绍的内容应该可以让您清楚地了解何时可以使用此缓存解决方案以及如何开始实施它。