Chapter 1. Distributed Computing Environment
Because of the multiplicity and variety of
distributed systems and networked environments
and their widespread differences, this book
does not focus on any single one of them.
Rather it describes and employes a
distributed computing universe that captures
the nature and basic structure of those systems
(e.g., distributed operating systems, data communication networks,
distributed databases, transaction processing systems, etc...),
allowing us to discard or ignore the system-specific details
while identifying the general principles and techniques.
This chapter contains the description of this universe,
its components, its laws (the axioms), and introduces the notions
of problems, protocols, cost measures
and knowledge. All these concepts are
grounded by means of a sample problem, broadcast,
and the design of a simple solution, flooding.
Chapter 2. Basic Problems and Protocols.
The aim of this chapter is to introduce same of the more basic
primitive computational problems and solution techniques. These
problems are basic in the sense that their solution is commonly
(sometimes, frequently) required for the functioning of the system
(e.g., broadcast and wakeup); they are primitive in the
sense that their computation is often a preliminary step or a module
of complex computations and protocols (e.g., traversal and
Some of these problems (e.g., broadcast and traversal}, by their nature, are started by a single entity; other problems (e.g., wake-up and
spanning-tree construction) have no such a restriction.
The computational differences created by the additional assumption of a
single initiator, as we will see, can be dramatic.
Included also in this chapter are the (multiple-initiators) computations in tree networks. Their fundamental importance derives from the fact that most global problems (i.e., problems that, to be solved, require the involvement of all entities), oftentimes can be correctly, easily, and efficiently solved by designing a protocol for trees, and executing it on a spanning-tree of the network.
The techniques we introduce in this chapter to solve these problems
are basic ones; once properly understood, they form a
powerful and essential toolset that can be effectively employed by
every designer of distributed algorithms.
Chapter 3. Election.
In a distributed environment, most applications often
require a single entity to act temporarily as a central controller
to coordinate the execution of a particular task by the entities.
The problem of choosing such a coordinator from a population of
autonomous symmetric entities is known as Leader Election.
There is no restriction on the number of entities that can
start the computation, nor on which entity should become leader.
Since election provides a mechanism for breaking the symmetry among the entities in a distributed environment, it is at the basis of most control and coordination processes (e.g., mutual exclusion, synchronization, concurrency control, etc.) employed in distributed systems, and it is closely related to other basic computations (e.g., minimum finding, spanning-tree construction, traversal).
In this chapter we study the election problem. We start with facing the
unexpected impossibility result and imposing conditions to bypass it.
We then continue examining the problem and designing solutions
continue by focusing on the development of election protocols that are
generic, that is can be used in any network.
of the focus is on ring networks since the tools and techniques developed
there can be generalized and exported to the other cases.
Chapter 4. Message Routing and Shortest Paths.
Communication is at the basis of computing in a distributed environment
but the task to achieve it efficiently is neither simple nor trivial.
Consider an entity x that wants to communicate some information
to another entity y . An
efficient approach is to choose a single path from x to
the message sent by x will travel only along this path,
relayed by the entities in the path, until it reaches its destination y .
The process of determining a path between a source x and a
destination y is known as routing.
there is more than one path from x to y , we would like obviously
to choose the least expensive one,
called shortest path. The process of determining
the most economic path between a source and a destination is known as
The (shortest-path) routing problem is commonly
solved by storing at each entity x information that will allow to address
a message to its destination though a (shortest) path. This
information is called routing table.
In this Chapter we will discuss several aspects of the routing problem.
First of all, we will consider the construction of the routing tables. We
will then address the problem of maintaining the information of the
tables up-to-date should changes occurr in the system. Finally we
will discuss how to represent routing information in a compact
way, suitable for systems where space is a problem
Chapter 5. Distributed Sets Operations.
In a distributed computing environment, each entity has its own data
stored in its local memory. Some data items held by one entity are
sometimes related to items held by other entities, and we focus and
operate on them.
In general, an entity x has a set of relevant data D_x . The
union of all
these local sets forms a distributed set of data.
A query is a request for some information about the global
data set, as well as about the individual sets. A query can originate at any entity;
entity where the query originates has locally the desired
the query can be answered immediately; otherwise, the entity will
to communicate with other entities to obtain the desired
In this Chapter we first focus on an important class of queries, order statistics; these includes finding the median of the set, finding the k -th smallest element. The problem of answering such queries is traditionally called selection.
Since selection as well as most queries are more easily and efficiently solved if the distribution is sorted, we will also investigate the problem of sorting the distributed data.
We will then concentrate on distributed set
operations, that is computing union, intersection and differences of
the local sets. The ability to perform such operations has a direct
impact on the processing of complex queries usually performed in
Chapter 6. Synchronous Computations.
In the distributed computing environments we have considered so far,
we have not made any assumption about time.
We do not know
for example how much time will a communication take,
and no assumption is made on the functioning of these clocks, their rate,
how they relate to each other or to communication delays.
For these reasons, the distributed computing environments described by
the basic model are commonly referred to as fully asynchronous
systems. They represent one extreme in the spectrum of message-passing
systems with respect to time.
At the other extreme are fully
synchronous systems, distributed computing environments
where local clocks are synchronized and
transmission delays are
A fully synchronous computing environments is dramatically different from an
asynchronous one: it provides the protocol designer
with computational means
and tools that are both unique and very powerful.
In this Chapter, we will study these tools and learn how to exploit
them to design efficient protocols.
Starting with basic techniques of communicators and pipelining,
we will also
examine the notion of asynchronous-to-synchronous transformer, a
``compiler'' that given in input an asynchronous protocol solving a
problem P generates an efficient synchronous protocol solving
We will then investigate the
two basic techniques that make an
explicit use of time, waiting and guessing; we will
use them in isolation and in conjunction in the context of
in rings and other networks.
We then focus on three synchronization problem: in unison
(to ensure that all local clocks sign the same value), the
wake-up or reset problem (all entities must enter a
special state), and the firing squad problem (all entities must
enter a special state at the same time and for the first time).
Chapter 7. Computing in Presence of Faults.
In all previous chapters, with few exceptions, we have assumed total
reliability, that is that the system is failure-free. Unfortunately,
total reliability is practically non existent in real systems. In this
Chapter we will examine how to compute, if possible, when failures can
and do occur.
Clearly no protocol can be resilient to an arbitrary number of faults.
In particular, if the entire system collapses, no protocol can be
correct. Hence the goal is to design protocols that are able to
withstand up to a certain amount of faults of a given type.
In this Chapter we examine the impact that faults have in distributed computing environments. As we will see, the consequences are devastating even when faults are limited in quantity and danger. just one entity in a complete network might crash This Single Failure Disaster result imposes a dramatic limitation on the design of fault-tolerant protocols. The only way around (possibly) is by substantially restricting the environment: either investing in the software and hardware necessary to make the system fully synchronous; or by constructing reliable fault-detectors; or, in the case of crash faults only, by ensuring somehow that all the faults occur before we start, i.e. partial realiability. Alternatively, we can give up certainty on the outcome and use randomization.
We study how to achieve fault-tolerance using each of these techniques in the case of localized entity failures. We then study the impact of localized link failures by means of a tale.
Finally, we consider the case
ubiquitous failures; that is,
communication faults that can occur anywhere in the
For the designer of
a protocol, these types of faults are much more difficult to
handle than the ones that occur always in the same places.
In the latter case, once a fault is detected, we know
that we can not trust that link; with mobile faults,
detection will not help us with the future events.
It is therefore not surprising that the number of dynamic faults that
tolerated at each time unit is by far less than that of the localized
and permanent faults we can deal with.
what is surprising is perhaps the fact that something can be
Chapter 8. Detecting Stable Properties.
The types of problems we are going to discuss in this chapters arise in very different
contexts and situations, and sometimes they appear to have little (if any at all) in common.
problems arise for example in the context of global termination:
detecting whether a computation (e.g., the execution of a protocol) has globally
terminated; garbage collection: deciding whether some distributed objects
(e.g., data items) are no longer needed within the system;
deadlock: deciding whether a circular wait has been created within the system
preventing any further progress.
All these problem do however share a very important trait: we need to decide whether a certain property holds (e.g., a data object is garbage, an entity is deadlocked, all entities have terminated their execution); the property is stable: if no external event occurs in the system, the property will continue to hold.
In this Chapter we will examine two of these problems in detail, designing efficient solutions
for them. We will then attack the task of designing a generic solution to
the problem of detecting whether a stable property holds,
regardless of the specific nature of the property.
Chapter 9. Continuous Computations.
When we have been discussing computations in distributed environments,
we have always considered computations that,
once started, terminate within finite time.
There are however computations that never terminate.
These are, for example, computations needed for the
control and maintainance of the environment, and they are
``on" as long as
the system is ``on: the protocols composing
a distributed operating system, the transaction management protocols in
a distributed transaction system, the network service protocols in
a data communication network, the object management functions in
a distributed object system, etc.
Because of this nature, these computations are called
Since the computation never ends
the efficiency of a continuous computation is measured
in terms of either its cost per basic operation it
implements, or its cost per basic event triggering its action.
In this Chapter we will examine some basic problems whose solution requires continuous computations: maintaining logical clocks, controlling access to a shared resource or service and maintaining a distributed queue ( distributed mutual exclusion), and detecting and resolving deadlocks.
Some continuous problems are just the (endless) repetition of a
terminating problem (plus adjustments);
others could be solved in that way but
have unique non-terminating solutions; and
others yet do not
have any terminating counterpart.
In this Chapter we will examine continuous problems of all these types.