spread 消息系统组件介绍 - mesadb/mesadb.github.io GitHub Wiki

  1. spread 高性能的分布式分组消息系统,支持局域网以及广域网通讯。

  2. spread 可以作为一个分布式应用的消息总线,并且具有高度的灵活性,可以做到多播,分组,以及点对点的消息传递。

  3. spread 主要利用 virtual synchrony 机制来使得网络拓扑内的节点之间的membership达到一致性。

  4. spread 在每个节点上都会运行一个独立的守护进程,节点内的应用进程与该守护进程通信,其他节点或者客户端也是与该守护进程通信。该守护进程跟踪管理组成员关系,并把组通信相关的信息在多个守护进程间共享。

Spread Dynamic Configuration 特性介绍:

在 Spread 版本4之前,配置文件需要指定所有的 daemons,修改config文件,变更 daemons 列表需要all daemons先关闭,然后再重启.将服务器添加到池中或者改变现有的服务器的名称或IP地址时,需要重启整个Spread系统.

这个对于动态的集群节点管理是非常不方便的.因此在Spread 版本4之后,引入了Dynamic Configuration特性. 在修改 daemon 的spread.conf配置文件时,不需要关闭和重启整个daemons.Daemons从segments上添加或移除,client不会丢失 spread 连接.一些对于 spread 的配置修改(改变现有daemon的名称),client 能够自动接收视图变化消息,显示成员关系的临时变化.

怎样激活一个 Dynamic Configuration 变更:

执行一个配置变更的流程如下所示:

  1. admin 程序运行一个spmonitor进程. spmonitor进程从旧的spread.conf文件中读取daemons 列表. 它需要知道哪些 daemons 在旧的配置文件中,为了发送通知给他们来重新读取 spread.conf 文件.

  2. admin 程序更新磁盘中的Spread.conf文件. 然后发送更新的文件到所有运行daemons的主机上.

  3. admin 程序选择spmonitor选项 "Reload Configuration".一个 command 消息包通过spmonitor进程发送到所有带旧配置文件的daemons上.command 消息包触发 daemon 启动 reload 进程. daemon算法的详细实现将在下面介绍.在这一点上,所有的daemons将切换到新的配置上.

  4. 一旦加载完毕,所有客户端应用可能接受一个成员关系变更通知消息.如果客户端所在的群组中成员发生变化,此消息将被生成,或者对于某种配置类型发生了变更, 带有成员的所有群组连接更多的成员,然后 daemon 将接受一个成员关系变更(显示来自远程 daemons 的所有的群组成员离开群组),然后下一个成员关系将显示群组中的所有客户端将连接到依然处于运行中的 daemons.

Dynamic Configuration 变更语意:

基本情况下,此算法看起来像下面描述的成员关系,特定的daemons已经出现故障或者脱离群组,同时一些daemons已经启动或者正在合并

我们从当前成员关系视图中删除所有的群组成员,故障/脑裂的 daemons 没有任何的群组状态.因此,我们将在正常的成员关系中删除它们. 已经添加到配置中的new daemons 将合并处于正常 EVS 中的群组状态.群组成员与它们连接到的 daemons 是一致的,在两个daemons之间不能有任何的不一致状态.

特殊情况下,如果相同的 IP 地址在两个不同的配置文件中,而其他配置(不同名称,广播地址等)不一致,在这种情况下,将生成一个singleton partition.此分区将隔离每个 daemon 和其他的 daemons,使得它们的群组状态收缩只有本地连接的客户端应用.然后,当singleton partition 被移除,它们将合并到其他的 daemons 中.而每个 daemon 将只知道它们自己本地连接的客户端群组成员,合并这些分区使整个分布式系统保持一致的状态.

任何改变配置的 daemon 将必须关闭和重启.这是因为Spread daemon在启动之后,不能够重新绑定到已经变更的广播,多播,或者IP单播地址上.因此,一台机器变更 IP 地址将需要那台机器的 daemon 关闭,同时使用新的配置重启,而其他的运行的daemons不需要关闭,将继续工作.只有网络配置变更的机器需要关闭.

Daemon 算法实现细节:

当一个重新加载配置的spmonitor命令被接受时,如果daemon处于OP状态,函数Prot_initiate_conf_reload()执行如下的步骤重新加载此配置.如果daemon 不处于OP状态(例如,它已经有一个成员关系), 标识符将被设置,同时成员关系完成,然后执行Prot_initiate_conf_reload()函数.

  1. 在配置代码中调用函数来加载新的配置文件,同时检查配置中的变更类型.如果新文件中的配置变更需要一个singleton partition,然后指示到协议代码.

  2. 通知 daemon 中的所有子系统,一个配置变更正在执行中,任何的保存在 daemon 配置中的缓存或者数据结构的当前状态将被重新加载.旧的配置将仍然通过不同的名字来访问,知道加载完成.这个过程通过调用"*_signal_conf_reload()"函数完成, * 替换成系统名称.例如, "Net_signal_conf_reload()" 和 "Memb_signal_conf_reload()".

3a) 如果不需要分区,然后初始化一个成员关系变更,然后返回.成员关系协议将运行到完成,通过探针到所有活跃的 daemons,形成一个新的成员关系,包括任何new daemons,同时删除任何不在配置文件中的daemons.

3b) 如果需要分区,然后一个singleton partition被创建, Conf_reload_state变量被设置,因此 daemon 的其他部分知道一个配置重载处于运行中,同时一个成员关系变更被触发.

  1. 当成员关系在Discard_packets() 函数中完成时,如果配置重载状态是活跃的,然后此分区将被移除,一个新成员的探针(查找所有的"非分区"daemons)被启动.一旦下一个成员关系发生变化,此配置重载过程结束.

测试一个分区是否在新的配置中需要如下所示.查看configuration.c文件中的函数Conf_reload_initiate()函数有实现细节.

a) 如果如下任意选项为 true,daemon 进程将退出,它将不再在新的配置文件中执行.

 1) I am no longer in the configuration.

 2) My IP/Name has changed.

 3) My broadcast/netmask has changed.

b) Otherwise examine all entries that are both in the new configuration and in the old configuration (matching based on IP address). If the same IP address is in both configurations then if any of the following differs between the old and new configuration, then a partition is required. If they are the same for ALL hosts that are in both files, then no partition is needed.

b) 否则检查在新配置文件和旧配置文件的所有条目.如果相同的 IP 地址在这两个配置文件中,如下当中的任何一个区别于新旧配置文件,则将需要一个分区.如果对于配置文件中的所有主机,它们是相同的,则不需要分区. 1) Name.

 2) Number of interfaces.

 3) Broadcast address or netmask.

 4) Any interface specifications have changed.

通常情况下,简单添加和删除 daemons,不需要分区.