You need to enable JavaScript to run this app. 分布式Horde下GenServer创建注册与API调用的延迟问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

分布式Horde下GenServer创建注册与API调用的延迟问题咨询

Horde 0.8.3分布式Elixir应用的实际部署问题

部署场景与现象

采用0.8.3版本的Horde为Elixir应用构建分布式注册表与分布式监督树体系,核心实现逻辑如下:

  • 以GenServer为基础实现UserAgent(简称UA)模块,每个UA实例代表一个接入应用的用户
  • 通过Horde.DynamicSupervisor.start_child(MyApi.DSup, {MyApi.UserAgent, user})启动UA实例
  • 在创建UA的同一函数逻辑中,调用UA的客户端接口UserAgent.ping(ua_id);该ping方法会通过via_tuple从注册表中查找对应UA的pid,再向其发送:ping消息

应用部署在N1、N2两个节点上后出现如下异常:
当start_child(...)与ping(...)的执行逻辑均在N1运行、而目标UA实际被调度创建在N2上时,绝大多数场景下调用ping(...)都无法在Horde注册表中找到该UA。经实测,新建的UA需要约150ms到350ms(平均250ms)才能在Horde注册表中达到全集群可见状态,该延迟来自Horde基于deltaCRDT实现的后台异步数据同步机制。

待确认的核心问题

  • 应用运行在单台物理服务器上(无跨节点网络延迟),配备12核CPU且注册表为空时,平均250ms的同步延迟是否属于正常水平?还是需要进一步排查是否存在配置或使用层面的问题?
  • 我原本认为Horde.DynamicSupervisor.start_child(...)是同步调用——即待全集群的注册表数据同步完成后才会返回,因为Horde官方声称其行为与标准库的DynamicSupervisor保持一致。这一认知是否正确?有没有办法实现跨节点注册的同步确认?
  • 我目前实现了如下带等待重试逻辑的get_pid(id, ...)方法来获取UA的pid,这种方案是否合理?
def get_pid(_id, _wait, waited, max_wait) when waited > max_wait, do: :error

def get_pid(id, wait, waited, max_wait) do
  Logger.debug("get_pid(#{id}, wait=#{wait}, waited=#{waited}, max_wait=#{max_wait})")
  case Horde.Registry.lookup(via_tuple(id)) do
    {pid, _} ->
      Logger.debug("\t-> got pid=#{inspect(pid)}")
      pid
    [] ->
      Logger.debug("\t-> got []. Going for a nap for #{wait}ms")
      Process.sleep(wait)
      get_pid(id, wait * 2, waited + wait, max_wait)
  end
end

内容的提问来源于stack exchange,提问作者mszmurlo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 03:45:05