JBoss Community Archive (Read Only)

Infinispan 6.0

Getting Started Guide

AuthorsDouglas Campos , Galder Zamarreño , Libor Krzyžanek , Manik Surtani , Mircea Markus , Pete Muir , Sanne GRINOVERO , Vlastimil Eliáš

Target Audience

This guide shows you how to get started using Infinispan. It covers the common uses of Infinispan, and shows you how to get off the ground. It also introduces to some of the essential concepts of Infinispan.

Under development

This guide is still under development. The content you will find here is correct, but there are some missing sections.

Introduction

This guide will walk you through downloading, installing and running Infinispan for the first time. It will then introduce to some of the key features of Infinispan.

Infinispan can be used in a variety of runtimes:

  • Java SE, started by your application

  • an application server which provides Infinispan as a service (such as JBoss AS)

  • bundled as a library in your application, deployed to an application server, and started on by your application (for example, you could use Infinispan with Tomcat or GlassFish)

Infinispan offers four modes of operation, which determine how and where the data is stored:

  • Local, where entries are stored on the local node only, regardless of whether a cluster has formed. In this mode Infinispan is typically operating as a local cache

  • Invalidation, where all entries are stored into a cache store (such as a database) only, and invalidated from all nodes. When a node needs the entry it will load it from a cache store. In this mode Infinispan is operating as a distributed cache, backed by a canonical data store such as a database

  • Replication, where all entries are replicated to all nodes. In this mode Infinispan is typically operating as a data grid or a temporary data store, but doesn't offer an increased heap space

  • Distribution, where entries are distributed to a subset of the nodes only. In this mode Infinispan is typically operating as a data grid providing an increased heap space

Invalidation, Replication and Distribution can all use synchronous or asynchronous communication.

Infinispan offers two access patterns, both of which are available in any runtime:

  • Embedded into your application code

  • As a Remote server accessed by a client (REST, memcached or Hot Rod)

This guide will introduce to each of the runtime options, access patterns and modes of operations by walking you through simple applications for each. All these applications are available in the Infinispan Quickstart distribution.

Downloading and installing Infinispan

To run the Infinispan, you'll need

  • Java 1.6

  • Maven 3, if you wish to use the quickstart examples or create a new project using the Infinispan archetype

  • the Infinispan distribution zip, if you wish to use Infinispan in server mode, or want to use the jars in an ant project

  • the Infinispan Quickstart zip, if you want to follow along with the projects discussed in the guide

If you already have any of these pieces of software, there is no need to install them again!

Choose your Java runtime, and follow their installation instructions. For example, you could choose one of:

Follow the official Maven installation guide if you don't already have Maven 3 installed. You can check which version of Maven you have installed (if any) by running mvn --version. If you see a version newer than 3.0.0, you are ready to go.

You can also deploy the examples using your favorite IDE. We provide instructions for using Eclipse only.

Finally, download Infinispan and the Infinispan Quickstart from the download page.

Infinispan in action - GUIDemo

TODO

Using Infinispan as an embedded cache in Java SE

Running Infinispan in embedded mode is very easy. First, we'll set up a project, and then we'll run Infinispan, and start adding data.

embedded-cache quickstart

All the code discussed in this tutorial is available in the embedded-cache quickstart.

Creating a new Infinispan project

The only thing you need to set up Infinispan is add it's dependencies to your project. If you are using Maven (or another build system like Gradle or Ivy which can use Maven dependencies), then this is easy. Just add:

pom.xml snippet
053.       <dependency>
054.          <groupId>org.infinispan</groupId>
055.          <artifactId>infinispan-embedded</artifactId>
056.          <version>${infinispan.version}</version>
057.       </dependency>

to your <dependencies> section of the POM. You'll need to substitute ${infinispan.version} for the version of Infinispan you wish to use.

Which version of Infinispan should I use?

We recommend using the latest final version of Infinispan. All releases are displayed on the downloads page.

You'll also need to enable the JBoss Maven repository. We recommend adding a profile:

pom.xml snippet
076.             <executions>
077.                <execution>
078.                   <goals>
079.                      <goal>java</goal>
080.                   </goals>
081.                </execution>
082.             </executions>
083.          </plugin>
084.       </plugins>
085.    </build>
086. 
087.    <profiles>
088.       <profile>
089.          <id>jboss-public-repository</id>
090.          <activation>
091.             <property>
092.                <name>jboss-public-repository</name>
093.                <value>!false</value>
094.             </property>
095.          </activation>
096.          <repositories>
097.             <repository>
098.                <id>jboss-public-repository-group</id>
099.                <name>JBoss Public Maven Repository Group</name>
100.                <url>http://repository.jboss.org/nexus/content/groups/public</url>
101.                <releases>
102.                   <enabled>true</enabled>
103.                   <updatePolicy>never</updatePolicy>
104.                </releases>
105.                <snapshots>
106.                   <enabled>true</enabled>
107.                   <updatePolicy>never</updatePolicy>
108.                </snapshots>
109.             </repository>
110.          </repositories>
111.          <pluginRepositories>
112.             <pluginRepository>
113.                <id>jboss-public-repository-group</id>
114.                <name>JBoss Public Maven Repository Group</name>

Alternatively, you can use the POM from the quickstart that accompanies this tutorial.

If you are using Ant, or another build system which doesn't provide declarative dependency management, then the Infinispan distribution zip contains a lib/ directory. Add the contents of this to the build classpath.

Running Infinispan on a single node

In order to run Infinispan, we're going to create a main method in the Quickstart class. Infinispan comes configured to run out of the box; once you have set up your dependencies, all you need to do to start using Infinispan is to create a new cache manager and get a handle on the default cache.

Quickstart.java
28. public class Quickstart {
29. 
30.    public static void main(String args[]) throws Exception {
31.       Cache<Object, Object> c = new DefaultCacheManager().getCache();
32.    }

We now need a way to run the main method! If you are using Maven, the best approach is to copy all the project dependencies to a directory, and at the same time compile the java classes from our project:

$> mvn clean compile dependency:copy-dependencies -DstripVersion

Having done that, we can run the main method:

$> java -cp target/classes/:target/dependency/* Quickstart

You should see Infinispan start up, and the version in use logged to the console.

Congratulations, you now have Infinispan running as a local cache!

Use the default cache

Infinispan exposes a Map-like, JSR-107-esque interface for accessing and mutating the data stored in the cache. For example:

DefaultCacheQuickstart.java
37.       
38.       // Add a entry
39.       cache.put("key", "value");
40.       // Validate the entry is now in the cache
41.       assertEqual(1, cache.size());
42.       assertTrue(cache.containsKey("key"));
43.       // Remove the entry from the cache
44.       Object v = cache.remove("key");
45.       // Validate the entry is no longer in the cache
46.       assertEqual("value", v);

Infinispan offers a thread-safe data-structure:

DefaultCacheQuickstart.java
48. 
49.       // Add an entry with the key "key"
50.       cache.put("key", "value");
51.       // And replace it if missing
52.       cache.putIfAbsent("key", "newValue");
53.       // Validate that the new value was not added

By default entries are immortal but you can override this on a per-key basis and provide lifespans.

DefaultCacheQuickstart.java
58. 
59.       //By default entries are immortal but we can override this on a per-key basis and provide lifespans.
60.       cache.put("key", "value", 5, SECONDS);
61.       assertTrue(cache.containsKey("key"));
62.       Thread.sleep(10000);

Use a custom cache

Each cache in Infinispan can offer a different set of features (for example transaction support, different replication modes or support for eviction), and you may want to use different caches for different classes of data in your application. To get a custom cache, you need to register it with the manager first:

CustomCacheQuickstart.java
33. 
34.    public static void main(String args[]) throws Exception {
35.       EmbeddedCacheManager manager = new DefaultCacheManager();
36.       manager.defineConfiguration("custom-cache", new ConfigurationBuilder()
37.             .eviction().strategy(LIRS).maxEntries(10)
38.             .build());
39.       Cache<Object, Object> c = manager.getCache("custom-cache");

The example above uses Infinispan's fluent configuration, which offers the ability to configure your cache programmatically. However, should you prefer to use XML, then you may. We can create an identical cache to the one created with a programmatic configuration:

infinispan.xml
24. <infinispan
25.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
26.         xsi:schemaLocation="urn:infinispan:config:7.0 http://www.infinispan.org/schemas/infinispan-config-7.0.xsd"
27.         xmlns="urn:infinispan:config:7.0">
28. 
29.    <cache-container default-cache="default">
30.        <local-cache name="xml-configured-cache">
31.           <eviction strategy="LIRS" max-entries="10" />
32.        </local-cache>
33.    </cache-container>

We then need to load the configuration file, and use the programmatically defined cache:

XmlConfiguredCacheQuickstart.java
29. 
30.    public static void main(String args[]) throws Exception {
31. 	   Cache<Object, Object> c = new DefaultCacheManager("infinispan.xml").getCache("xml-configured-cache");

Using Infinispan as an embedded data grid in Java SE

Clustering Infinispan is simple.  Under the covers, Infinispan uses JGroups as a network transport, and JGroups handles all the hard work of forming a cluster.

Sharing JGroups channels

By default all caches created from a single CacheManager share the same JGroups channel and multiplex RPC messages over it. In this example caches 1, 2 and 3 all use the same JGroups channel:

EmbeddedCacheManager cm = // get CacheManager from somewhere
Cache<Object, Object> cache1 = cm.getCache("replSyncCache");
Cache<Object, Object> cache2 = cm.getCache("replAsyncCache");
Cache<Object, Object> cache3 = cm.getCache("invalidationSyncCache");
clustered-cache quickstart

All the code discussed in this tutorial is available in the clustered-cache quickstart.

Running Infinispan in a cluster

It is easy set up a clustered cache. This tutorial will show you how to create two nodes in different processes on the same local machine. The quickstart follows the same structure as the embedded-cache quickstart, using Maven to compile the project, and a main method to launch the node.

If you are following along with the quickstarts, you can try the examples out. First, compile the project:

$> mvn clean compile dependency:copy-dependencies -DstripVersion

The quickstart contains two examples of a clustered cache, one in replication mode and one distribution mode. To run the replication mode example, we need to launch both nodes from different consoles. For the first node:

$> java -cp target/classes/:target/dependency/* org.infinispan.quickstart.clusteredcache.replication.Node0

And for the second node:

$> java -cp target/classes/:target/dependency/* org.infinispan.quickstart.clusteredcache.replication.Node1

You should see JGroups and Infinispan start up on both consoles, and after about 15s the cache entry log message appear on the console of the first node.

To run the distribution mode example, we need to launch three nodes from different consoles. For the first node:

$> java -cp target/classes/:target/dependency/* org.infinispan.quickstart.clusteredcache.distribution.Node0

And for the second node:

$> java -cp target/classes/:target/dependency/* org.infinispan.quickstart.clusteredcache.distribution.Node1

And for the third node:

$> java -cp target/classes/:target/dependency/* org.infinispan.quickstart.clusteredcache.distribution.Node2

You should see JGroups and Infinispan start up on both consoles, and after about 15s see the 10 entries added by third node distributed to the first and second nodes.

clustered-cache quickstart architecture

Logging changes to the cache

An easy way to see what is going on with your cache is to log mutated entries. An Infinispan listener is notified of any mutations:

import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;

/**
 * An Infinispan listener that simply logs cache entries being created and
 * removed
 * 
 * @author Pete Muir
 */
@Listener
public class LoggingListener {

   private Log log = LogFactory.getLog(LoggingListener.class);

   @CacheEntryCreated
   public void observeAdd(CacheEntryCreatedEvent<?, ?> event) {
      if (!event.isPre()) // So that message is only logged after operation succeeded
         log.infof("Cache entry with key %s added in cache %s", event.getKey(), event.getCache());
   }

   @CacheEntryRemoved
   public void observeRemove(CacheEntryRemovedEvent<?, ?> event) {
      log.infof("Cache entry with key %s removed in cache %s", event.getKey(), event.getCache());
   }

}

Listeners methods are declared using annotations, and receive a payload which contains metadata about the notification. Listeners are notified of any changes. Here, the listeners simply log any entries added or removed.

The replication mode example contains two nodes, each of which are started in a separate process. The nodes are very simple, Node0 starts up, registers a listener that logs any changes, and waits for the cluster to form. Node1 starts up, waits for the cluster to form, and then adds an entry. The interesting work happens in the common super class, examined in Configuring a replicated data-grid.

Waiting for the cluster to form

Infinispan only replicates data to nodes which are already in the cluster. If a node is added to the cluster after an entry is added, it won't be replicated there. In order to see replication take effect, we need to wait until Both nodes make use of the utility class ClusterValidation, calling it's waitForClusterToForm to achieve this. We won't dig into how this works here, but if you are interested take a look at the code.

The distribution mode example contains three nodes, each of which are started in a separate process. The nodes are very simple, Node0 and Node1 start up, register listeners that logs any changes, and wait for the cluster to form. Node2 starts up, waits for the cluster to form, and then adds 20 entries. Each entry get's distributed to it's owners, and you will see some entries add on Node0 and some on Node1. You'll notice that Node2 gets notified of all adds - this is just because it is the node which adds the entry, it doesn't reflect that the fact that all these entries are stored there! The interesting work happens in the common super class, examined in Configuring a distributed data-grid.

Configuring the cluster

First, we need to ensure that Infinispan is cluster aware. Infinispan provides a default configuration for a clustered cache:

new ConfigurationBuilder()
   .clustering().cacheMode(CacheMode.REPL_SYNC)
   .build()

GlobalConfiguration.getClusteredDefault() is a quick way to get a preconfigured, cluster-aware GlobalConfiguration and can be used as a starting point to fine tuning the configuration.

Tweaking the cluster configuration for your network

Depending on your network setup, you may need to tweak your JGroups set up. JGroups is configured via an XML file; the file to use can be specified via the GlobalConfiguration:

GlobalConfigurationBuilder.defaultClusteredBuilder()
   .transport().addProperty("configurationFile", "jgroups.xml")
   .build()

The JGroups documentation provides extensive advice on getting JGroups working on your network. If you are new to configuring JGroups, you may get a little lost, so you might want to try tweaking these configuration parameters:

  • Using the system property -Djgroups.bind_addr="127.0.0.1" causes JGroups to bind only to your loopback interface, meaning any firewall you may have configured won't get in the way. Very useful for testing a cluster where all nodes are on one machine.

TODO - add more tips!

You can also configure the JGroups properties to use in Infinispan's XML configuration:

<global>
   <transport>
      <properties>
         <property name="configurationFile" value="jgroups.xml"/>
      </properties>
   </transport>
</global>

Configuring a replicated data-grid

In replicated mode, Infinispan will store every entry on every node in the grid. This offers high durability and availability of data, but means the storage capacity is limited by the available heap space on the node with least memory.

The cache should be configured to work in replication mode (either synchronous or asynchronous), and can otherwise be configured as normal. For example, if you want to configure the cache programatically:

private static EmbeddedCacheManager createCacheManagerProgramatically() {
   return new DefaultCacheManager(
      GlobalConfigurationBuilder.defaultClusteredBuilder()
         .transport().addProperty("configurationFile", "jgroups.xml")
         .build(),
      new ConfigurationBuilder()
         .clustering().cacheMode(CacheMode.REPL_SYNC)
         .build()
   );
}

You can configure an identical cache using XML:

cfg.xml:

<infinispan xsi:schemaLocation="urn:infinispan:config:5.1 http://www.infinispan.org/schemas/infinispan-config-5.1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:infinispan:config:5.1">
   <global>
      <transport>
         <properties>
            <property name="configurationFile" value="jgroups.xml"/>
         </properties>
      </transport>
   </global>
   <default>
      <!-- Configure a synchronous replication cache -->
      <clustering mode="replication">
         <sync/>
      </clustering>
   </default>
</infinispan>
private static EmbeddedCacheManager createCacheManagerFromXml() throws IOException {
   return new DefaultCacheManager("infinispan-replication.xml");
}

Configuring a distributed data-grid

In distributed mode, Infinispan will store every entry on a subset of the nodes in the grid (controlled by the parameter numOwners, which controls how many owners each entry will have). Compared to replication, distribution offers increased storage capacity, but with reduced availability (increased latency to access data) and durability. Adjusting the number of owners allows you to obtain the trade off between space, durability and availability.

Infinispan also offers a topology aware consistent hash which will ensure that the owners of entries are located in different data centers, racks and nodes to offer improved durability in case of node or network outages.

The cache should be configured to work in distibuted mode (either synchronous or asynchronous), and can otherwise be configured as normal. For example, if you want to configure the cache programatically:

new ConfigurationBuilder()
   .clustering()
      .cacheMode(CacheMode.DIST_SYNC)
      .hash().numOwners(2)
   .build()

You can configure an identical cache using XML:

cfg.xml:

<default>
   <!-- Configure a synchronous replication cache -->
   <clustering mode="distribution">
      <sync/>
      <hash numOwners="2"/>
   </clustering>
</default>

Creating your own Infinispan project

TODO

Using Infinispan as a second level cache for Hibernate

TODO

Accessing an Infinispan data grid remotely

Using Hot Rod to access an Infinispan data-grid

TODO

Using REST to access an Infinipsan data-grid

TODO

Using memcached to access an Infinispan data-grid

TODO

Using Infinispan in JBoss AS 7

TODO

Using Infinispan in servlet containers (such as Tomcat or Jetty) and other application servers (such as GlassFish)

TODO

Monitoring Infinispan

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-11 09:38:10 UTC, last content change 2012-11-19 14:23:01 UTC.