= Apache Ignite Cluster Manager for Vert.x

This is a cluster manager implementation for Vert.x that uses http://ignite.apache.org/index.html[Apache Ignite].

In Vert.x a cluster manager is used for various functions including:

* Discovery and group membership of Vert.x nodes in a cluster
* Maintaining cluster wide topic subscriber lists (so we know which nodes are interested in which event bus
addresses)
* Distributed Map support
* Distributed Locks
* Distributed Counters

Cluster managersdo not* handle the event bus inter-node transport, this is done directly by Vert.x with TCP
connections.

Vert.x cluster manager is a pluggable component, so you can pick the one you want, or the one that is the most
adapted to your environment. So you can replace default Vert.x cluster manager by this implementation.

== Using Ignite cluster manager

If the jar is on your classpath then Vert.x will automatically detect this and use it as the cluster manager.
Please make sure you don’t have any other cluster managers on your classpath or Vert.x might choose the wrong one.

Alternatively, you can configure the following system property to instruct vert.x to use this cluster manager:
`-Dvertx.clusterManagerFactory=io.vertx.spi.cluster.ignite.IgniteClusterManager`

### Using Vert.x from command line

`vertx-ignite-3.9.12.jar` should be in the `lib` directory of the Vert.x installation.

### Using Vert.x in Maven or Gradle project

Add a dependency to the artifact.

* Maven (in your `pom.xml`):

[source,xml,subs="+attributes"]
----
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-ignite</artifactId>
 <version>3.9.12</version>
</dependency>
----

* Gradle (in your `build.gradle` file):

[source,groovy,subs="+attributes"]
----
compile 'io.vertx:vertx-ignite:3.9.12'
----

### Programmatically specifying cluster manager

You can also specify the cluster manager programmatically. In order to do this just specify it on the options
when you are creating your Vert.x instance, for example:

[source,java]
----
ClusterManager clusterManager = new IgniteClusterManager();

VertxOptions options = new VertxOptions().setClusterManager(clusterManager);
Vertx.clusteredVertx(options, res -> {
 if (res.succeeded()) {
   Vertx vertx = res.result();
 } else {
   // failed!
 }
});
----

== Configuring cluster manager

Note: Starting with version 2.0, Apache Ignite has introduced a new off-heap memory architecture. All caches use
off-heap memory by default. New memory architecture is described in
https://apacheignite.readme.io/docs/page-memory[Ignite Virtual Memory] article.

=== Using configuration file

The cluster manager is configured by a file `default-ignite.xml` which is packaged inside the jar.

If you want to override this configuration you can provide `ignite.xml` file on your classpath and this will be
used instead.

The xml file is a Ignite configuration file and is described in details in
https://apacheignite.readme.io/docs[Apache Ignite documentation].

### Configuring programmatically

You can also specify configuration programmatically:

[source,java]
----
IgniteConfiguration cfg = new IgniteConfiguration();
// Configuration code (omitted)

ClusterManager clusterManager = new IgniteClusterManager(cfg);

VertxOptions options = new VertxOptions().setClusterManager(clusterManager);
Vertx.clusteredVertx(options, res -> {
 if (res.succeeded()) {
   Vertx vertx = res.result();
 } else {
   // failed!
 }
});
----

=== Discovery and network transport configuration

The default configuration uses `TcpDiscoveryMulticastIpFinder` so you must have multicast enabled on your network.
For cases when multicast is disabled `TcpDiscoveryVmIpFinder` should be used with pre-configured list of IP addresses.
Please see http://apacheignite.readme.io/docs/cluster-config[Cluster Configuration] section
at Apache Ignite documentation for details.

== Trouble shooting clustering

If the default multicast configuration is not working here are some common causes:

=== Multicast not enabled on the machine.

By default the cluster manager is using `TcpDiscoveryMulticastIpFinder`, so IP multicasting is required,
on some systems, multicast route(s) need to be added to the routing table otherwise, the default route will be used.

Note that some systems don't consult the routing table for IP multicast routing, only for unicast routing

MacOS example:

----
# Adds a multicast route for 224.0.0.1-231.255.255.254
sudo route add -net 224.0.0.0/5 127.0.0.1

# Adds a multicast route for 232.0.0.1-239.255.255.254
sudo route add -net 232.0.0.0/5 192.168.1.3
----

Please google for more information.

=== Using wrong network interface

If you have more than one network interface on your machine (and this can also be the case if you are running
VPN software on your machine), then Apache Ignite may be using the wrong one.

To tell Ignite to use a specific interface you can provide the IP address of the interface to the
bean of `IgniteConfiguration` type using `localHost` property. For example:

----
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
 <property name="localHost" value="192.168.1.20"/>
</bean>
----

When running Vert.x is in clustered mode, you should also make sure that Vert.x knows about the correct interface.
When running at the command line this is done by specifying the `cluster-host` option:

----
vertx run myverticle.js -cluster -cluster-host your-ip-address
----

Where `your-ip-address` is the same IP address you specified in the Apache Ignite configuration.

If using Vert.x programmatically you can specify this using `link:../../apidocs/io/vertx/core/VertxOptions.html#setClusterHost-java.lang.String-[setClusterHost]`.

=== Using a VPN

This is a variation of the above case. VPN software often works by creating a virtual network interface which often
doesn't support multicast. If you have a VPN running and you do not specify the correct interface to use in both the
Ignite configuration and to Vert.x then the VPN interface may be chosen instead of the correct interface.

So, if you have a VPN running you may have to configure both the Ignite and Vert.x to use the correct interface as
described in the previous section.

=== When multicast is not available

In some cases you may not be able to use multicast as it might not be available in your environment. In that case
you should configure another transport using corresponding IP finder, e.g. `TcpDiscoveryVmIpFinder` to use TCP sockets,
or `TcpDiscoveryS3IpFinder` to use Amazon S3.

For more information on available Ignite transports and how to configure them please consult the
https://apacheignite.readme.io/docs/clustering[Ignite Clustering] documentation.

=== Enabling logging

When trouble-shooting clustering issues it's often useful to get some logging output from Ignite
to see if it's forming a cluster properly. You can do this (when using the default JUL logging) by adding a file
called `vertx-default-jul-logging.properties` on your classpath. This is a standard java.util.loging (JUL)
configuration file. Inside it set:

----
org.apache.ignite.level=INFO
----

and also

----
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.FileHandler.level=INFO
----