• 沒有找到結果。

Uniform Reliable Broadcast

With regular reliable broadcast, the semantics just require the correct processes to deliver the same set of messages, regardless of what messages have been deliv-ered by faulty processes. In particular, a process that rb-broadcasts a message might rb-deliver it and then crash, before the best-effort broadcast abstraction can even beb-deliver the message to any other process. Indeed, this scenario may occur in both reliable broadcast algorithms that we presented (eager and lazy). It is thus pos-sible that no other process, including correct ones, ever rb-delivers that message.

There are cases where such behavior causes problems because even a process that rb-delivers a message and later crashes may bring the application into a inconsistent state.

We now introduce a stronger definition of reliable broadcast, called uniform reliable broadcast. This definition is stronger in the sense that it guarantees that the set of messages delivered by faulty processes is always a subset of the messages delivered by correct processes. Many other abstractions also have such uniform variants.

3.4.1 Specification

Uniform reliable broadcast differs from reliable broadcast by the formulation of its agreementproperty. The specification is given in Module3.3.

Uniformity is typically important if the processes interact with the external world, e.g., print something on a screen, authorize the delivery of money through a bank machine, or trigger the launch of a rocket. In this case, the fact that a process has delivered a message is important, even if the process has crashed afterward. This is because the process, before crashing, could have communicated with the external world after having delivered the message. The processes that did not crash should also be aware of that message having been delivered, and of the possible external action having been performed.

Figure3.3depicts an execution of a reliable broadcast algorithm that is not uni-form. Both processes p and q rb-deliver the message as soon as they beb-deliver

Module 3.3: Interface and properties of uniform reliable broadcast Module:

Name: UniformReliableBroadcast, instance urb.

Events:

Request: ⟨ urb, Broadcast | m ⟩: Broadcasts a message m to all processes.

Indication: ⟨ urb, Deliver | p, m ⟩: Delivers a message m broadcast by process p.

Properties:

URB1–URB3: Same as properties RB1–RB3 in (regular) reliable broadcast (Mod-ule3.2).

URB4: Uniform agreement: If a message m is delivered by some process (whether correct or faulty), then m is eventually delivered by every correct process.

rb−deliver rb−broadcast

p

q

r

s

rb−deliver

Figure 3.3:Nonuniform reliable broadcast

it, but crash before they are able to relay the message to the remaining processes.

Still, processes r and s are consistent among themselves (neither has rb-delivered the message).

3.4.2 Fail-Stop Algorithm: All-Ack Uniform Reliable Broadcast

Basically, our “Lazy Reliable Broadcast” and “Eager Reliable Broadcast” algo-rithms do not ensure uniform agreement because a process may rb-deliver a message and then crash. Even if this process has relayed its message to all processes (through a best-effort broadcast primitive), the message might not reach any of the remaining processes. Note that even if we considered the same algorithms and replaced the best-effort broadcast abstraction with a reliable broadcast one, we would still not implement a uniform broadcast abstraction. This is because a process may deliver a message before relaying it to all processes.

Algorithm3.4, named “All-Ack Uniform Reliable Broadcast,” implements uni-form reliable broadcast in the fail-stop model. Basically, in this algorithm, a process

Algorithm 3.4: All-Ack Uniform Reliable Broadcast Implements:

UniformReliableBroadcast, instance urb.

Uses:

BestEffortBroadcast, instance beb.

PerfectFailureDetector, instanceP. upon eventurb,Initdo

delivered:=; pending:=; correct:=Π;

forallmdo ack[m]:=; upon eventurb,Broadcast| m ⟩do

pending:= pending∪ {(self, m)};

triggerbeb,Broadcast| [DATA, self, m]; upon eventbeb,Deliver| p,[DATA,s, m]do

ack[m]:= ack[m]∪ {p}; if(s, m)̸∈pendingthen

pending:= pending∪ {(s, m)};

triggerbeb,Broadcast | [DATA,s, m]; upon event⟨ P,Crash| p ⟩do

correct:= correct\ {p};

function candeliver(m) returns Boolean is return(correctack[m]);

upon exists(s, m)pendingsuch thatcandeliver(m)∧ m ̸∈delivereddo delivered:= delivered∪ {m};

triggerurb,Deliver| s,m;

delivers a message only when it knows that the message has been beb-delivered and thereby seen by all correct processes. All processes relay the message once, after they have seen it. Each process keeps a record of processes from which it has already received a message (either because the process originally sent the message or because the process relayed it). When all correct processes have retransmitted the message, all correct processes are guaranteed to deliver the message, as illustrated in Fig.3.4.

The algorithm uses a variable delivered for filtering out duplicate messages and a variable pending, used to collect the messages that have been beb-delivered and seen, but that still need to be urb-delivered.

The algorithm also uses an array ack with sets of processes, indexed by all possi-ble messages. The entry ack[m] gathers the set of processes that the process knows have seen m. Of course, the array can be implemented with a finite amount of

urb−broadcast p

q

r

s urb−deliver

urb−deliver urb−deliver

Figure 3.4:Sample execution of all-ack uniform reliable broadcast

memory by using a sparse representation. Note that the last upon statement of the algorithm is triggered by an internal event defined on the state of the algorithm.

Correctness. The validity property follows from the completeness property of the failure detector and from the validity property of the underlying best-effort broad-cast. The no duplication property relies on the delivered variable to filter out duplicates. No creation is derived from the no creation property of the underlying best-effort broadcast. Uniform agreement is ensured by having each process wait to urb-deliver a message until all correct processes have seen and relayed the message.

This mechanism relies on the accuracy property of the perfect failure detector.

Performance. When considering the number of communication steps, in the best case, the algorithm requires two communication steps to urb-deliver a message to all processes. In such scenario, in the first step it sends N messages and in the second step N(N −1) messages, for a total of N2messages. In the worst case, if the processes crash in sequence, N + 1 steps are required. Therefore, uniform reliable broadcast requires one step more to deliver a message than its regular counterpart.

3.4.3 Fail-Silent Algorithm: Majority-Ack Uniform Reliable Broadcast

The “All-Ack Uniform Reliable Broadcast” algorithm of Sect.3.4.2(Algorithm3.4) is not correct if the failure detector is not perfect. Uniform agreement would be violated if accuracy is not satisfied and validity would be violated if completeness is not satisfied.

We now give a uniform reliable broadcast algorithm that does not rely on a per-fect failure detector but assumes a majority of correct processes, i.e., N > 2f if we assume that up to f processes may crash. We leave it as an exercise to show why the majority assumption is needed in the fail-silent model, without any failure detector.

Algorithm 3.5, called “Majority-Ack Uniform Reliable Broadcast,” is similar to Algorithm 3.4 (“All-Ack Uniform Reliable Broadcast”) in the fail-silent model, except that processes do not wait until all correct processes have seen a message, but only until a majority quorum has seen and retransmitted the message. Hence, the algorithm can be obtained by a small modification from the previous one, affecting only the condition under which a message is delivered.

Algorithm 3.5: Majority-Ack Uniform Reliable Broadcast Implements:

UniformReliableBroadcast, instance urb.

Uses:

BestEffortBroadcast, instance beb.

// Except for the functioncandeliver(·)below and for the absence ofCrashevents // triggered by the perfect failure detector, it is the same as Algorithm3.4.

function candeliver(m) returns Boolean is return#(ack[m]) > N/2;

Correctness. The algorithm provides uniform reliable broadcast if N > 2f. The no duplicationproperty follows directly from the use of the variable delivered. The no creationproperty follows from the no creation property of best-effort broadcast.

To argue for the uniform agreement and validity properties, we first observe that if a correct process p beb-delivers some message m then p eventually urb-delivers m.

Indeed, if p is correct, and given that p beb-broadcasts m according to the algorithm, then every correct process beb-delivers and hence beb-broadcasts m. As we assume a majority of the processes to be correct, p eventually beb-delivers m from more than N/2 processes and urb-delivers it.

Consider now the validity property. If a correct process p urb-broadcasts a mes-sage m then p beb-broadcasts m, and hence p beb-delivers m eventually; according to the above observation, p eventually also urb-delivers m. Consider now uniform agreement, and let q be any process that urb-delivers m. To do so, q must have beb-delivered m from a majority of the processes. Because of the assumption of a correct majority, at least one correct process must have beb-broadcast m. Hence, all correct processes eventually beb-deliver m by the validity property of best-effort broadcast, which implies that all correct processes also urb-deliver m eventually according to the observation made earlier.

Performance. The performance of the algorithm is similar to the performance of the

“All-Ack Uniform Reliable Broadcast” algorithm.