2012-09-05 00:16:23 +00:00
|
|
|
==========================
|
|
|
|
Adding/Removing Monitors
|
|
|
|
==========================
|
|
|
|
|
|
|
|
When you have a cluster up and running, you may add or remove monitors
|
2013-11-21 03:28:27 +00:00
|
|
|
from the cluster at runtime. To bootstrap a monitor, see `Manual Deployment`_
|
|
|
|
or `Monitor Bootstrap`_.
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
Adding Monitors
|
|
|
|
===============
|
|
|
|
|
|
|
|
Ceph monitors are light-weight processes that maintain a master copy of the
|
|
|
|
cluster map. You can run a cluster with 1 monitor. We recommend at least 3
|
2014-01-22 12:21:36 +00:00
|
|
|
monitors for a production cluster. Ceph monitors use a variation of the
|
2014-07-24 23:00:52 +00:00
|
|
|
`Paxos`_ protocol to establish consensus about maps and other critical
|
2014-01-22 12:21:36 +00:00
|
|
|
information across the cluster. Due to the nature of Paxos, Ceph requires
|
|
|
|
a majority of monitors running to establish a quorum (thus establishing
|
|
|
|
consensus).
|
|
|
|
|
|
|
|
It is advisable to run an odd-number of monitors but not mandatory. An
|
|
|
|
odd-number of monitors has a higher resiliency to failures than an
|
|
|
|
even-number of monitors. For instance, on a 2 monitor deployment, no
|
|
|
|
failures can be tolerated in order to maintain a quorum; with 3 monitors,
|
|
|
|
one failure can be tolerated; in a 4 monitor deployment, one failure can
|
|
|
|
be tolerated; with 5 monitors, two failures can be tolerated. This is
|
|
|
|
why an odd-number is advisable. Summarizing, Ceph needs a majority of
|
|
|
|
monitors to be running (and able to communicate with each other), but that
|
|
|
|
majority can be achieved using a single monitor, or 2 out of 2 monitors,
|
|
|
|
2 out of 3, 3 out of 4, etc.
|
|
|
|
|
|
|
|
For an initial deployment of a multi-node Ceph cluster, it is advisable to
|
|
|
|
deploy three monitors, increasing the number two at a time if a valid need
|
|
|
|
for more than three exists.
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
Since monitors are light-weight, it is possible to run them on the same
|
2013-11-21 03:28:27 +00:00
|
|
|
host as an OSD; however, we recommend running them on separate hosts,
|
|
|
|
because fsync issues with the kernel may impair performance.
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2013-11-21 03:28:27 +00:00
|
|
|
.. note:: A *majority* of monitors in your cluster must be able to
|
2012-11-08 19:59:15 +00:00
|
|
|
reach each other in order to establish a quorum.
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
Deploy your Hardware
|
|
|
|
--------------------
|
|
|
|
|
2012-11-08 19:59:15 +00:00
|
|
|
If you are adding a new host when adding a new monitor, see `Hardware
|
|
|
|
Recommendations`_ for details on minimum recommendations for monitor hardware.
|
|
|
|
To add a monitor host to your cluster, first make sure you have an up-to-date
|
2014-07-24 23:00:52 +00:00
|
|
|
version of Linux installed (typically Ubuntu 14.04 or RHEL 7).
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
Add your monitor host to a rack in your cluster, connect it to the network
|
|
|
|
and ensure that it has network connectivity.
|
|
|
|
|
2013-10-11 21:04:36 +00:00
|
|
|
.. _Hardware Recommendations: ../../../start/hardware-recommendations
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
Install the Required Software
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
For manually deployed clusters, you must install Ceph packages
|
2014-07-24 23:00:52 +00:00
|
|
|
manually. See `Installing Packages`_ for details.
|
2012-09-05 00:16:23 +00:00
|
|
|
You should configure SSH to a user with password-less authentication
|
|
|
|
and root permissions.
|
|
|
|
|
2014-07-24 23:00:52 +00:00
|
|
|
.. _Installing Packages: ../../../install/install-storage-cluster
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
|
2012-12-20 18:25:14 +00:00
|
|
|
.. _Adding a Monitor (Manual):
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
Adding a Monitor (Manual)
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
This procedure creates a ``ceph-mon`` data directory, retrieves the monitor map
|
2012-11-08 19:59:15 +00:00
|
|
|
and monitor keyring, and adds a ``ceph-mon`` daemon to your cluster. If
|
|
|
|
this results in only two monitor daemons, you may add more monitors by
|
|
|
|
repeating this procedure until you have a sufficient number of ``ceph-mon``
|
|
|
|
daemons to achieve a quorum.
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2012-12-19 16:48:37 +00:00
|
|
|
At this point you should define your monitor's id. Traditionally, monitors
|
|
|
|
have been named with single letters (``a``, ``b``, ``c``, ...), but you are
|
|
|
|
free to define the id as you see fit. For the purpose of this document,
|
|
|
|
please take into account that ``{mon-id}`` should be the id you chose,
|
|
|
|
without the ``mon.`` prefix (i.e., ``{mon-id}`` should be the ``a``
|
|
|
|
on ``mon.a``).
|
|
|
|
|
2014-07-24 23:00:52 +00:00
|
|
|
#. Create the default directory on the machine that will host your
|
|
|
|
new monitor. ::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
ssh {new-mon-host}
|
2012-12-19 16:48:37 +00:00
|
|
|
sudo mkdir /var/lib/ceph/mon/ceph-{mon-id}
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2012-11-09 03:14:36 +00:00
|
|
|
#. Create a temporary directory ``{tmp}`` to keep the files needed during
|
2014-07-24 23:00:52 +00:00
|
|
|
this process. This directory should be different from the monitor's default
|
2012-11-09 03:14:36 +00:00
|
|
|
directory created in the previous step, and can be removed after all the
|
2014-07-24 23:00:52 +00:00
|
|
|
steps are executed. ::
|
2012-11-09 03:14:36 +00:00
|
|
|
|
2012-11-09 17:18:19 +00:00
|
|
|
mkdir {tmp}
|
2012-11-09 03:14:36 +00:00
|
|
|
|
|
|
|
#. Retrieve the keyring for your monitors, where ``{tmp}`` is the path to
|
2014-07-24 23:00:52 +00:00
|
|
|
the retrieved keyring, and ``{key-filename}`` is the name of the file
|
|
|
|
containing the retrieved monitor key. ::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2014-07-24 23:00:52 +00:00
|
|
|
ceph auth get mon. -o {tmp}/{key-filename}
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2012-11-09 03:14:36 +00:00
|
|
|
#. Retrieve the monitor map, where ``{tmp}`` is the path to
|
2014-07-24 23:00:52 +00:00
|
|
|
the retrieved monitor map, and ``{map-filename}`` is the name of the file
|
2012-11-09 03:14:36 +00:00
|
|
|
containing the retrieved monitor monitor map. ::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2014-07-24 23:00:52 +00:00
|
|
|
ceph mon getmap -o {tmp}/{map-filename}
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2012-11-09 03:14:36 +00:00
|
|
|
#. Prepare the monitor's data directory created in the first step. You must
|
|
|
|
specify the path to the monitor map so that you can retrieve the
|
|
|
|
information about a quorum of monitors and their ``fsid``. You must also
|
|
|
|
specify a path to the monitor keyring::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2014-07-24 23:00:52 +00:00
|
|
|
sudo ceph-mon -i {mon-id} --mkfs --monmap {tmp}/{map-filename} --keyring {tmp}/{key-filename}
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
#. Start the new monitor and it will automatically join the cluster.
|
|
|
|
The daemon needs to know which address to bind to, either via
|
|
|
|
``--public-addr {ip:port}`` or by setting ``mon addr`` in the
|
|
|
|
appropriate section of ``ceph.conf``. For example::
|
|
|
|
|
2012-12-19 16:48:37 +00:00
|
|
|
ceph-mon -i {mon-id} --public-addr {ip:port}
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
Removing Monitors
|
|
|
|
=================
|
|
|
|
|
2012-11-08 19:59:15 +00:00
|
|
|
When you remove monitors from a cluster, consider that Ceph monitors use
|
|
|
|
PAXOS to establish consensus about the master cluster map. You must have
|
|
|
|
a sufficient number of monitors to establish a quorum for consensus about
|
|
|
|
the cluster map.
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2012-12-20 18:25:14 +00:00
|
|
|
.. _Removing a Monitor (Manual):
|
|
|
|
|
2012-09-05 00:16:23 +00:00
|
|
|
Removing a Monitor (Manual)
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
This procedure removes a ``ceph-mon`` daemon from your cluster. If this
|
2012-11-08 19:59:15 +00:00
|
|
|
procedure results in only two monitor daemons, you may add or remove another
|
|
|
|
monitor until you have a number of ``ceph-mon`` daemons that can achieve a
|
|
|
|
quorum.
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
#. Stop the monitor. ::
|
|
|
|
|
2012-12-19 16:48:37 +00:00
|
|
|
service ceph -a stop mon.{mon-id}
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
#. Remove the monitor from the cluster. ::
|
|
|
|
|
2012-12-19 16:48:37 +00:00
|
|
|
ceph mon remove {mon-id}
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
#. Remove the monitor entry from ``ceph.conf``.
|
|
|
|
|
|
|
|
|
|
|
|
Removing Monitors from an Unhealthy Cluster
|
|
|
|
-------------------------------------------
|
|
|
|
|
2015-03-16 16:32:22 +00:00
|
|
|
This procedure removes a ``ceph-mon`` daemon from an unhealthy
|
|
|
|
cluster, for example a cluster where the monitors cannot form a
|
|
|
|
quorum.
|
|
|
|
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2015-04-07 08:20:44 +00:00
|
|
|
#. Stop all ``ceph-mon`` daemons on all monitor hosts. ::
|
2015-03-16 16:32:22 +00:00
|
|
|
|
2015-04-07 08:20:44 +00:00
|
|
|
ssh {mon-host}
|
2015-03-16 16:32:22 +00:00
|
|
|
service ceph stop mon || stop ceph-mon-all
|
|
|
|
# and repeat for all mons
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2013-05-21 21:45:29 +00:00
|
|
|
#. Identify a surviving monitor and log in to that host. ::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
|
|
|
ssh {mon-host}
|
|
|
|
|
2015-03-16 22:20:01 +00:00
|
|
|
#. Extract a copy of the monmap file. ::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2013-05-21 21:45:29 +00:00
|
|
|
ceph-mon -i {mon-id} --extract-monmap {map-path}
|
2015-03-16 16:32:22 +00:00
|
|
|
# in most cases, that's
|
|
|
|
ceph-mon -i `hostname` --extract-monmap /tmp/monmap
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2015-03-16 16:32:22 +00:00
|
|
|
#. Remove the non-surviving or problematic monitors. For example, if
|
|
|
|
you have three monitors, ``mon.a``, ``mon.b``, and ``mon.c``, where
|
|
|
|
only ``mon.a`` will survive, follow the example below::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2013-05-21 21:45:29 +00:00
|
|
|
monmaptool {map-path} --rm {mon-id}
|
|
|
|
# for example,
|
|
|
|
monmaptool /tmp/monmap --rm b
|
|
|
|
monmaptool /tmp/monmap --rm c
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2015-03-16 16:32:22 +00:00
|
|
|
#. Inject the surviving map with the removed monitors into the
|
|
|
|
surviving monitor(s). For example, to inject a map into monitor
|
|
|
|
``mon.a``, follow the example below::
|
2012-09-05 00:16:23 +00:00
|
|
|
|
2012-12-19 16:48:37 +00:00
|
|
|
ceph-mon -i {mon-id} --inject-monmap {map-path}
|
2013-05-21 21:45:29 +00:00
|
|
|
# for example,
|
|
|
|
ceph-mon -i a --inject-monmap /tmp/monmap
|
2012-12-20 18:25:14 +00:00
|
|
|
|
2015-03-16 16:32:22 +00:00
|
|
|
#. Start only the surviving monitors.
|
|
|
|
|
2015-04-07 08:20:44 +00:00
|
|
|
#. Verify the monitors form a quorum (``ceph -s``).
|
2015-03-16 16:32:22 +00:00
|
|
|
|
|
|
|
#. You may wish to archive the removed monitors' data directory in
|
2015-04-07 08:20:44 +00:00
|
|
|
``/var/lib/ceph/mon`` in a safe location, or delete it if you are
|
2015-03-16 16:32:22 +00:00
|
|
|
confident the remaining monitors are healthy and are sufficiently
|
|
|
|
redundant.
|
2012-12-20 18:25:14 +00:00
|
|
|
|
|
|
|
.. _Changing a Monitor's IP address:
|
|
|
|
|
|
|
|
Changing a Monitor's IP Address
|
|
|
|
===============================
|
|
|
|
|
|
|
|
.. important:: Existing monitors are not supposed to change their IP addresses.
|
|
|
|
|
|
|
|
Monitors are critical components of a Ceph cluster, and they need to maintain a
|
|
|
|
quorum for the whole system to work properly. To establish a quorum, the
|
|
|
|
monitors need to discover each other. Ceph has strict requirements for
|
|
|
|
discovering monitors.
|
|
|
|
|
|
|
|
Ceph clients and other Ceph daemons use ``ceph.conf`` to discover monitors.
|
2013-01-11 19:59:53 +00:00
|
|
|
However, monitors discover each other using the monitor map, not ``ceph.conf``.
|
2012-12-20 18:25:14 +00:00
|
|
|
For example, if you refer to `Adding a Monitor (Manual)`_ you will see that you
|
|
|
|
need to obtain the current monmap for the cluster when creating a new monitor,
|
|
|
|
as it is one of the required arguments of ``ceph-mon -i {mon-id} --mkfs``. The
|
|
|
|
following sections explain the consistency requirements for Ceph monitors, and a
|
|
|
|
few safe ways to change a monitor's IP address.
|
|
|
|
|
2013-11-21 03:28:27 +00:00
|
|
|
|
2012-12-20 18:25:14 +00:00
|
|
|
Consistency Requirements
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
A monitor always refers to the local copy of the monmap when discovering other
|
|
|
|
monitors in the cluster. Using the monmap instead of ``ceph.conf`` avoids
|
|
|
|
errors that could break the cluster (e.g., typos in ``ceph.conf`` when
|
|
|
|
specifying a monitor address or port). Since monitors use monmaps for discovery
|
|
|
|
and they share monmaps with clients and other Ceph daemons, the monmap provides
|
|
|
|
monitors with a strict guarantee that their consensus is valid.
|
|
|
|
|
|
|
|
Strict consistency also applies to updates to the monmap. As with any other
|
|
|
|
updates on the monitor, changes to the monmap always run through a distributed
|
|
|
|
consensus algorithm called `Paxos`_. The monitors must agree on each update to
|
|
|
|
the monmap, such as adding or removing a monitor, to ensure that each monitor in
|
|
|
|
the quorum has the same version of the monmap. Updates to the monmap are
|
|
|
|
incremental so that monitors have the latest agreed upon version, and a set of
|
|
|
|
previous versions, allowing a monitor that has an older version of the monmap to
|
|
|
|
catch up with the current state of the cluster.
|
|
|
|
|
|
|
|
If monitors discovered each other through the Ceph configuration file instead of
|
|
|
|
through the monmap, it would introduce additional risks because the Ceph
|
|
|
|
configuration files aren't updated and distributed automatically. Monitors
|
2014-07-09 05:45:08 +00:00
|
|
|
might inadvertently use an older ``ceph.conf`` file, fail to recognize a
|
2012-12-20 18:25:14 +00:00
|
|
|
monitor, fall out of a quorum, or develop a situation where `Paxos`_ isn't able
|
|
|
|
to determine the current state of the system accurately. Consequently, making
|
|
|
|
changes to an existing monitor's IP address must be done with great care.
|
|
|
|
|
|
|
|
|
|
|
|
Changing a Monitor's IP address (The Right Way)
|
|
|
|
-----------------------------------------------
|
|
|
|
|
|
|
|
Changing a monitor's IP address in ``ceph.conf`` only is not sufficient to
|
|
|
|
ensure that other monitors in the cluster will receive the update. To change a
|
|
|
|
monitor's IP address, you must add a new monitor with the IP address you want
|
|
|
|
to use (as described in `Adding a Monitor (Manual)`_), ensure that the new
|
|
|
|
monitor successfully joins the quorum; then, remove the monitor that uses the
|
|
|
|
old IP address. Then, update the ``ceph.conf`` file to ensure that clients and
|
|
|
|
other daemons know the IP address of the new monitor.
|
|
|
|
|
|
|
|
For example, lets assume there are three monitors in place, such as ::
|
|
|
|
|
|
|
|
[mon.a]
|
|
|
|
host = host01
|
|
|
|
addr = 10.0.0.1:6789
|
|
|
|
[mon.b]
|
|
|
|
host = host02
|
|
|
|
addr = 10.0.0.2:6789
|
|
|
|
[mon.c]
|
|
|
|
host = host03
|
|
|
|
addr = 10.0.0.3:6789
|
|
|
|
|
|
|
|
To change ``mon.c`` to ``host04`` with the IP address ``10.0.0.4``, follow the
|
|
|
|
steps in `Adding a Monitor (Manual)`_ by adding a new monitor ``mon.d``. Ensure
|
|
|
|
that ``mon.d`` is running before removing ``mon.c``, or it will break the
|
|
|
|
quorum. Remove ``mon.c`` as described on `Removing a Monitor (Manual)`_. Moving
|
|
|
|
all three monitors would thus require repeating this process as many times as
|
|
|
|
needed.
|
|
|
|
|
2013-11-21 03:28:27 +00:00
|
|
|
|
2012-12-20 18:25:14 +00:00
|
|
|
Changing a Monitor's IP address (The Messy Way)
|
|
|
|
-----------------------------------------------
|
|
|
|
|
|
|
|
There may come a time when the monitors must be moved to a different network, a
|
|
|
|
different part of the datacenter or a different datacenter altogether. While it
|
|
|
|
is possible to do it, the process becomes a bit more hazardous.
|
|
|
|
|
|
|
|
In such a case, the solution is to generate a new monmap with updated IP
|
|
|
|
addresses for all the monitors in the cluster, and inject the new map on each
|
|
|
|
individual monitor. This is not the most user-friendly approach, but we do not
|
|
|
|
expect this to be something that needs to be done every other week. As it is
|
|
|
|
clearly stated on the top of this section, monitors are not supposed to change
|
|
|
|
IP addresses.
|
|
|
|
|
|
|
|
Using the previous monitor configuration as an example, assume you want to move
|
|
|
|
all the monitors from the ``10.0.0.x`` range to ``10.1.0.x``, and these
|
|
|
|
networks are unable to communicate. Use the following procedure:
|
|
|
|
|
|
|
|
#. Retrieve the monitor map, where ``{tmp}`` is the path to
|
|
|
|
the retrieved monitor map, and ``{filename}`` is the name of the file
|
|
|
|
containing the retrieved monitor monitor map. ::
|
|
|
|
|
|
|
|
ceph mon getmap -o {tmp}/{filename}
|
|
|
|
|
|
|
|
#. The following example demonstrates the contents of the monmap. ::
|
|
|
|
|
|
|
|
$ monmaptool --print {tmp}/{filename}
|
|
|
|
|
|
|
|
monmaptool: monmap file {tmp}/{filename}
|
|
|
|
epoch 1
|
|
|
|
fsid 224e376d-c5fe-4504-96bb-ea6332a19e61
|
|
|
|
last_changed 2012-12-17 02:46:41.591248
|
|
|
|
created 2012-12-17 02:46:41.591248
|
|
|
|
0: 10.0.0.1:6789/0 mon.a
|
|
|
|
1: 10.0.0.2:6789/0 mon.b
|
|
|
|
2: 10.0.0.3:6789/0 mon.c
|
|
|
|
|
|
|
|
#. Remove the existing monitors. ::
|
|
|
|
|
|
|
|
$ monmaptool --rm a --rm b --rm c {tmp}/{filename}
|
|
|
|
|
|
|
|
monmaptool: monmap file {tmp}/{filename}
|
|
|
|
monmaptool: removing a
|
|
|
|
monmaptool: removing b
|
|
|
|
monmaptool: removing c
|
|
|
|
monmaptool: writing epoch 1 to {tmp}/{filename} (0 monitors)
|
|
|
|
|
|
|
|
#. Add the new monitor locations. ::
|
|
|
|
|
|
|
|
$ monmaptool --add a 10.1.0.1:6789 --add b 10.1.0.2:6789 --add c 10.1.0.3:6789 {tmp}/{filename}
|
|
|
|
|
|
|
|
monmaptool: monmap file {tmp}/{filename}
|
|
|
|
monmaptool: writing epoch 1 to {tmp}/{filename} (3 monitors)
|
|
|
|
|
|
|
|
#. Check new contents. ::
|
|
|
|
|
|
|
|
$ monmaptool --print {tmp}/{filename}
|
|
|
|
|
|
|
|
monmaptool: monmap file {tmp}/{filename}
|
|
|
|
epoch 1
|
|
|
|
fsid 224e376d-c5fe-4504-96bb-ea6332a19e61
|
|
|
|
last_changed 2012-12-17 02:46:41.591248
|
|
|
|
created 2012-12-17 02:46:41.591248
|
|
|
|
0: 10.1.0.1:6789/0 mon.a
|
|
|
|
1: 10.1.0.2:6789/0 mon.b
|
|
|
|
2: 10.1.0.3:6789/0 mon.c
|
|
|
|
|
|
|
|
At this point, we assume the monitors (and stores) are installed at the new
|
|
|
|
location. The next step is to propagate the modified monmap to the new
|
|
|
|
monitors, and inject the modified monmap into each new monitor.
|
|
|
|
|
|
|
|
#. First, make sure to stop all your monitors. Injection must be done while
|
|
|
|
the daemon is not running.
|
|
|
|
|
|
|
|
#. Inject the monmap. ::
|
|
|
|
|
|
|
|
ceph-mon -i {mon-id} --inject-monmap {tmp}/{filename}
|
|
|
|
|
|
|
|
#. Restart the monitors.
|
|
|
|
|
|
|
|
After this step, migration to the new location is complete and
|
|
|
|
the monitors should operate successfully.
|
2013-11-21 03:28:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
.. _Manual Deployment: ../../../install/manual-deployment
|
2014-01-22 12:21:36 +00:00
|
|
|
.. _Monitor Bootstrap: ../../../dev/mon-bootstrap
|
2015-03-16 16:32:22 +00:00
|
|
|
.. _Paxos: http://en.wikipedia.org/wiki/Paxos_(computer_science)
|