我试图弄清楚什么是解决Elixir应用程序的以下负载分配/流程唯一性保证问题的最佳方法.
应用程序
我的Elixir应用程序在n不同的节点上启动(从大型池中随机选择,没有预先知道的固定IP或主机名),形成一个集群(我不确定什么是进行节点发现的最佳方式,但现在让我们忽略它).
简而言之,应用程序的主要目的是使两个系统随时间保持同步,基本上是一个集成.每个用户都有一个集成,可以添加新的集成,也可以随时删除现有的集成.
问题
我希望每次集成都有一个Erlang进程,因为它在概念上非常优雅并带来许多好处(例如每个集成都有一个自然的同步点).看起来这也是扩展系统的方法.
问题是显然这个过程需要在整个集群中是唯一的(如果两个进程试图同步相同的集成,很难预测数据会发生什么),并且我想在节点失败时自动重新分配工作或者新的整合进来了.
此外,在部署新版本的应用程序时,新群集将在旧群集关闭之前启动(我们不依赖于热代码重新加载).需要以某种方式处理这一过渡阶段.
可能解决方案
一种解决方案可能是依赖全球流程.启动时,节点会自行注册,连接到其他已注册的节点,然后尝试启动其全局Scheduler进程的副本,该进程的唯一作用是启动跨节点的集成过程.
虽然这提供了容错功能,但它不能保证每个集成一个进程,因为群集可以通过网络分区分成两个.它也不处理新旧集群在线并且旧集群仍在工作的短暂时期.
某种全局锁定机制(通过共享的Redis实例?)可用于处理网络分区和应用程序重启,但这看起来相当hacky.
有什么建议?
谢谢!
似乎源自模式匹配的二进制字符串的部分转换为整数:
iex(21)> <<type::size(8)>> = Base.decode16!("05")
<<5>>
iex(22)> type
5
Run Code Online (Sandbox Code Playgroud)
我希望type保持一个普通的二进制字符串,因为毕竟应用程序知道二进制代表什么类型的数据.
我无法找到将子字符串保留为二进制字符串的方法.它是Erlang实现的设计决策还是限制?