ETS入口限制,用作缓存服务器

时间:2018-02-04 15:54:56

标签: erlang elixir ets

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

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

我想保持简单,因此GenServer中的所有状态(一个Map)都应该只有一个条目。入门级是否有限制?

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

如果是ETS表,App可以在完全其他主机上启动,并连接到缓存节点(ETS)。

1 个答案:

答案 0 :(得分:0)

这当然可以通过各种方式完成。您可以拥有一个单独的商店,例如Mnesia(引擎盖下的ETS),Redis或普通数据库。在后两种情况下,您需要将Genserver状态转换为字符串并分别执行::erlang.term_to_binary:erlang.binary_to_term

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

请求进入时:

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

基于我在本地ETS vs Redis所做的基准测试,ETS是更高效的方式也就不足为奇了,但ElastiCache是​​一个很棒的选择如果你不想打扰专门的Mnesia商店。

如果它涉及需要运行的特定GenServer,那么您很可能会查看故障转移而不是管理单个用户请求。

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

这里复杂的问题是你运行多个应用程序的情况,你会使用哪个密钥让崩溃的应用程序以正确的状态重新初始化GenServer?

这里有几个开放式问题围绕着你的确切用例,但到目前为止所提出的问题应该让你对利用这个缓存解决方案以及如何开始实现它的时候有一个合理的想法。