Infinispan offers both declarative and programmatic configuration.
Declarative configuration comes in a form of XML document that adheres to a provided Infinispan configuration XML schema.
Every aspect of Infinispan that can be configured declaratively can also be configured programmatically. In fact, declarative configuration, behind the scenes, invokes the programmatic configuration API as the XML configuration file is being processed. One can even use a combination of these approaches. For example, you can read static XML configuration files and at runtime programmatically tune that same configuration. Or you can use a certain static configuration defined in XML as a starting point or template for defining additional configurations in runtime.
There are two main configuration abstractions in Infinispan:
Global configuration defines global settings shared among all cache instances created by a single EmbeddedCacheManager. Shared resources like thread pools, serialization/marshalling settings, transport and network settings, JMX domains are all part of global configuration.
Cache configuration is specific to the actual caching domain itself: it specifies eviction, locking, transaction, clustering, persistence etc. You can specify as many named cache configurations as you need. One of these caches can be indicated as the
default cache, which is the cache returned by the
CacheManager.getCache() API, whereas other named caches are retrieved via the
CacheManager.getCache(String name) API.
Whenever they are specified, named caches inherit settings from the default cache while additional behavior can be specified or overridden. Infinispan also provides a very flexible inheritance mechanism, where you can define a hierarchy of configuration templates, allowing multiple caches to share the same settings, or overriding specific parameters as necessary.
|Embedded and Server configuration use different schemas, but we strive to maintain them as compatible as possible so that you can easily migrate between the two.|
One of the major goals of Infinispan is to aim for zero configuration. A simple XML configuration file containing nothing more than a single infinispan element is enough to get you started. The configuration file listed below provides sensible defaults and is perfectly valid.
However, that would only give you the most basic, local mode, non-clustered cache manager with no caches. Non-basic configurations are very likely to use customized global and default cache elements.
Declarative configuration is the most common approach to configuring Infinispan cache instances. In order to read XML configuration files one would typically construct an instance of DefaultCacheManager by pointing to an XML file containing Infinispan configuration. Once the configuration file is read you can obtain reference to the default cache instance.
EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml"); Cache defaultCache = manager.getCache();
or any other named instance specified in
Cache someNamedCache = manager.getCache("someNamedCache");
The name of the default cache is defined in the
<cache-container> element of the XML configuration file, and additional caches can be configured using the
The following example shows the simplest possible configuration for each of the cache types supported by Infinispan:
<infinispan> <cache-container default-cache="local"> <transport cluster="mycluster"/> <local-cache name="local"/> <invalidation-cache name="invalidation" mode="SYNC"/> <replicated-cache name="repl-sync" mode="SYNC"/> <distributed-cache name="dist-sync" mode="SYNC"/> </cache-container> </infinispan>
As mentioned above, Infinispan supports the notion of configuration templates. These are full or partial configuration declarations which can be shared among multiple caches or as the basis for more complex configurations.
The following example shows how a configuration named
local-template is used to define a cache named
<infinispan> <cache-container default-cache="local"> <!-- template configurations --> <local-cache-configuration name="local-template"> <expiration interval="10000" lifespan="10" max-idle="10"/> </local-cache-configuration> <!-- cache definitions --> <local-cache name="local" configuration="local-template" /> </cache-container> </infinispan>
Templates can inherit from previously defined templates, augmenting and/or overriding some or all of the configuration elements:
<infinispan> <cache-container default-cache="local"> <!-- template configurations --> <local-cache-configuration name="base-template"> <expiration interval="10000" lifespan="10" max-idle="10"/> </local-cache-configuration> <local-cache-configuration name="extended-template" configuration="base-template"> <expiration lifespan="20"/> <memory> <object size="2000"/> </memory> </local-cache-configuration> <!-- cache definitions --> <local-cache name="local" configuration="base-template" /> <local-cache name="local-bounded" configuration="extended-template" /> </cache-container> </infinispan>
In the above example,
base-template defines a local cache with a specific expiration configuration. The
extended-template configuration inherits from
base-template, overriding just a single parameter of the expiration element (all other attributes are inherited) and adds a memory element. Finally, two caches are defined:
local which uses the
base-template configuration and
local-bounded which uses the
| Be aware that for multi-valued elements (such as |
An alternative way to apply templates to caches is to use wildcards in the template name, e.g.
basecache*. Any cache whose name matches the template wildcard will inherit that configuration.
<infinispan> <cache-container> <local-cache-configuration name="basecache*"> <expiration interval="10500" lifespan="11" max-idle="11"/> </local-cache-configuration> <local-cache name="basecache-1"/> <local-cache name="basecache-2"/> </cache-container> </infinispan>
basecache-2 will use the
basecache* configuration. The configuration will also be applied when retrieving undefined caches programmatically.
|If a cache name matches multiple wildcards, i.e. it is ambiguous, an exception will be thrown.|
The configuration parser supports XInclude which means you can split your XML configuration across multiple files:
<infinispan xmlns:xi="http://www.w3.org/2001/XInclude"> <cache-container> <local-cache name="cache-1"/> <xi:include href="included.xml" /> </cache-container> </infinispan>
|the parser supports a minimal subset of the XInclude spec (no support for XPointer, fallback, text processing and content negotiation).|
Programmatic Infinispan configuration is centered around the CacheManager and ConfigurationBuilder API. Although every single aspect of Infinispan configuration could be set programmatically, the most usual approach is to create a starting point in a form of XML configuration file and then in runtime, if needed, programmatically tune a specific configuration to suit the use case best.
EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml"); Cache defaultCache = manager.getCache();
Let’s assume that a new synchronously replicated cache is to be configured programmatically. First, a fresh instance of Configuration object is created using ConfigurationBuilder helper object, and the cache mode is set to synchronous replication. Finally, the configuration is defined/registered with a manager.
Configuration c = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).build(); String newCacheName = "repl"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
The default cache configuration (or any other cache configuration) can be used as a starting point for creation of a new cache. For example, lets say that
infinispan-config-file.xml specifies a replicated cache as a default and that a distributed cache is desired with a specific L1 lifespan while at the same time retaining all other aspects of a default cache. Therefore, the starting point would be to read an instance of a default Configuration object and use
ConfigurationBuilder to construct and modify cache mode and L1 lifespan on a new
Configuration object. As a final step the configuration is defined/registered with a manager.
EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml"); Configuration dcc = manager.getDefaultCacheConfiguration(); Configuration c = new ConfigurationBuilder().read(dcc).clustering().cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L).build(); String newCacheName = "distributedWithL1"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
As long as the base configuration is the default named cache, the previous code works perfectly fine. However, other times the base configuration might be another named cache. So, how can new configurations be defined based on other defined caches? Take the previous example and imagine that instead of taking the default cache as base, a named cache called "replicatedCache" is used as base. The code would look something like this:
EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml"); Configuration rc = manager.getCacheConfiguration("replicatedCache"); Configuration c = new ConfigurationBuilder().read(rc).clustering().cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L).build(); String newCacheName = "distributedWithL1"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
While the above paragraph shows how to combine declarative and programmatic configuration, starting from an XML configuration is completely optional. The ConfigurationBuilder fluent interface style allows for easier to write and more readable programmatic configuration. This approach can be used for both the global and the cache level configuration. GlobalConfiguration objects are constructed using GlobalConfigurationBuilder while Configuration objects are built using ConfigurationBuilder. Let’s look at some examples on configuring both global and cache level options with this API:
Sometimes you might also want to enable collection of global JMX statistics at cache manager level or get information about the transport. To enable global JMX statistics simply do:
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .globalJmxStatistics() .enable() .build();
Please note that by not enabling (or by explicitly disabling) global JMX statistics your are just turning off statistics collection. The corresponding MBean is still registered and can be used to manage the cache manager in general, but the statistics attributes do not return meaningful values.
Further options at the global JMX statistics level allows you to configure the cache manager name which comes handy when you have multiple cache managers running on the same system, or how to locate the JMX MBean Server:
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .globalJmxStatistics() .cacheManagerName("SalesCacheManager") .mBeanServerLookup(new JBossMBeanServerLookup()) .build();
Some of the Infinispan features are powered by a group of the thread pool executors which can also be tweaked at this global level. For example:
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .replicationQueueThreadPool() .threadPoolFactory(ScheduledThreadPoolExecutorFactory.create()) .build();
You can not only configure global, cache manager level, options, but you can also configure cache level options such as the cluster mode:
Configuration config = new ConfigurationBuilder() .clustering() .cacheMode(CacheMode.DIST_SYNC) .sync() .l1().lifespan(25000L) .hash().numOwners(3) .build();
Or you can configure eviction and expiration settings:
Configuration config = new ConfigurationBuilder() .memory() .size(20000) .expiration() .wakeUpInterval(5000L) .maxIdle(120000L) .build();
An application might also want to interact with an Infinispan cache within the boundaries of JTA and to do that you need to configure the transaction layer and optionally tweak the locking settings. When interacting with transactional caches, you might want to enable recovery to deal with transactions that finished with an heuristic outcome and if you do that, you will often want to enable JMX management and statistics gathering too:
Configuration config = new ConfigurationBuilder() .locking() .concurrencyLevel(10000).isolationLevel(IsolationLevel.REPEATABLE_READ) .lockAcquisitionTimeout(12000L).useLockStriping(false).writeSkewCheck(true) .versioning().enable().scheme(VersioningScheme.SIMPLE) .transaction() .transactionManagerLookup(new GenericTransactionManagerLookup()) .recovery() .jmxStatistics() .build();
Configuring Infinispan with chained cache stores is simple too:
Configuration config = new ConfigurationBuilder() .persistence().passivation(false) .addSingleFileStore().location("/tmp").async().enable() .preload(false).shared(false).threadPoolSize(20).build();
The fluent configuration can also be used to configure more advanced or exotic options, such as advanced externalizers:
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .serialization() .addAdvancedExternalizer(998, new PersonExternalizer()) .addAdvancedExternalizer(999, new AddressExternalizer()) .build();
Or, add custom interceptors:
Configuration config = new ConfigurationBuilder() .customInterceptors().addInterceptor() .interceptor(new FirstInterceptor()).position(InterceptorConfiguration.Position.FIRST) .interceptor(new LastInterceptor()).position(InterceptorConfiguration.Position.LAST) .interceptor(new FixPositionInterceptor()).index(8) .interceptor(new AfterInterceptor()).after(NonTransactionalLockingInterceptor.class) .interceptor(new BeforeInterceptor()).before(CallInterceptor.class) .build();
For information on the individual configuration options, please check the configuration guide.
The configuration format of Infinispan has changed since schema version 6.0 in order to align the embedded schema with the one used by the server. For this reason, when upgrading to schema 7.x or later, you should use the configuration converter included in the all distribution. Simply invoke it from the command-line passing the old configuration file as the first parameter and the name of the converted file as the second parameter.
bin/config-converter.sh oldconfig.xml newconfig.xml
bin\config-converter.bat oldconfig.xml newconfig.xml
|If you wish to help write conversion tools from other caching systems, please contact infinispan-dev.|