Erlang 的高可用性?

High availability in Erlang?

在 Erlang 中实现高可用性的典型方法有哪些?

让我们假设一些 gen_server 在本地注册为 ?MODULE。给定 N 独立并由默认的 Erlang 节点互连,每个 运行 一个 gen_server 的实例,如何 1) 确保没有请求因某些参与节点的故障而丢失(只要因为至少其中一个在线),2)对它们进行负载平衡以避免某些节点过载而其他节点挂起等待新消息?据我所知,不存在内置的负载均衡器:没有 pg2 或较新的 pg 就足够了(仍然可能是朝这个方向进一步工作的良好基础)。

我敢打赌这是一个普遍存在的问题,并且确实存在久经考验的 "Erlangish" 解决方案。它们是什么?

我认为对于 1) 只有一次保证,您需要某种分布式事务算法,因为连接可能会失败并且您不知道远程节点中请求的状态:远程节点是否已死?它是否还活着并且只是因为网络故障而断开连接?在失败之前请求处理进行了多长时间?
你应该检查 mnesia,它与 Erlang 深度集成。

如果您放宽对 1) 的要求(例如,如果请求是幂等的。您只关心至少一次或失败不常见),monitoring 远程可能就足够了gen_server 如果与远程服务器的连接因任何原因丢失,则只重播请求。

对于 2,我们在节点前面以最少连接方式使用 haproxy or nginx 网络服务器,尽管我相信您指的是 'inside' Erlang。在那种情况下,我会执行以下操作以获得带有负载信息的本地 ETS:

  1. 有一个 MODULE sidekick,可以定期向集群中的其他 sidekick 广播本地 MODULE 的邮箱大小(或其他指标)。
  2. 如果 sidekick 收到这个广播,它会将源节点和大小写入 ETS,或者只是在内部保存它们,暂时将最不忙的存储在 ETS 中
  3. 如果 sidekick 注意到远程节点断开连接,它会更新 ETS

关于OTP23's pg,不要轻易丢弃。根据文档 Process Groups implement strong eventual consistency.,您可能已经过载的服务器暂时离开了进程组,它们最终将停止接收请求。您可以按节点设置多个服务器,触发较低以离开组以实现更均匀的分配。