Merge "Draft of topoprocessing documentation"
[docs.git] / docs / getting-started-guide / common-features / clustering.rst
1 Setting Up Clustering
2 =====================
3
4 Clustering Overview
5 -------------------
6
7 Clustering is a mechanism that enables multiple processes and programs to work
8 together as one entity.  For example, when you search for something on
9 google.com, it may seem like your search request is processed by only one web
10 server. In reality, your search request is processed by may web servers
11 connected in a cluster. Similarly, you can have multiple instances of
12 OpenDaylight working together as one entity.
13
14 Advantages of clustering are:
15
16 * Scaling: If you have multiple instances of OpenDaylight running, you can
17   potentially do more work and store more data than you could with only one
18   instance. You can also break up your data into smaller chunks (shards) and
19   either distribute that data across the cluster or perform certain operations
20   on certain members of the cluster.
21 * High Availability: If you have multiple instances of OpenDaylight running and
22   one of them crashes, you will still have the other instances working and
23   available.
24 * Data Persistence: You will not lose any data stored in OpenDaylight after a
25   manual restart or a crash.
26
27 The following sections describe how to set up clustering on both individual and
28 multiple OpenDaylight instances.
29
30 Multiple Node Clustering
31 ------------------------
32
33 The following sections describe how to set up multiple node clusters in OpenDaylight.
34
35 Deployment Considerations
36 ^^^^^^^^^^^^^^^^^^^^^^^^^
37
38 To implement clustering, the deployment considerations are as follows:
39
40 * To set up a cluster with multiple nodes, we recommend that you use a minimum
41   of three machines. You can set up a cluster with just two nodes. However, if
42   one of the two nodes fail, the cluster will not be operational.
43
44   .. note:: This is because clustering in OpenDaylight requires a majority of the
45              nodes to be up and one node cannot be a majority of two nodes.
46
47 * Every device that belongs to a cluster needs to have an identifier.
48   OpenDaylight uses the node's ``role`` for this purpose. After you define the
49   first node's role as *member-1* in the ``akka.conf`` file, OpenDaylight uses
50   *member-1* to identify that node.
51
52 * Data shards are used to contain all or a certain segment of a OpenDaylight's
53   MD-SAL datastore. For example, one shard can contain all the inventory data
54   while another shard contains all of the topology data.
55
56   If you do not specify a module in the ``modules.conf`` file and do not specify
57   a shard in ``module-shards.conf``, then (by default) all the data is placed in
58   the default shard (which must also be defined in ``module-shards.conf`` file).
59   Each shard has replicas configured. You can specify the details of where the
60   replicas reside in ``module-shards.conf`` file.
61
62 * If you have a three node cluster and would like to be able to tolerate any
63   single node crashing, a replica of every defined data shard must be running
64   on all three cluster nodes.
65
66   .. note:: This is because OpenDaylight's clustering implementation requires a
67             majority of the defined shard replicas to be running in order to
68             function. If you define data shard replicas on two of the cluster nodes
69             and one of those nodes goes down, the corresponding data shards will not
70             function.
71
72 * If you have a three node cluster and have defined replicas for a data shard
73   on each of those nodes, that shard will still function even if only two of
74   the cluster nodes are running. Note that if one of those remaining two nodes
75   goes down, the shard will not be operational.
76
77 * It is  recommended that you have multiple seed nodes configured. After a
78   cluster member is started, it sends a message to all of its seed nodes.
79   The cluster member then sends a join command to the first seed node that
80   responds. If none of its seed nodes reply, the cluster member repeats this
81   process until it successfully establishes a connection or it is shut down.
82
83 * After a node is unreachable, it remains down for configurable period of time
84   (10 seconds, by default). Once a node goes down, you need to restart it so
85   that it can rejoin the cluster. Once a restarted node joins a cluster, it
86   will synchronize with the lead node automatically.
87
88 Setting Up a Multiple Node Cluster
89 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90
91 To run OpenDaylight in a three node cluster, perform the following:
92
93 First, determine the three machines that will make up the cluster. After that,
94 do the following on each machine:
95
96 #. Copy the OpenDaylight distribution zip file to the machine.
97 #. Unzip the distribution.
98 #. Open the following .conf files:
99
100    * configuration/initial/akka.conf
101    * configuration/initial/module-shards.conf
102
103 #. In each configuration file, make the following changes:
104
105    Find every instance of the following lines and replace _127.0.0.1_ with the
106    hostname or IP address of the machine on which this file resides and
107    OpenDaylight will run::
108
109       netty.tcp {
110         hostname = "127.0.0.1"
111
112    .. note:: The value you need to specify will be different for each node in the
113              cluster.
114
115 #. Find the following lines and replace _127.0.0.1_ with the hostname or IP
116    address of any of the machines that will be part of the cluster::
117
118       cluster {
119         seed-nodes = ["akka.tcp://opendaylight-cluster-data@127.0.0.1:2550"]
120
121 #. Find the following section and specify the role for each member node. Here
122    we assign the first node with the *member-1* role, the second node with the
123    *member-2* role, and the third node with the *member-3* role::
124
125      roles = [
126        "member-1"
127      ]
128
129    .. note:: This step should use a different role on each node.
130
131 #. Open the configuration/initial/module-shards.conf file and update the
132    replicas so that each shard is replicated to all three nodes::
133
134       replicas = [
135           "member-1",
136           "member-2",
137           "member-3"
138       ]
139
140    For reference, view a sample config files <<_sample_config_files,below>>.
141
142 #. Move into the +<karaf-distribution-directory>/bin+ directory.
143 #. Run the following command::
144
145       JAVA_MAX_MEM=4G JAVA_MAX_PERM_MEM=512m ./karaf
146
147 #. Enable clustering by running the following command at the Karaf command line::
148
149       feature:install odl-mdsal-clustering
150
151 OpenDaylight should now be running in a three node cluster. You can use any of
152 the three member nodes to access the data residing in the datastore.
153
154 Sample Config Files
155 """""""""""""""""""
156
157 Sample ``akka.conf`` file::
158
159    odl-cluster-data {
160      bounded-mailbox {
161        mailbox-type = "org.opendaylight.controller.cluster.common.actor.MeteredBoundedMailbox"
162        mailbox-capacity = 1000
163        mailbox-push-timeout-time = 100ms
164      }
165
166      metric-capture-enabled = true
167
168      akka {
169        loglevel = "DEBUG"
170        loggers = ["akka.event.slf4j.Slf4jLogger"]
171
172        actor {
173
174          provider = "akka.cluster.ClusterActorRefProvider"
175          serializers {
176                    java = "akka.serialization.JavaSerializer"
177                    proto = "akka.remote.serialization.ProtobufSerializer"
178                  }
179
180                  serialization-bindings {
181                      "com.google.protobuf.Message" = proto
182
183                  }
184        }
185        remote {
186          log-remote-lifecycle-events = off
187          netty.tcp {
188            hostname = "10.194.189.96"
189            port = 2550
190            maximum-frame-size = 419430400
191            send-buffer-size = 52428800
192            receive-buffer-size = 52428800
193          }
194        }
195
196        cluster {
197          seed-nodes = ["akka.tcp://opendaylight-cluster-data@10.194.189.96:2550"]
198
199          auto-down-unreachable-after = 10s
200
201          roles = [
202            "member-1"
203          ]
204
205        }
206      }
207    }
208
209    odl-cluster-rpc {
210      bounded-mailbox {
211        mailbox-type = "org.opendaylight.controller.cluster.common.actor.MeteredBoundedMailbox"
212        mailbox-capacity = 1000
213        mailbox-push-timeout-time = 100ms
214      }
215
216      metric-capture-enabled = true
217
218      akka {
219        loglevel = "INFO"
220        loggers = ["akka.event.slf4j.Slf4jLogger"]
221
222        actor {
223          provider = "akka.cluster.ClusterActorRefProvider"
224
225        }
226        remote {
227          log-remote-lifecycle-events = off
228          netty.tcp {
229            hostname = "10.194.189.96"
230            port = 2551
231          }
232        }
233
234        cluster {
235          seed-nodes = ["akka.tcp://opendaylight-cluster-rpc@10.194.189.96:2551"]
236
237          auto-down-unreachable-after = 10s
238        }
239      }
240    }
241
242 Sample ``module-shards.conf`` file::
243
244    module-shards = [
245        {
246            name = "default"
247            shards = [
248                {
249                    name="default"
250                    replicas = [
251                        "member-1",
252                        "member-2",
253                        "member-3"
254                    ]
255                }
256            ]
257        },
258        {
259            name = "topology"
260            shards = [
261                {
262                    name="topology"
263                    replicas = [
264                        "member-1",
265                        "member-2",
266                        "member-3"
267                    ]
268                }
269            ]
270        },
271        {
272            name = "inventory"
273            shards = [
274                {
275                    name="inventory"
276                    replicas = [
277                        "member-1",
278                        "member-2",
279                        "member-3"
280                    ]
281                }
282            ]
283        },
284        {
285             name = "toaster"
286             shards = [
287                 {
288                     name="toaster"
289                     replicas = [
290                        "member-1",
291                        "member-2",
292                        "member-3"
293                     ]
294                 }
295             ]
296        }
297    ]
298
299 Clustering Scripts
300 ------------------
301
302 OpenDaylight includes some scripts to help with the clustering configuration.
303
304 .. note::
305
306     Scripts are stored in the OpenDaylight distribution/bin folder, and
307     maintained in the distribution project
308     `repository <https://git.opendaylight.org/gerrit/p/integration/distribution>`_
309     in the folder distribution-karaf/src/main/assembly/bin/.
310
311 Configure Cluster Script
312 ^^^^^^^^^^^^^^^^^^^^^^^^
313
314 This script is used to configure the cluster parameters (e.g. akka.conf,
315 module-shards.conf) on a member of the controller cluster. The user should
316 restart the node to apply the changes.
317
318 .. note::
319
320     The script can be used at any time, even before the controller is started
321     for the first time.
322
323 Usage::
324
325     bin/configure_cluster.sh <index> <seed_nodes_list>
326
327 * index: Integer within 1..N, where N is the number of seed nodes. This indicates
328   which controller node (1..N) is configured by the script.
329 * seed_nodes_list: List of seed nodes (IP address), separated by comma or space.
330
331 The IP address at the provided index should belong to the member executing
332 the script. When running this script on multiple seed nodes, keep the
333 seed_node_list the same, and vary the index from 1 through N.
334
335 Optionally, shards can be configured in a more granular way by modifying the
336 file "custom_shard_configs.txt" in the same folder as this tool. Please see
337 that file for more details.
338
339 Example::
340
341     bin/configure_cluster.sh 2 192.168.0.1 192.168.0.2 192.168.0.3
342
343 The above command will configure the member 2 (IP address 192.168.0.2) of a
344 cluster made of 192.168.0.1 192.168.0.2 192.168.0.3.
345
346 Set Persistence Script
347 ^^^^^^^^^^^^^^^^^^^^^^
348
349 This script is used to enable or disable the config datastore persistence. The
350 default state is enabled but there are cases where persistence may not be
351 required or even desired. The user should restart the node to apply the changes.
352
353 .. note::
354
355   The script can be used at any time, even before the controller is started
356   for the first time.
357
358 Usage::
359
360     bin/set_persistence.sh <on/off>
361
362 Example::
363
364     bin/set_persistence.sh off
365
366 The above command will disable the config datastore persistence.