Apache Ignite is a horizontally scalable fault-tolerant distributed in-memory computing platform.
As of now, there is a Hello World application to get started on this platform. But the documentation requires us to fill in a few important details by ourselves; otherwise the application can't be run successfully.
Here is a complete set of steps to run this application (self contained with the code).
We describe the steps to be followed on a CentOS 8 box. But it should be easy to adapt the steps to any Linux platform.
As of now, the latest version of Apache Ignite is v2.8.1 .
- JDK 8 should be installed on your machine already
- Install Apache Ignite on a CentOS machine using the documentation available.
- Install Maven:
sudo yum install -y maven
Let Ignite be installed as an OS service.
Don't start Ignite yet, since a small configuration change will be required.
Let's say our application will be named helloignite
. Create a directory structure like the following, with the Java source file (IgniteHelloWorld.java
).
[techie@datavm helloignite]$ tree
.
├── pom.xml
└── src
└── main
└── java
└── com
└── ty
└── datavm
└── helloignite
└── IgniteHelloWorld.java
We used a package named com.ty.datavm.helloignite
, but you could use a different one.
Here is the complete Java code for this application. Note the import
statements.
package com.ty.datavm.helloignite;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteException;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.lang.IgniteRunnable;
import org.apache.ignite.resources.IgniteInstanceResource;
import java.util.Collections;
public class IgniteHelloWorld {
public static void main(String[] args) throws IgniteException {
// Preparing IgniteConfiguration using Java APIs
IgniteConfiguration cfg = new IgniteConfiguration();
// The node will be started as a client node.
cfg.setClientMode(true);
// Classes of custom Java logic will be transferred over the wire from this app.
cfg.setPeerClassLoadingEnabled(true);
// Setting up an IP Finder to ensure the client can locate the servers.
TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
ipFinder.setAddresses(Collections.singletonList("127.0.0.1:47500..47509"));
cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(ipFinder));
// Starting the node
Ignite ignite = Ignition.start(cfg);
// Create an IgniteCache and put some values in it.
IgniteCache<Integer, String> cache = ignite.getOrCreateCache("myCache");
cache.put(1, "Hello");
cache.put(2, "World!");
System.out.println(">> Created the cache and add the values.");
// Executing custom Java compute task on server nodes.
ignite.compute(ignite.cluster().forServers()).broadcast(new RemoteTask());
System.out.println(">> Compute task is executed, check for output on the server nodes.");
// Disconnect from the cluster.
ignite.close();
}
/**
* A compute tasks that prints out a node ID and some details about its OS and JRE.
* Plus, the code shows how to access data stored in a cache from the compute task.
*/
private static class RemoteTask implements IgniteRunnable {
@IgniteInstanceResource
Ignite ignite;
@Override public void run() {
System.out.println(">> Executing the compute task");
System.out.println(
" Node ID: " + ignite.cluster().localNode().id() + "\n" +
" OS: " + System.getProperty("os.name") +
" JRE: " + System.getProperty("java.runtime.name"));
IgniteCache<Integer, String> cache = ignite.cache("myCache");
System.out.println(">> " + cache.get(1) + " " + cache.get(2));
}
}
}
For the build to be successful, the pom.xml
file must be correctly written:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ty.datavm</groupId>
<artifactId>helloignite</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>helloignite</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>2.8.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.ty.datavm.helloignite.IgniteHelloWorld</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<mainClass>com.ty.datavm.helloignite.IgniteHelloWorld</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
This includes the required Ignite jar files.
For this example, and usually for better performance, we have to enable peer class-loading.
cd /usr/share/apache-ignite/config
Then edit the file default-config.xml
, adding the entry: <property name="peerClassLoadingEnabled" value="true" />
.
That is, this configuration file should now look like:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="peerClassLoadingEnabled" value="true" />
</bean>
</beans>
Alternatively you can create a new config file and pass it as argument when starting the server processes.
For this example, we will create only two nodes running Ignite.
Note that when Ignite was installed, it created an OS user called ignite
to run the processes. So first login as this user:
In one terminal run: sudo -u ignite /usr/bin/env bash
, and then start the server:
cd /usr/share/apache-ignite
bin/ignite.sh
Let the server process run in foreground.
In another terminal follow exactly the same steps to start another server process.
Now in a different terminal, run the following command to launch the hello wold program:
mvn clean install exec:java -P com.ty.datavm.helloignite.IgniteHelloWorld
This maven command will compile, package and run the application.
The maven command will display some messages like:
>> Created the cache and add the values.
>> Compute task is executed, check for output on the server nodes.
Check the logs on the server side. There should be messages like:
>> Executing the compute task
Node ID: fcbd683c-fe98-43c6-8bda-dacc0c28d795
OS: Linux JRE: OpenJDK Runtime Environment
>> Hello World!
If you come across an error from maven like Local node and remote node have different version numbers
, make sure your pom.xml
refers to
exactly the same version of Ignite that is running on the server side.
If there is a message from maven like Remote node has peer class loading enabled flag different from local
, it means the server configuration is not yet done (
see changes to default-config.xml
file mentioned above).
Just type Ctrl-C
, in each terminal where a server process is running.