目录
组通信
向进程子集发送和传递消息
组成员身份对发件人透明
- 一次发送操作,无需向所有组成员发送单独的消息
交付与接收
- 多播消息并不总是在进程节点收到后立即交给进程内部的应用层
- 消息接收:在中间缓冲区(例如网络接口缓冲区)中排队到达消息
- 消息传递:将消息从中间缓冲区传递到目标应用程序
问题
- 传递保证消息被一组接收
- 协调:小组成员之间的传递顺序
组播应用
- 计算机支持的协作工作 (CSCW)
- 与复制服务器的通信(容错)
- 网络中的事件通知
系统模型
进程可以通过一对一的通道进行可靠的通信
进程可能仅因崩溃而失败
进程是组的成员,组是通过多播操作发送的消息的目的地
消息m:
- 包含发件人 (sender(m)) 和目的地组 (group(m)) 的 ID
操作
- 多播(g, m)
- 组播消息 m 到组 g
- 传递(m)
- 在收件人处传递消息
层级结构
X-multicast(多播类型)
X-multicast(g, m)
X-deliver(m)
X is
- B: basic 基本
- R: reliable 可靠
- FO: FIFO order
- CO: causal order 因果排序
- TO: total order 全排序
Basic Multicast 基本组播
保证传递信息,除非多播进程崩溃
原语和实现
- 使用可靠的一对一 send() 操作
- B-multicast(g, m): 对于每个进程 p ∈ g, send(p, m)
- B-deliver(m) at p:当在 p 接收(m)时,对于所有 p
ack-implosion 确认爆炸:
- 问题存在于使用并发发送(p,m)操作
- 所有收件人大约在同一时间确认收到
- 缓冲区溢出导致 ack 消息丢失
- 重传,甚至更多的确认消息
Reliable Multicast 可靠组播
完整性
- 一个正确的进程 p 最多传递一次消息
- 传递的消息与多播发送操作中发送的消息相同
有效性
- 如果一个正确的进程多播消息 m,那么它最终将传递 m(活性)
协定性
- 如果一个正确的进程传递了消息 m,那么消息 m 的目标组中的所有其他正确进程也将传递消息 m
原语
R-multicast(m, g)
R-deliver(m)
基于B-multicast的R-multicast
初始化:
Received := {};
对于进程 p 去 R-multicast m 到组 g:
B-multicast(g,m); (p∈g is included as destination)
On B-deliver(m) 在进程q 并且 g = group(m):
if (m ∉ Received):
Received := Received ∪ {m};
if (q ≠ p):
B-multicast(g,m);
R-deliver(m)
分析
有效性
- 一个正确的过程最终会 B-deliver 给自己
完整性
- 基于底层通信介质
协定性
- B-deliver 后 B-multicast 到所有其他进程
效率低下
- 每条消息发送|g| 次,对于每个进程
有序组播
假设
- 每个进程最多属于一个组
先进先出排序 FIFO order
- 如果一个正确的进程发出一个多播(g,m)然后多播(g,m'),那么每个传递m'的正确进程都会在m'之前传递m
因果排序 Casual order
- 如果多播(g,m)→多播(g,m’),其中→仅由消息传递引起,那么每个正确的传递m’的进程都会在m’之前传递m
全排序 Total order
- 如果一个正确的进程在它传递m’之前传递了 m,那么任何其他传递 m' 的正确过程将在 m' 之前传递 m
如何实现排序
先进先出 FIFO
- 使用序列号并延迟传递,直到在发送方和接收方之间就序列号达成一致
全部 Total
- 使用全局序列号
因果关系
- 仅对多播消息使用向量时间戳
FO-Multicast 实现
先进先出排序
每个进程 p 维护以下序列号:
:p 发送到 g 的消息数量
:从 q 发的在 p 处传递的消息数量,对于每个进程 q != p
在进程 p 的 FO-multicast(m, g) 上:
- 将 增加 1
- 带上 在消息上,作为其序列号
- B-multicast(<m, >, g)
如果进程 p 从进程 q 接收到序列号为 S 的多播:
- 如果 S = +1,那么这是下一条消息,
- FO-deliver(m)
- := S
- If S > +1, then
- 将消息放在保留队列中,直到传递了中间消息并且 S = +1
TO-Multicast
完全排序
主要思想
- 为多播消息分配完全有序的标识符,以便每个进程基于这些标识符做出相同的传递决策
- 传递类似于先进先出传递,只是使用特定于组的序列号而不是特定于进程的序列号
标识符分配的两种主要方法
- Sequencer 序列器
- 关于消息标识符分配的集体协议
这里针对Sequencer进行讲解
具有特殊作用的进程:sequencer
在 p 的 TO-multicast(m, g):
- B组播消息到g和sequencer
Sequencer
- 维护一个全局序列号 Sg(初始为 0)
- 当多播消息 m 被 B -deliver给它时:
- Sg = Sg + 1
- B-multicast(<“order”, m, Sg>, g)
在进程 p 接收多播
- p 维护本地接收序列号 Rg
- 消息 m 被放置在保留队列中,直到:
- B-deliver(<“order”, m, Sg>) 从 sequencer 并且 Rg = Sg + 1
- 然后 TO-deliver(m) 并且 Rg = Rg + 1
CO-Multicast使用向量时间戳
因果排序
- 考虑了仅由多播消息建立的发生在之前的关系
主要思想:
- 每个进程pi维护自己的向量时间戳Vi
- Vi [j] :从 pj 在 pi 传递的消息数
进程pi初始化:
- Vi[j] = 0 (j = 0, 1, 2 …, N)
CO-multicast at pi:
- Vi[i] = Vi[i] + 1
- 在消息m中带着 向量Vi 作为它的序列号.
- B-multicast(<m, Vi>, g)
在从 pj 到 pi 的 B-deliver(<m, Vj>) 上,将 消息m 放入保留队列
直到:
1、m 是 pi 期望来自 pj 的下一条消息:Vj[j] = Vi[j] + 1 并且,
2、发生在 m 之前的所有多播都已在 pi 传递:对于所有 k≠j: Vj[k] ≤ Vi[k]
当两个条件都满足时:CO-deliver(m) 并设置 Vi[j] = Vi[j] + 1
Nice,恭喜大家又成功看完,多播也大概讲完了,第一次看必然会觉得很抽象,但是没关系,多查查资料,慢慢就熟悉了,再次感谢大家观看!有问题欢迎随时评论交流。目前先更新到这里,之后有时间会继续更新的。感谢~