You can query the cluster for which nodes have joined the cluster. This is done using the ``membershipNodes``method::
val allNodesInCluster = clusterNode.membershipNodes
You can also query the 'Cluster' object for which nodes are member of the a specific cluster::
val nodes = Cluster nodesInCluster "test-cluster"
Resetting the Cluster
~~~~~~~~~~~~~~~~~~~~~
You can reset the whole cluster using the ``reset`` method on the ``Cluster`` object::
Cluster.reset
This shuts down all nodes and removes them from the cluster, it also removes all clustered actors and configuration data from the registry. Use this method with care.
You can reset all the nodes in a specific cluster using the ``resetNodesInCluster`` method on the ``Cluster`` object::
Cluster resetNodesInCluster "test-cluster"
Cluster event subscription
--------------------------
The cluster module supports subscribing to events happening in the cluster. For
example, this can be very useful for knowing when a new nodes come and go,
allowing you to dynamically resize the cluster. Here is an example::
..todo:: add explanation on how to do this with the Java API
Once we can serialize and deserialize the actor we have what we need in
order to cluster the actor. We have four methods at our disposal:
-``store``
-``remove``
-``use``
-``release``
ActorAddress
----------------
The ``ActorAddress`` is used to represent the address to a specific actor. All methods in the API that deals with actors works with ``ActorAddress`` and represents one of these identifiers:
-``actorUuid`` -- the UUID for an actor; ``Actor.uuid``
-``actorId`` -- the ID for an actor; ``Actor.id``
-``actorClassName`` -- the class name of an actor; ``Actor.actorClassName``
To create a ``ActorAddress`` you can create the it using named arguments like this::
ActorAddress(actorUuid = uuid)
ActorAddress(actorId = id)
ActorAddress(actorClassName = className)
Or, if you are using the API from Java (or prefer the syntaxt in Scala) then you can use the ``ActorAddress`` factory methods::
ActorAddress.forUuid(uuid)
ActorAddress.forId(id)
ActorAddress.forClassName(className)
Store and Remove
----------------
The methods for storing an actor in the cluster and removing it from the cluster
are:
-``store`` -- clusters the actor by adding it to the clustered actor registry, available to any node in the cluster
-``remove`` -- removes the actor from the clustered actor registry
The ``store`` method also allows you to specify a replication factor. The
The ``implicit format: Format[T]`` might look scary but this argument is chosen for you and passed in automatically by the compiler as long as you have imported the serialization typeclass for the actor you are storing, e.g. the ``HelloActorFormat`` (defined above and imported in the sample below).
Here is an example of how to use ``store`` to cluster an already
created actor::
import Actor._
import ActorSerialization._
import BinaryFormats._
val clusterNode = Cluster.newNode(NodeAddress("test-cluster", "node1")).start
The final argument ``router`` defines a routing policy in which you have the
following options:
-``Router.Direct`` -- this policy means that the reference will only represent one single actor which it will use all the time when sending messages to the actor. If the query returns multiple actors then a single one is picked out randomly.
-``Router.Random`` -- this policy will route the messages to a randomly picked actor in the set of actors in the cluster, returned by the query.
-``Router.RoundRobin`` -- this policy will route the messages to the set of actors in the cluster returned by the query in a round-robin fashion. E.g. circle around the set of actors in order.
Here is an example::
// Store the PongActor in the cluster and deploy it to 5 nodes in the cluster
localNode store (classOf[PongActor], 5)
// Get a reference to all the pong actors through a round-robin router ActorRef
val pong = localNode ref (actorAddress, Router.RoundRobin)
// Send it messages
pong ! Ping
Actor migration
---------------
The cluster has mechanisms to either manually or automatically fail over all
actors running on a node that have crashed to another node in the cluster. It
will also make sure that all remote clients that are communicating these actors
will automatically and transparently reconnect to the new host node.
Automatic actor migration on fail-over
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All actors are checked out with ``use`` are tracked by the cluster and will be
automatically failed over to a new node in the cluster if the node that up and
how is it is running on (using it) it crashes. Tracking will stop when the actor
is checked in using ``release``.
Manual actor migration
~~~~~~~~~~~~~~~~~~~~~~
You can move an actor for one node to another using the ``migrate`` method. Here is the parameter list:
-``from`` -- the address of the node migrating from (default is the address for the node you are invoking it on)
-``to`` -- the address of the node migrating to
-``actorAddress`` -- the ``ActorAddress``
Here is an example::
clusterNode migrate (
NodeAddress("test-cluster", "node1"),
NodeAddress("test-cluster", "node2"),
actorAddress)
Here is an example using ``actorId`` and ``to``, e.g. relying on the default value for ``from`` (this node)::
- When using this method you should only specify one of the parameters using "named parameters" as in the examples above. Default argument for ``node`` is "this" node.
Lookup the remote addresses for a specific actor (can reside on more than one node):
and it will be possible to have one single configuration file, stored on the server, and pushed out to all
the nodes that joins the cluster. Each node only needs to be configured with the ZooKeeper
server address and the master configuration will only reside in one single place
simplifying administration of the cluster and alleviates the risk of having
different configuration files lying around in the cluster.
Leader election
---------------
The cluster supports leader election. There will always only be one single
leader in the cluster. The first thing that happens when the cluster startup is
a leader election. The leader that gets elected will stay the leader until it
crashes or is shut down, then an automatic reelection process will take place
and a new leader is elected. Only having one leader in a cluster can be very
useful to solve the wide range of problems. You can find out which node is the
leader by invoking the ``leader`` method. A node can also check if it is the
leader by invoking the ``isLeader`` method. A leader node can also explicitly
resign and issue a new leader election by invoking the ``resign`` method. Each node has an election number stating its ranking in the last election. You can query a node for its election number through the ``electionNumber`` method.
JMX monitoring and management
-----------------------------
..todo:: Add some docs to each method
The clustering module has an JMX MBean that you can use. Here is the interface