-
Language:
English
-
Language:
English
Developer Guide
For use with Red Hat JBoss Data Grid 6.1
Edition 2
Abstract
Preface
Chapter 1. JBoss Data Grid
1.1. About JBoss Data Grid
- Schemaless key-value store – Red Hat JBoss Data Grid is a NoSQL database that provides the flexibility to store different objects without a fixed data model.
- Grid-based data storage – Red Hat JBoss Data Grid is designed to easily replicate data across multiple nodes.
- Elastic scaling – Adding and removing nodes is achieved simply and is non-disruptive.
- Multiple access protocols – It is easy to access the data grid using REST, Memcached, Hot Rod, or simple map-like API.
1.2. JBoss Data Grid Supported Configurations
1.3. JBoss Data Grid Usage Modes
1.3.1. JBoss Data Grid Usage Modes
- Remote Client-Server mode
- Library mode
1.3.2. Remote Client-Server Mode
- easier scaling of the data grid.
- easier upgrades of the data grid without impact on client applications.
1.3.3. Library Mode
- transactions.
- listeners and notifications.
1.4. JBoss Data Grid Benefits
Benefits of JBoss Data Grid
- Performance
- Accessing objects from local memory is faster than accessing objects from remote data stores (such as a database). JBoss Data Grid provides an efficient way to store in-memory objects coming from a slower data source, resulting in faster performance than a remote data store. JBoss Data Grid also offers optimization for both clustered and non clustered caches to further improve performance.
- Consistency
- Storing data in a cache carried the inherent risk: at the time it is accessed, the data may be outdated (stale). To address this risk, JBoss Data Grid uses mechanisms such as cache invalidation and expiration to remove stale data entries from the cache. Additionally, JBoss Data Grid supports JTA, distributed (XA) and two-phase commit transactions along with transaction recovery and a version API to remove or replace data according to saved versions.
- Massive Heap and High Availability
- In JBoss Data Grid, applications no longer need to delegate the majority of their data lookup processes to a large single server database for performance benefits. JBoss Data Grid employs techniques such as replication and distribution to completely remove the bottleneck that exists in the majority of current enterprise applications.
Example 1.1. Massive Heap and High Availability Example
In a sample grid with 16 blade servers, each node has 2 GB storage space dedicated for a replicated cache. In this case, all the data in the grid is copies of the 2 GB data. In contrast, using a distributed grid (assuming the requirement of one copy per data item, resulting in the capacity of the overall heap being divided by two) the resulting memory backed virtual heap contains 16 GB data. This data can now be effectively accessed from anywhere in the grid. In case of a server failure, the grid promptly creates new copies of the lost data and places them on operational servers in the grid. - Scalability
- A significant benefit of a distributed data grid over a replicated clustered cache is that a data grid is scalable in terms of both capacity and performance. Add a node to JBoss Data Grid to increase throughput and capacity for the entire grid. JBoss Data Grid uses a consistent hashing algorithm that limits the impact of adding or removing a node to a subset of the nodes instead of every node in the grid.Due to the even distribution of data in JBoss Data Grid, the only upper limit for the size of the grid is the group communication on the network. The network's group communication is minimal and restricted only to the discovery of new nodes. Nodes are permitted by all data access patterns to communicate directly via peer-to-peer connections, facilitating further improved scalability. JBoss Data Grid clusters can be scaled up or down in real time without requiring an infrastructure restart. The result of the real time application of changes in scaling policies results in an exceptionally flexible environment.
- Data Distribution
- JBoss Data Grid uses consistent hash algorithms to determine the locations for keys in clusters. Benefits associated with consistent hashing include:Data distribution ensures that sufficient copies exist within the cluster to provide durability and fault tolerance, while not an abundance of copies, which would reduce the environment's scalability.
- cost effectiveness.
- speed.
- deterministic location of keys with no requirements for further metadata or network traffic.
- Persistence
- JBoss Data Grid exposes a
CacheStore
interface and several high-performance implementations, including the JDBC Cache stores and file system based cache stores. Cache stores can be used to populate the cache when it starts and to ensure that the relevant data remains safe from corruption. The cache store also overflows data to the disk when required if a process runs out of memory. - Language bindings
- JBoss Data Grid supports both the popular Memcached protocol, with existing clients for a large number of popular programming languages, as well as an optimized JBoss Data Grid specific protocol called Hot Rod. As a result, instead of being restricted to Java, JBoss Data Grid can be used for any major website or application. Additionally, remote caches can be accessed using the HTTP protocol via a RESTful API.
- Management
- In a grid environment of several hundred or more servers, management is an important feature. JBoss Operations Network, the enterprise network management software, is the best tool to manage multiple JBoss Data Grid instances. JBoss Operations Network's features allow easy and effective monitoring of the Cache Manager and cache instances.
- Remote Data Grids
- Rather than scale up the entire application server architecture to scale up your data grid, JBoss Data Grid provides a Remote Client-Server mode which allows the data grid infrastructure to be upgraded independently from the application server architecture. Additionally, the data grid server can be assigned different resources than the application server and also allow independent data grid upgrades and application redeployment within the data grid.
1.5. JBoss Data Grid Prerequisites
1.6. JBoss Data Grid Version Information
1.7. JBoss Data Grid Cache Architecture
Figure 1.1. JBoss Data Grid Cache Architecture
- Elements that a user cannot directly interact with (depicted within a dark box), which includes the Cache, Cache Manager, Level 1 Cache, Persistent Store Interfaces and the Persistent Store.
- Elements that a user can interact directly with (depicted within a white box), which includes Cache Interfaces and the Application.
JBoss Data Grid's cache architecture includes the following elements:
- The Persistent Store permanently stores cache instances and entries.
- JBoss Data Grid offers two Persistent Store Interfaces to access the persistent store. Persistent store interfaces can be either:
- A cache loader is a read only interface that provides a connection to a persistent data store. A cache loader can locate and retrieve data from cache instances and from the persistent store.
- A cache store extends the cache loader functionality to include write capabilities by exposing methods that allow the cache loader to load and store states.
- The Level 1 Cache (or L1 Cache) stores remote cache entries after they are initially accessed, preventing unnecessary remote fetch operations for each subsequent use of the same entries.
- The Cache Manager is the primary mechanism used to retrieve a Cache instance in JBoss Data Grid, and can be used as a starting point for using the Cache.
- The Cache stores cache instances retrieved by a Cache Manager.
- Cache Interfaces use protocols such as Memcached and Hot Rod, or REST to interface with the cache. For details about the remote interfaces, refer to the Developer Guide.
- Memcached is a distributed memory object caching system used to store key-values in-memory. The Memcached caching system defines a text based, client-server caching protocol called the Memcached protocol.
- Hot Rod is a binary TCP client-server protocol used in JBoss Data Grid. It was created to overcome deficiencies in other client/server protocols, such as Memcached. Hot Rod enables clients to do smart routing of requests in partitioned or distributed JBoss Data Grid server clusters.
- The REST protocol eliminates the need for tightly coupled client libraries and bindings. The REST API introduces an overhead, and requires a REST client or custom code to understand and create REST calls.
- An application allows the user to interact with the cache via a cache interface. Browsers are a common example of such end-user applications.
1.8. JBoss Data Grid APIs
- Cache
- Batching
- Grouping
- CacheStore and ConfigurationBuilder
- Externalizable
- Notification (also known as the Listener API because it deals with Notifications and Listeners)
- The Asynchronous API (can only be used in conjunction with the Hot Rod Client in Remote Client-Server Mode)
- The REST Interface
- The Memcached Interface
- The Hot Rod Interface
- The RemoteCache API
Part I. Programmable APIs
Chapter 2. The Cache API
2.1. About the Cache API
ConcurrentMap
interface. How entries are stored depends on the cache mode in use. For example, an entry may be replicated to a remote node or an entry may be looked up in a cache store.
Note
2.2. Using the ConfigurationBuilder API to Configure the Cache API
ConfigurationBuilder
helper object.
Configuration c = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).build(); String newCacheName = "repl"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
An explanation of each line of the provided configuration is as follows:
Configuration c = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).build();
In the first line of the configuration, a new cache configuration object (namedc
) is created using theConfigurationBuilder
. Configurationc
is assigned the default values for all cache configuration options except the cache mode, which is overridden and set to synchronous replication (REPL_SYNC
).String newCacheName = "repl";
In the second line of the configuration, a new variable (of typeString
) is created and assigned the valuerepl
.manager.defineConfiguration(newCacheName, c);
In the third line of the configuration, the cache manager is used to define a named cache configuration for itself. This named cache configuration is calledrepl
and its configuration is based on the configuration provided for cache configurationc
in the first line.Cache<String, String> cache = manager.getCache(newCacheName);
In the fourth line of the configuration, the cache manager is used to obtain a reference to the unique instance of therepl
that is held by the cache manager. This cache instance is now ready to be used to perform operations to store and retrieve data.
2.3. Per-Invocation Flags
2.3.1. About Per-Invocation Flags
2.3.2. Per-Invocation Flag Functions
putForExternalRead()
method in JBoss Data Grid's Cache API uses flags internally. This method can load a JBoss Data Grid cache with data loaded from an external resource. To improve the efficiency of this call, JBoss Data Grid calls a normal put
operation passing the following flags:
- The
ZERO_LOCK_ACQUISITION_TIMEOUT
flag: JBoss Data Grid uses an almost zero lock acquisition time when loading data from an external source into a cache. - The
FAIL_SILENTLY
flag: If the locks cannot be acquired, JBoss Data Grid fails silently without throwing any lock acquisition exceptions. - The
FORCE_ASYNCHRONOUS
flag: If clustered, the cache replicates asynchronously, irrespective of the cache mode set. As a result, a response from other nodes is not required.
putForExternalRead
calls of this type are used because the client can retrieve the required data from a persistent store if the data cannot be found in memory. If the client encounters a cache miss, it should retry the operation.
2.3.3. Configure Per-Invocation Flags
withFlags()
method call. For example:
Cache cache = ... cache.getAdvancedCache() .withFlags(Flag.SKIP_CACHE_STORE, Flag.CACHE_MODE_LOCAL) .put("local", "only");
Note
withFlags()
method for each invocation. If the cache operation must be replicated onto another node, the flags are also carried over to the remote nodes.
2.3.4. Per-Invocation Flags Example
put()
, should not return the previous value, two flags are used. The two flags prevent a remote lookup (to get the previous value) in a distributed environment, which in turn prevents the retrieval of the undesired, potential, previous value. Additionally, if the cache is configured with a cache loader, the two flags prevent the previous value from being loaded from its cache store.
Cache cache = ... cache.getAdvancedCache() .withFlags(Flag.IGNORE_RETURN_VALUES) .put("local", "only")
2.4. The AdvancedCache Interface
2.4.1. About the AdvancedCache Interface
AdvancedCache
interface, geared towards extending JBoss Data Grid, in addition to its simple Cache Interface. The AdvancedCache
Interface can:
- Inject custom interceptors.
- Access certain internal components.
- Apply flags to alter the behavior of certain cache methods.
AdvancedCache
:
AdvancedCache advancedCache = cache.getAdvancedCache();
2.4.2. Flag Usage with the AdvancedCache Interface
AdvancedCache.withFlags()
to apply any number of flags to a cache invocation, for example:
advancedCache.withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_LOCKING) .withFlags(Flag.FORCE_SYNCHRONOUS) .put("hello", "world");
2.4.3. Custom Interceptors and the AdvancedCache Interface
AdvancedCache
Interface provides a mechanism that allows advanced developers to attach custom interceptors. Custom interceptors can alter the behavior of the Cache API methods and the AdvacedCache
Interface can be used to attach such interceptors programmatically at run time.
2.4.4. Custom Interceptors
2.4.4.1. About Custom Interceptors
2.4.4.2. Custom Interceptor Design
- A custom interceptor must extend the
CommandInterceptor
. - A custom interceptor must declare a public, empty constructor to allow for instantiation.
- A custom interceptor must have JavaBean style setters defined for any property that is defined through the
property
element.
2.4.4.3. Add Custom Interceptors
2.4.4.3.1. Adding Custom Interceptors Declaratively
<namedCache name="cacheWithCustomInterceptors"> <!-- Define custom interceptors. All custom interceptors need to extend org.jboss.cache.interceptors.base.CommandInterceptor --> <customInterceptors> <interceptor position="FIRST" class="com.mycompany.CustomInterceptor1"> <properties> <property name="attributeOne" value="value1" /> <property name="attributeTwo" value="value2" /> </properties> </interceptor> <interceptor position="LAST" class="com.mycompany.CustomInterceptor2"/> <interceptor index="3" class="com.mycompany.CustomInterceptor1"/> <interceptor before="org.infinispanpan.interceptors.CallInterceptor" class="com.mycompany.CustomInterceptor2"/> <interceptor after="org.infinispanpan.interceptors.CallInterceptor" class="com.mycompany.CustomInterceptor1"/> </customInterceptors> </namedCache>
Note
2.4.4.3.2. Adding Custom Interceptors Programmatically
AdvancedCache
.
CacheManager cm = getCacheManager(); Cache aCache = cm.getCache("aName"); AdvancedCache advCache = aCache.getAdvancedCache();
addInterceptor()
method to add the interceptor.
advCache.addInterceptor(new MyInterceptor(), 0);
Chapter 3. The Batching API
3.1. About the Batching API
Note
3.2. About Java Transaction API Transactions
- First, it retrieves the transactions currently associated with the thread.
- If not already done, it registers
XAResource
with the transaction manager to receive notifications when a transaction is committed or rolled back.
Important
ExceptionTimeout
where JBoss Data Grid is Unable to acquire lock after {time} on key {key} for requester {thread}
, enable transactions. This occurs because non-transactional caches acquire locks on each node they write on. Using transactions prevents deadlocks because caches acquire locks on a single node. This problem is resolved in JBoss Data Grid 6.1.
3.3. Batching and the Java Transaction API (JTA)
- Locks acquired during an invocation are retained until the transaction commits or rolls back.
- All changes are replicated in a batch on all nodes in the cluster as part of the transaction commit process. Ensuring that multiple changes occur within the single transaction, the replication traffic remains lower and improves performance.
- When using synchronous replication or invalidation, a replication or invalidation failure causes the transaction to roll back.
- If a
CacheLoader
that is compatible with a JTA resource, for example a JTADataSource
, is used for a transaction, the JTA resource can also participate in the transaction. - All configurations related to a transaction apply for batching as well.
<transaction syncRollbackPhase="false" syncCommitPhase="false" useEagerLocking="true" eagerLockSingleNode="true" />The configuration attributes can be used for both transactions and batching, using different values.
Note
3.4. Using the Batching API
3.4.1. Enable the Batching API
<distributed-cache name="default" batching="true"> ... </distributed-cache>
3.4.2. Configure the Batching API
To configure the Batching API in the XML file:
<invocationBatching enabled="true" />
To configure the Batching API programmatically use:
Configuration c = new ConfigurationBuilder().invocationBatching().enable().build();
3.4.3. Use the Batching API
startBatch()
and endBatch()
on the cache as follows to use batching:
Cache cache = cacheManager.getCache();
Example 3.1. Without Using Batch
cache.put("key", "value");
cache.put(key, value);
line executes, the values are replaced immediately.
Example 3.2. Using Batch
cache.startBatch(); cache.put("k1", "value"); cache.put("k2", "value"); cache.put("k3", "value"); cache.endBatch(true); cache.startBatch(); cache.put("k1", "value"); cache.put("k2", "value"); cache.put("k3", "value"); cache.endBatch(false);
cache.endBatch(true
);
executes, all modifications made since the batch started are replicated.
cache.endBatch(false
);
executes, changes made in the batch are discarded.
3.4.4. Batching API Usage Example
Example 3.3. Batching API Usage Example
Chapter 4. The Grouping API
4.1. About the Grouping API
4.2. Grouping API Operations
- Intrinsic to the entry, which means it was generated by the key class.
- Extrinsic to the entry, which means it was generated by an external function.
4.3. Grouping API Configuration
To configure JBoss Data Grid using the programmatic API, call the following:
Configuration c = new ConfigurationBuilder().clustering().hash().groups().enabled().build();
To configure JBoss Data Grid using XML, use the following:
<clustering> <hash> <groups enabled="true" /> </hash> </clustering>
@Group
annotation within the method to specify the intrinsic group. For example:
class User { ... String office; ... int hashCode() { // Defines the hash for the key, normally used to determine location ... } // Override the location by specifying a group, all keys in the same // group end up with the same owner @Group String getOffice() { return office; } }
Note
String
.
Grouper
interface. The computeGroup
method within the Grouper
interface returns the group.
Grouper
operates as an interceptor and passes previously computed values to the computeGroup()
method. If defined, @Group
determines which group is passed to the first Grouper
, providing improved group control when using intrinsic groups.
grouper
to determine a key's group, its keyType
must be assignable from the target key.
Grouper
:
public class KXGrouper implements Grouper<String> { // A pattern that can extract from a "kX" (e.g. k1, k2) style key // The pattern requires a String key, of length 2, where the first character is // "k" and the second character is a digit. We take that digit, and perform // modular arithmetic on it to assign it to group "1" or group "2". private static Pattern kPattern = Pattern.compile("(^k)(<a>\\d</a>)$"); public String computeGroup(String key, String group) { Matcher matcher = kPattern.matcher(key); if (matcher.matches()) { String g = Integer.parseInt(matcher.group(2)) % 2 + ""; return g; } else return null; } public Class<String> getKeyType() { return String.class; } }
grouper
uses the key class to extract the group from a key using a pattern. Information specified on the key class is ignored. Each grouper
must be registered to be used.
When configuring JBoss Data Grid programmatically:
Configuration c = new ConfigurationBuilder().clustering().hash().groups().addGrouper(new KXGrouper()).build();
Or when configuring JBoss Data Grid using XML:
<clustering> <hash> <groups enabled="true"> <grouper class="com.acme.KXGrouper" /> </groups> </hash> </clustering>
Chapter 5. The CacheStore and ConfigurationBuilder APIs
5.1. About the CacheStore API
5.2. The ConfigurationBuilder API
5.2.1. About the ConfigurationBuilder API
- Chain coding of configuration options in order to make the coding process more efficient
- Improve the readability of the configuration
5.2.2. Using the ConfigurationBuilder API
5.2.2.1. Programmatically Create a CacheManager and Replicated Cache
Procedure 5.1. Steps for Programmatic Configuration in JBoss Data Grid
- Create a CacheManager as a starting point in an XML file. If required, this CacheManager can be programmed in runtime to the specification that meets the requirements of the use case. The following is an example of how to create a CacheManager:
EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml"); Cache defaultCache = manager.getCache();
- Create a new synchronously replicated cache programmatically.
- Create a new configuration object instance using the ConfigurationBuilder helper object:
Configuration c = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC) .build();
In the first line of the configuration, a new cache configuration object (namedc
) is created using theConfigurationBuilder
. Configurationc
is assigned the default values for all cache configuration options except the cache mode, which is overridden and set to synchronous replication (REPL_SYNC
). - Set the cache mode to synchronous replication:
String newCacheName = "repl";
In the second line of the configuration, a new variable (of typeString
) is created and assigned the valuerepl
. - Define or register the configuration with a manager:
manager.defineConfiguration(newCacheName, c);
In the third line of the configuration, the cache manager is used to define a named cache configuration for itself. This named cache configuration is calledrepl
and its configuration is based on the configuration provided for cache configurationc
in the first line. Cache<String, String> cache = manager.getCache(newCacheName);
In the fourth line of the configuration, the cache manager is used to obtain a reference to the unique instance of therepl
that is held by the cache manager. This cache instance is now ready to be used to perform operations to store and retrieve data.
5.2.2.2. Create a Customized Cache Using the Default Named Cache
infinispan-config-file.xml
specifies the configuration for a replicated cache as a default and a distributed cache with a customized lifespan value is required. The required distributed cache must retain all aspects of the default cache specified in the infinispan-config-file.xml
file except the mentioned aspects.
Procedure 5.2. Customize the Default Cache
- Read an instance of a default Configuration object to get the default configuration:
EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml"); Configuration dcc = cacheManager.getDefaultCacheConfiguration();
- Use the ConfigurationBuilder to construct and modify the cache mode and L1 cache lifespan on a new configuration object:
Configuration c = new ConfigurationBuilder().read(dcc).clustering() .cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L) .build();
- Register/define your cache configuration with a cache manager:
Cache<String, String> cache = manager.getCache(newCacheName);
5.2.2.3. Create a Customized Cache Using a Non-Default Named Cache
replicatedCache
as the base instead of the default cache.
Procedure 5.3. Create a Customized Cache Using a Non-Default Named Cache
- Read the
replicatedCache
to get the default configuration:EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml"); Configuration rc = cacheManager.getCacheConfiguration("replicatedCache");
- Use the ConfigurationBuilder to construct and modify the desired configuration on a new configuration object:
Configuration c = new ConfigurationBuilder().read(rc).clustering() .cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L) .build();
- Register/define your cache configuration with a cache manager:
Cache<String, String> cache = manager.getCache(newCacheName);
5.2.2.4. Using the Configuration Builder to Create Caches Programmatically
5.2.2.5. Global Configuration Examples
5.2.2.5.1. Globally Configure the Transport Layer
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .globalJmxStatistics() .build();
5.2.2.5.2. Globally Configure the Cache Manager Name
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .globalJmxStatistics() .cacheManagerName("SalesCacheManager") .mBeanServerLookupClass(JBossMBeanServerLookup.class) .build();
5.2.2.5.3. Globally Customize Thread Pool Executors
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .replicationQueueScheduledExecutor() .factory(DefaultScheduledExecutorFactory.class) .addProperty("threadNamePrefix", "RQThread") .build();
5.2.2.6. Cache Level Configuration Examples
5.2.2.6.1. Cache Level Configuration for the Cluster Mode
Configuration config = new ConfigurationBuilder() .clustering() .cacheMode(CacheMode.DIST_SYNC) .sync() .l1().lifespan(25000L) .hash().numOwners(3) .build();
5.2.2.6.2. Cache Level Eviction and Expiration Configuration
Configuration config = new ConfigurationBuilder() .eviction() .maxEntries(20000).strategy(EvictionStrategy.LIRS).expiration() .wakeUpInterval(5000L) .maxIdle(120000L) .build();
5.2.2.6.3. Cache Level Configuration for JTA Transactions
Configuration config = new ConfigurationBuilder() .locking() .concurrencyLevel(10000).isolationLevel(IsolationLevel.REPEATABLE_READ) .lockAcquisitionTimeout(12000L).useLockStriping(false).writeSkewCheck(true) .transaction() .recovery() .transactionManagerLookup(new GenericTransactionManagerLookup()) .jmxStatistics() .build();
5.2.2.6.4. Cache Level Configuration Using Chained Persistent Stores
Configuration config = new ConfigurationBuilder() .loaders() .shared(false).passivation(false).preload(false) .addFileCacheStore().location("/tmp").streamBufferSize(1800).async().enable().threadPoolSize(20).build();
5.2.2.6.5. Cache Level Configuration for Advanced Externalizers
GlobalConfiguration globalConfig = new GlobalConfigurationBuilder() .serialization() .addAdvancedExternalizer(PersonExternalizer.class) .addAdvancedExternalizer(999, AddressExternalizer.class) .build();
5.2.2.6.6. Cache Level Configuration for Custom Interceptors
Configuration config = new ConfigurationBuilder() .customInterceptors().interceptors() .add(new FirstInterceptor()).first() .add(new LastInterceptor()).last() .add(new FixPositionInterceptor()).atIndex(8) .add(new AfterInterceptor()).after(LockingInterceptor.class) .add(new BeforeInterceptor()).before(CallInterceptor.class) .build();
Chapter 6. The Externalizable API
6.1. About Externalizer
Externalizer
is a class that can:
- Marshall a given object type to a byte array.
- Unmarshall the contents of a byte array into an instance of the object type.
6.2. About the Externalizable API
6.3. Using the Externalizable API
6.3.1. The Externalizable API Usage
- Transform an object class into a serialized class
- Read an object class from an output.
readObject()
implementations create object instances of the target class. This provides flexibility in the creation of instances and allows target classes to persist immutably.
Note
6.3.2. The Externalizable API Configuration Example
- Provide an
externalizer
implementation for the type of object to be marshalled/unmarshalled. - Annotate the marshalled type class using {@link SerializeWith} to indicate the
externalizer
class.
import org.infinispan.marshall.Externalizer; import org.infinispan.marshall.SerializeWith; @SerializeWith(Person.PersonExternalizer.class) public class Person { final String name; final int age; public Person(String name, int age) { this.name = name; this.age = age; } public static class PersonExternalizer implements Externalizer<Person> { @Override public void writeObject(ObjectOutput output, Person person) throws IOException { output.writeObject(person.name); output.writeInt(person.age); } @Override public Person readObject(ObjectInput input) throws IOException, ClassNotFoundException { return new Person((String) input.readObject(), input.readInt()); } } }
- The payload size generated using this method can be inefficient due to constraints within the model.
- An Externalizer can be required for a class for which the source code is not available, or the source code cannot be modified.
- The use of annotations can limit framework developers or service providers attempting to abstract lower level details, such as marshalling layer.
6.3.3. Linking Externalizers with Marshaller Classes
readObject()
and writeObject()
methods link with the type classes they are configured to externalize by providing a getTypeClasses()
implementation.
import org.infinispan.util.Util; ... @Override public Set<Class<? extends ReplicableCommand>> getTypeClasses() { return Util.asSet(LockControlCommand.class, RehashControlCommand.class, StateTransferControlCommand.class, GetKeyValueCommand.class, ClusteredGetCommand.class, MultipleRpcCommand.class, SingleRpcCommand.class, CommitCommand.class, PrepareCommand.class, RollbackCommand.class, ClearCommand.class, EvictCommand.class, InvalidateCommand.class, InvalidateL1Command.class, PutKeyValueCommand.class, PutMapCommand.class, RemoveCommand.class, ReplaceCommand.class); }
@Override public Set<Class<? extends List>> getTypeClasses() { return Util.<Class<? extends List>>asSet( Util.loadClass("java.util.Collections$SingletonList")); }
6.4. The AdvancedExternalizer
6.4.1. About the AdvancedExternalizer
6.4.2. AdvancedExternalizer Example Configuration
import org.infinispan.marshall.AdvancedExternalizer; public class Person { final String name; final int age; public Person(String name, int age) { this.name = name; this.age = age; } public static class PersonExternalizer implements AdvancedExternalizer<Person> { @Override public void writeObject(ObjectOutput output, Person person) throws IOException { output.writeObject(person.name); output.writeInt(person.age); } @Override public Person readObject(ObjectInput input) throws IOException, ClassNotFoundException { return new Person((String) input.readObject(), input.readInt()); } @Override public Set<Class<? extends Person>> getTypeClasses() { return Util.<Class<? extends Person>>asSet(Person.class); } @Override public Integer getId() { return 2345; } } }
6.4.3. Externalizer Identifiers
getId()
implementations.- Declarative or Programmatic configuration that identifies the externalizer when unmarshalling a payload.
GetId()
will either return a positive integer or a null value:
- A positive integer allows the externalizer to be identified when read and assigned to the correct Externalizer capable of reading the contents.
- A null value indicates that the identifier of the AdvancedExternalizer will be defined via declarative or programmatic configuration.
6.4.4. Registering Advanced Externalizers
The following is an example of a declarative configuration for an advanced Externalizer implementation:
<infinispan> <global> <serialization> <advancedExternalizers> <advancedExternalizer externalizerClass="Person$PersonExternalizer"/> </advancedExternalizers> </serialization> </global> ... </infinispan>
The following is an example of a programmatic configuration for an advanced Externalizer implementation:
GlobalConfigurationBuilder builder = ... builder.serialization() .addAdvancedExternalizer(new Person.PersonExternalizer());
The following is a declarative configuration for the location of the identifier definition during registration:
<infinispan> <global> <serialization> <advancedExternalizers> <advancedExternalizer id="123" externalizerClass="Person$PersonExternalizer"/> </advancedExternalizers> </serialization> </global> ... </infinispan>
The following is a programmatic configuration for the location of the identifier definition during registration:
GlobalConfigurationBuilder builder = ... builder.serialization() .addAdvancedExternalizer(123, new Person.PersonExternalizer());
6.4.5. Register Multiple Externalizers Programmatically
@Marshalls
annotation.
builder.serialization() .addAdvancedExternalizer(new Person.PersonExternalizer(), new Address.AddressExternalizer());
6.5. Internal Externalizer Implementation Access
6.5.1. Internal Externalizer Implementation Access
public static class ABCMarshallingExternalizer implements AdvancedExternalizer<ABCMarshalling> { @Override public void writeObject(ObjectOutput output, ABCMarshalling object) throws IOException { MapExternalizer ma = new MapExternalizer(); ma.writeObject(output, object.getMap()); } @Override public ABCMarshalling readObject(ObjectInput input) throws IOException, ClassNotFoundException { ABCMarshalling hi = new ABCMarshalling(); MapExternalizer ma = new MapExternalizer(); hi.setMap((ConcurrentHashMap<Long, Long>) ma.readObject(input)); return hi; } ...
public static class ABCMarshallingExternalizer implements AdvancedExternalizer<ABCMarshalling> { @Override public void writeObject(ObjectOutput output, ABCMarshalling object) throws IOException { output.writeObject(object.getMap()); } @Override public ABCMarshalling readObject(ObjectInput input) throws IOException, ClassNotFoundException { ABCMarshalling hi = new ABCMarshalling(); hi.setMap((ConcurrentHashMap<Long, Long>) input.readObject()); return hi; } ... }
Chapter 7. The Notification/Listener API
7.1. About the Listener API
7.2. Listener Example
@Listener public class PrintWhenAdded { @CacheEntryCreated public void print(CacheEntryCreatedEvent event) { System.out.println("New entry " + event.getKey() + " created in the cache"); } }
7.3. Cache Entry Modified Listener Configuration
Cache.get()
when isPre
(an Event method) is false
. For more information about isPre()
, refer to the JBoss Data Grid API Documentation's listing for the org.infinispan.notifications.cachelistener.event
package.
CacheEntryModifiedEvent.getValue()
to retrieve the new value of the modified entry.
7.4. Notifications
7.4.1. About Listener Notifications
@Listener
. A Listenable is an interface that denotes that the implementation can have listeners attached to it. Each listener is registered using methods defined in the Listenable.
7.4.2. About Cache-level Notifications
7.4.3. Cache Manager-level Notifications
- Nodes joining or leaving a cluster;
- The starting and stopping of caches
7.4.4. About Synchronous and Asynchronous Notifications
@Listener (sync = false)public class MyAsyncListener { .... }
<asyncListenerExecutor/>
element in the configuration file to tune the thread pool that is used to dispatch asynchronous notifications.
7.5. Notifying Futures
7.5.1. About NotifyingFutures
Futures
, but a sub-interface known as a NotifyingFuture
. Unlike a JDK Future
, a listener can be attached to a NotifyingFuture
to notify the user about a completed future.
Note
NotifyingFutures
are only available in Library mode.
7.5.2. NotifyingFutures Example
NotifyingFutures
in JBoss Data Grid:
FutureListener futureListener = new FutureListener() { public void futureDone(Future future) { try { future.get(); } catch (Exception e) { // Future did not complete successfully System.out.println("Help!"); } } }; cache.putAsync("key", "value").attachListener(futureListener);
Part II. Remote Client-Server Mode Interfaces
Chapter 8. The Asynchronous API
8.1. About the Asynchronous API
Async
appended to each method name. Asynchronous methods return a Future that contains the result of the operation.
Cache(String, String)
, Cache.put(String key, String value)
returns a String, while Cache.putAsync(String key, String value)
returns a Future(String)
.
8.2. Asynchronous API Benefits
- The guarantee of synchronous communication, with the added ability to handle failures and exceptions.
- Not being required to block a thread's operations until the call completes.
Set<Future<?>> futures = new HashSet<Future<?>>(); futures.add(cache.putAsync("key1", "value1")); futures.add(cache.putAsync("key2", "value2")); futures.add(cache.putAsync("key3", "value3"));
futures.add(cache.putAsync(key1, value1));
futures.add(cache.putAsync(key2, value2));
futures.add(cache.putAsync(key3, value3));
8.3. About Asynchronous Processes
- Network calls
- Marshalling
- Writing to a cache store (optional)
- Locking
8.4. Return Values and the Asynchronous API
Future
or the NotifyingFuture
in order to query the previous value.
Note
Future.get()
Chapter 9. The REST Interface
9.1. About the REST Interface in JBoss Data Grid
9.2. Ruby Client Code
require 'net/http' http = Net::HTTP.new('localhost', 8080) #An example of how to create a new entry http.post('/rest/MyData/MyKey', DATA HERE', {"Content-Type" => "text/plain"}) #An example of using a GET operation to retrieve the key puts http.get('/rest/MyData/MyKey').body #An Example of using a PUT operation to overwrite the key http.put('/rest/MyData/MyKey', 'MORE DATA', {"Content-Type" => "text/plain"}) #An example of Removing the remote copy of the key http.delete('/rest/MyData/MyKey') #An example of creating binary data http.put('/rest/MyImages/Image.png', File.read('/Users/michaelneale/logo.png'), {"Content-Type" => "image/png"})
9.3. Using JSON with Ruby Example
To use JavaScript Object Notation (JSON) with ruby to interact with JBoss Data Grid's REST Interface, install the JSON Ruby library (refer to your platform's package manager or the Ruby documentation) and declare the requirement using the following code:
require 'json'
The following code is an example of how to use JavaScript Object Notation (JSON) in conjunction with Ruby to send specific data, in this case the name and age of an individual, using the PUT
function.
data = {:name => "michael", :age => 42 } http.put('/infinispan/rest/Users/data/0', data.to_json, {"Content-Type" => "application/json"})
9.4. Python Client Code
import httplib #How to insert data conn = httplib.HTTPConnection("localhost:8080") data = "SOME DATA HERE \!" #could be string, or a file... conn.request("POST", "/rest/Bucket/0", data, {"Content-Type": "text/plain"}) response = conn.getresponse() print response.status #How to retrieve data import httplib conn = httplib.HTTPConnection("localhost:8080") conn.request("GET", "/rest/Bucket/0") response = conn.getresponse() print response.status print response.read()
9.5. Java Client Code
Define imports as follows:
import java.io.BufferedReader;import java.io.IOException; import java.io.InputStreamReader;import java.io.OutputStreamWriter; import java.net.HttpURLConnection;import java.net.URL;
The following is an example of using Java to add a string value to a cache:
public class RestExample { /** * Method that puts a String value in cache. * @param urlServerAddress * @param value * @throws IOException */ public void putMethod(String urlServerAddress, String value) throws IOException { System.out.println("----------------------------------------"); System.out.println("Executing PUT"); System.out.println("----------------------------------------"); URL address = new URL(urlServerAddress); System.out.println("executing request " + urlServerAddress); HttpURLConnection connection = (HttpURLConnection) address.openConnection(); System.out.println("Executing put method of value: " + value); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "text/plain"); connection.setDoOutput(true); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream()); outputStreamWriter.write(value); connection.connect(); outputStreamWriter.flush(); System.out.println("----------------------------------------"); System.out.println(connection.getResponseCode() + " " + connection.getResponseMessage()); System.out.println("----------------------------------------"); connection.disconnect(); }
The following code is an example of a method used that reads a value specified in a URL using Java to interact with the JBoss Data Grid REST Interface.
/** * Method that gets an value by a key in url as param value. * @param urlServerAddress * @return String value * @throws IOException */ public String getMethod(String urlServerAddress) throws IOException { String line = new String(); StringBuilder stringBuilder = new StringBuilder(); System.out.println("----------------------------------------"); System.out.println("Executing GET"); System.out.println("----------------------------------------"); URL address = new URL(urlServerAddress); System.out.println("executing request " + urlServerAddress); HttpURLConnection connection = (HttpURLConnection) address.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "text/plain"); connection.setDoOutput(true); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); connection.connect(); while ((line = bufferedReader.readLine()) \!= null) { stringBuilder.append(line + '\n'); } System.out.println("Executing get method of value: " + stringBuilder.toString()); System.out.println("----------------------------------------"); System.out.println(connection.getResponseCode() + " " + connection.getResponseMessage()); System.out.println("----------------------------------------"); connection.disconnect(); return stringBuilder.toString(); }
/** * Main method example. * @param args * @throws IOException */ public static void main(String\[\] args) throws IOException { //Note that the cache name is "cacheX" RestExample restExample = new RestExample(); restExample.putMethod("http://localhost:8080/rest/cacheX/1", "Infinispan REST Test"); restExample.getMethod("http://localhost:8080/rest/cacheX/1"); } } }
9.6. Configure the REST Interface
9.6.1. About JBoss Data Grid Connectors
- The
hotrod-connector
element, which defines the configuration for a Hot Rod based connector. - The
memcached-connector
element, which defines the configuration for a memcached based connector. - The
rest-connector
element, which defines the configuration for a REST interface based connector.
9.6.2. Configure REST Connectors
rest-connector
element in JBoss Data Grid's Remote Client-Server mode.
<subsystem xmlns="urn:jboss:domain:datagrid:1.0"> <rest-connector virtual-server="default-host" cache-container="default" context-path="$CONTEXT_PATH" security-domain="other" auth-method="BASIC" security-mode="WRITE" /> </subsystem>
9.6.3. REST Connector Attributes
- The
rest-connector
element specifies the configuration information for the REST connector.- The
virtual-server
parameter specifies the virtual server used by the REST connector. The default value for this parameter isdefault-host
. This is an optional parameter. - The
cache-container
parameter names the cache container used by the REST connector. This is a mandatory parameter. - The
context-path
parameter specifies the context path for the REST connector. The default value for this parameter is an empty string (""
). This is an optional parameter. - the
security-domain
parameter specifies that the specified domain, declared in the security subsystem, should be used to authenticate access to the REST endpoint. This is an optional parameter. If this parameter is omitted, no authentication is performed. - The
auth-method
parameter specifies the method used to retrieve credentials for the end point. The default value for this parameter isBASIC
. Supported alternate values includeDIGEST
,CLIENT-CERT
andSPNEGO
. This is an optional parameter. - The
security-mode
parameter specifies whether authentication is required only for write operations (such as PUT, POST and DELETE) or for read operations (such as GET and HEAD) as well. Valid values for this parameter areWRITE
for authenticating write operations only, orREAD_WRITE
to authenticate read and write operations.
9.7. Using the REST Interface
9.7.1. REST Interface Operations
- Adding data.
- Retrieving data.
- Removing data.
9.7.2. Adding Data
9.7.2.1. Adding Data Using the REST Interface
- HTTP
PUT
method - HTTP
POST
method
PUT
and POST
methods are used, the body of the request contains this data, which includes any information added by the user.
PUT
and POST
methods require a Content-Type header.
9.7.2.2. About PUT /{cacheName}/{cacheKey}
PUT
request from the provided URL form places the payload, (from the request body) in the targeted cache using the provided key. The targeted cache must exist on the server for this task to successfully complete.
hr
is the cache name and payRoll%2F3
is the key. The value %2F
indicates that a /
was used in the key.
http://someserver/rest/hr/payRoll%2F3
Time-To-Live
and Last-Modified
values are updated, if an update is required.
Note
%2F
to represent a /
in the key (as in the provided example) can be successfully run if the server is started using the following argument:
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
9.7.2.3. About POST /{cacheName}/{cacheKey}
POST
method from the provided URL form places the payload (from the request body) in the targeted cache using the provided key. However, in a POST
method, if a value in a cache/key exists, a HTTP CONFLICT
status is returned and the content is not updated.
9.7.3. Retrieving Data
9.7.3.1. Retrieving Data Using the REST Interface
- HTTP
GET
method. - HTTP
HEAD
method.
9.7.3.2. About GET /{cacheName}/{cacheKey}
GET
method returns the data located in the supplied cacheName
, matched to the relevant key, as the body of the response. The Content-Type header provides the type of the data. A browser can directly access the cache.
9.7.3.3. About HEAD /{cacheName}/{cacheKey}
HEAD
method operates in a manner similar to the GET
method, however returns no content (header fields are returned).
9.7.4. Removing Data
9.7.4.1. Removing Data Using the REST Interface
DELETE
method to retrieve data from the cache. The DELETE
method can:
- Remove a cache entry/value. (
DELETE /{cacheName}/{cacheKey}
) - Remove a cache. (
DELETE /{cacheName}
)
9.7.4.2. About DELETE /{cacheName}/{cacheKey}
DELETE /{cacheName}/{cacheKey}
), the DELETE
method removes the key/value from the cache for the provided key.
9.7.4.3. About DELETE /{cacheName}
DELETE /{cacheName}
), the DELETE
method removes all entries in the named cache. After a successful DELETE
operation, the HTTP status code 200
is returned.
9.7.4.4. Background Delete Operations
performAsync
header to true
to ensure an immediate return while the removal operation continues in the background.
9.7.5. REST Interface Operation Headers
9.7.5.1. Headers
Table 9.1. Header Types
Headers | Mandatory/Optional | Values | Default Value | Details |
---|---|---|---|---|
Content-Type | Mandatory | - | - | If the Content-Type is set to application/x-java-serialized-object , it is stored as a Java object. |
performAsync | Optional | True/False | - | If set to true , an immediate return occurs, followed by a replication of data to the cluster on its own. This feature is useful when dealing with bulk data inserts and large clusters. |
timeToLiveSeconds | Optional | Numeric (positive and negative numbers) | -1 (This value prevents expiration as a direct result of timeToLiveSeconds. Expiration values set elsewhere override this default value.) | Reflects the number of seconds before the entry in question is automatically deleted. Setting a negative value for timeToLiveSeconds provides the same result as the default value. |
maxIdleTimeSeconds | Optional | Numeric (positive and negative numbers) | -1 (This value prevents expiration as a direct result of maxIdleTimeSeconds. Expiration values set elsewhere override this default value.) | Contains the number of seconds after the last usage when the entry will be automatically deleted. Passing a negative value provides the same result as the default value. |
timeToLiveSeconds
and maxIdleTimeSeconds
headers:
- If both the
timeToLiveSeconds
andmaxIdleTimeSeconds
headers are assigned the value0
, the cache uses the defaulttimeToLiveSeconds
andmaxIdleTimeSeconds
values configured either using XML or programatically. - If only the
maxIdleTimeSeconds
header value is set to0
, thetimeToLiveSeconds
value should be passed as the parameter (or the default-1
, if the parameter is not present). Additionally, themaxIdleTimeSeconds
parameter value defaults to the values configured either using XML or programatically. - If only the
timeToLiveSeconds
header value is set to0
, expiration occurs immediately and themaxIdleTimeSeconds
value is set to the value passed as a parameter (or the default-1
if no parameter was supplied).
ETags (Entity Tags) are returned for each REST Interface entry, along with a Last-Modified
header that indicates the state of the data at the supplied URL. ETags are used in HTTP operations to request data exclusively in cases where the data has changed to save bandwidth. The following headers support ETags (Entity Tags) based optimistic locking:
Table 9.2. Entity Tag Related Headers
Header | Algorithm | Example | Details |
---|---|---|---|
If-Match | If-Match = "If-Match" ":" ( "*" | 1#entity-tag ) | - | Used in conjunction with a list of associated entity tags to verify that a specified entity (that was previously obtained from a resource) remains current. |
If-None-Match | - | Used in conjunction with a list of associated entity tags to verify that none of the specified entities (that was previously obtained from a resource) are current. This feature facilitates efficient updates of cached information when required and with minimal transaction overhead. | |
If-Modified-Since | If-Modified-Since = "If-Modified-Since" ":" HTTP-date | If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT | Compares the requested variant's last modification time and date with a supplied time and date value. If the requested variant has not been modified since the specified time and date, a 304 (not modified) response is returned without a message-body instead of an entity. |
If-Unmodified-Since | If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date | If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT | Compares the requested variant's last modification time and date with a supplied time and date value. If the requested resources has not been modified since the supplied date and time, the specified operation is performed. If the requested resource has been modified since the supplied date and time, the operation is not performed and a 412 (Precondition Failed) response is returned. |
9.8. REST Interface Security
Note
9.8.1. Enable Security for the REST Endpoint
JBoss Data Grid includes an example standalone-rest-auth.xml
file located within the JBoss Data Grid directory at the location /docs/examples/configs
).
$JDG_HOME/standalone/configuration
directory to use the configuration. From the $JDG_HOME
location, enter the following command to create a copy of the standalone-rest-auth.xml
in the appropriate location:
$ cp docs/examples/configs/standalone-rest-auth.xml standalone/configuration/standalone.xml
standalone-rest-auth.xml
to start with a new configuration template.
Procedure 9.1. Enable Security for the REST Endpoint
standalone.xml
:
Specify Security Parameters
Ensure that the rest endpoint specifies a valid value for thesecurity-domain
andauth-method
parameters. Recommended settings for these parameters are as follows:<subsystem xmlns="urn:jboss:domain:datagrid:1.0"> <rest-connector virtual-server="default-host" cache-container="local" security-domain="other" auth-method="BASIC"/> </subsystem>
Check Security Domain Declaration
Ensure that the security subsystem contains the corresponding security-domain declaration. For details about setting up security-domain declarations, refer to the JBoss Application Server 7 or JBoss Enterprise Application Platform 6 documentation.Add an Application User
Run the relevant script and enter the configuration settings to add an application user.- Run the
adduser.sh
script (located in$JDG_HOME/bin
).- On a Windows system, run the
adduser.bat
file (located in$JDG_HOME/bin
) instead.
- When prompted about the type of user to add, select
Application User (application-users.properties)
by enteringb
. - Accept the default value for realm (
ApplicationRealm
) by pressing the return key. - Specify a username and password.
- When prompted for a role for the created user, enter
REST
. - Ensure the username and application realm information is correct when prompted and enter "yes" to continue.
Verify the Created Application User
Ensure that the created application user is correctly configured.- Check the configuration listed in the
application-users.properties
file (located in$JDG_HOME/standalone/configuration/
). The following is an example of what the correct configuration looks like in this file:user1=2dc3eacfed8cf95a4a31159167b936fc
- Check the configuration listed in the
application-roles.properties
file (located in$JDG_HOME/standalone/configuration/
). The following is an example of what the correct configuration looks like in this file:user1=REST
Test the Server
Start the server and enter the following link in a browser window to access the REST endpoint:http://localhost:8080/rest/namedCache
Note
If testing using a GET request, a405
response code is expected and indicates that the server was successfully authenticated.
Chapter 10. The Memcached Interface
10.1. About the Memcached Protocol
10.2. About Memcached Servers in JBoss Data Grid
- Standalone, where each server acts independently without communication with any other memcached servers.
- Clustered, where servers replicate and distribute data to other memcached servers.
10.3. Using the Memcached Interface
10.3.1. Memcached Statistics
Table 10.1. Memcached Statistics
Statistic | Data Type | Details |
---|---|---|
uptime | 32-bit unsigned integer. | Contains the time (in seconds) that the memcached instance has been available and running. |
time | 32-bit unsigned integer. | Contains the current time. |
version | String | Contains the current version. |
curr_items | 32-bit unsigned integer. | Contains the number of items currently stored by the instance. |
total_items | 32-bit unsigned integer. | Contains the total number of items stored by the instance during its lifetime. |
cmd_get | 64-bit unsigned integer | Contains the total number of get operation requests (requests to retrieve data). |
cmd_set | 64-bit unsigned integer | Contains the total number of set operation requests (requests to store data). |
get_hits | 64-bit unsigned integer | Contains the number of keys that are present from the keys requested. |
get_misses | 64-bit unsigned integer | Contains the number of keys that were not found from the keys requested. |
delete_hits | 64-bit unsigned integer | Contains the number of keys to be deleted that were located and successfully deleted. |
delete_misses | 64-bit unsigned integer | Contains the number of keys to be deleted that were not located and therefore could not be deleted. |
incr_hits | 64-bit unsigned integer | Contains the number of keys to be incremented that were located and successfully incremented |
incr_misses | 64-bit unsigned integer | Contains the number of keys to be incremented that were not located and therefore could not be incremented. |
decr_hits | 64-bit unsigned integer | Contains the number of keys to be decremented that were located and successfully decremented. |
decr_misses | 64-bit unsigned integer | Contains the number of keys to be decremented that were not located and therefore could not be decremented. |
cas_hits | 64-bit unsigned integer | Contains the number of keys to be compared and swapped that were found and successfully compared and swapped. |
cas_misses | 64-bit unsigned integer | Contains the number of keys to be compared and swapped that were not found and therefore not compared and swapped. |
cas_badvalue | 64-bit unsigned integer | Contains the number of keys where a compare and swap occurred but the original value did not match the supplied value. |
evictions | 64-bit unsigned integer | Contains the number of eviction calls performed. |
bytes_read | 64-bit unsigned integer | Contains the total number of bytes read by the server from the network. |
bytes_written | 64-bit unsigned integer | Contains the total number of bytes written by the server to the network. |
10.4. Configure the Memcached Interface
10.4.1. About JBoss Data Grid Connectors
- The
hotrod-connector
element, which defines the configuration for a Hot Rod based connector. - The
memcached-connector
element, which defines the configuration for a memcached based connector. - The
rest-connector
element, which defines the configuration for a REST interface based connector.
10.4.2. Configure Memcached Connectors
memcached-connector
element in JBoss Data Grid's Remote Client-Server Mode.
<subsystem xmlns="urn:jboss:domain:datagrid:1.0"> <memcached-connector socket-binding="memcached" cache-container="default" worker-threads="4" idle-timeout="-1" tcp-nodelay="true" send-buffer-size="0" receive-buffer-size="0" /> </subsystem>
10.4.3. Memcached Connector Attributes
- The following is a list of attributes used to configure the memcached connector within the
connectors
element in JBoss Data Grid's Remote Client-Server Mode.- The
memcached-connector
element defines the configuration elements for use with memcached.- The
socket-binding
parameter specifies the socket binding port used by the memcached connector. This is a mandatory parameter. - The
cache-container
parameter names the cache container used by the memcached connector. This is a mandatory parameter. - The
worker-threads
parameter specifies the number of worker threads available for the memcached connector. The default value for this parameter is the number of cores available multiplied by two. This is an optional parameter. - The
idle-timeout
parameter specifies the time (in milliseconds) the connector can remain idle before the connection times out. The default value for this parameter is-1
, which means that no timeout period is set. This is an optional parameter. - The
tcp-nodelay
parameter specifies whether TCP packets will be delayed and sent out in batches. Valid values for this parameter aretrue
andfalse
. The default value for this parameter istrue
. This is an optional parameter. - The
send-buffer-size
parameter indicates the size of the send buffer for the memcached connector. The default value for this parameter is the size of the TCP stack buffer. This is an optional parameter. - The
receive-buffer-size
parameter indicates the size of the receive buffer for the memcached connector. The default value for this parameter is the size of the TCP stack buffer. This is an optional parameter.
Chapter 11. The Hot Rod Interface
11.1. About Hot Rod
11.2. The Benefits of Using Hot Rod over Memcached
- Memcached
- The memcached protocol causes the server endpoint to use the memcached text wire protocol. The memcached wire protocol has the benefit of being commonly used, and is available for almost any platform. All of JBoss Data Grid's functions, including clustering, state sharing for scalability, and high availability, are available when using memcached.However the memcached protocol lacks dynamicity, resulting in the need to manually update the list of server nodes on your clients in the event one of the nodes in a cluster fails. Also, memcached clients are not aware of the location of the data in the cluster. This means that they will request data from a non-owner node, incurring the penalty of an additional request from that node to the actual owner, before being able to return the data to the client. This is where the Hot Rod protocol is able to provide greater performance than memcached.
- Hot Rod
- JBoss Data Grid's Hot Rod protocol is a binary wire protocol that offers all the capabilities of memcached, while also providing better scaling, durability, and elasticity.The Hot Rod protocol does not need the hostnames and ports of each node in the remote cache, whereas memcached requires these parameters to be specified. Hot Rod clients automatically detect changes in the topology of clustered Hot Rod servers; when new nodes join or leave the cluster, clients update their Hot Rod server topology view. Consequently, Hot Rod provides ease of configuration and maintenance, with the advantage of dynamic load balancing and failover.Additionally, the Hot Rod wire protocol uses smart routing when connecting to a distributed cache. This involves sharing a consistent hash algorithm between the server nodes and clients, resulting in faster read and writing capabilities than memcached.
11.3. About Hot Rod Servers in JBoss Data Grid
11.4. Hot Rod Hash Functions
Integer.MAX_INT
). This value is returned to the client using the Hot Rod protocol each time a hash-topology change is detected to prevent Hot Rod clients assuming a specific hash space as a default. The hash space can only contain positive numbers ranging from 0
to Integer.MAX_INT
.
11.5. Hot Rod Server Nodes
11.5.1. About Consistent Hashing Algorithms
11.5.2. The hotrod.properties File
infinispan.client.hotrod.server_list=remote-server:11222
infinispan.client.hotrod.request_balancing_strategy
- For replicated (vs distributed) Hot Rod server clusters, the client balances requests to the servers according to this strategy.The default value for this property is
org.infinispan.client.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy
. infinispan.client.hotrod.server_list
- This is the initial list of Hot Rod servers to connect to, specified in the following format: host1:port1;host2:port2... At least one host:port must be specified.The default value for this property is
127.0.0.1:11222
. infinispan.client.hotrod.force_return_values
- Whether or not to enable Flag.FORCE_RETURN_VALUE for all calls.The default value for this property is
false
. infinispan.client.hotrod.tcp_no_delay
- Affects TCP NODELAY on the TCP stack.The default value for this property is
true
. infinispan.client.hotrod.ping_on_startup
- If true, a ping request is sent to a back end server in order to fetch cluster's topology.The default value for this property is
true
. infinispan.client.hotrod.transport_factory
- Controls which transport will be used. Currently only the TcpTransport is supported.The default value for this property is
org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory
. infinispan.client.hotrod.marshaller
- Allows you to specify a custom Marshaller implementation to serialize and deserialize user objects.The default value for this property is
org.infinispan.marshall.jboss.GenericJBossMarshaller
. infinispan.client.hotrod.async_executor_factory
- Allows you to specify a custom asynchronous executor for async calls.The default value for this property is
org.infinispan.client.hotrod.impl.async.DefaultAsyncExecutorFactory
. infinispan.client.hotrod.default_executor_factory.pool_size
- If the default executor is used, this configures the number of threads to initialize the executor with.The default value for this property is
10
. infinispan.client.hotrod.default_executor_factory.queue_size
- If the default executor is used, this configures the queue size to initialize the executor with.The default value for this property is
100000
. infinispan.client.hotrod.hash_function_impl.1
- This specifies the version of the hash function and consistent hash algorithm in use, and is closely tied with the Hot Rod server version used.The default value for this property is the
Hash function specified by the server in the responses as indicated in ConsistentHashFactory
. infinispan.client.hotrod.key_size_estimate
- This hint allows sizing of byte buffers when serializing and deserializing keys, to minimize array resizing.The default value for this property is
64
. infinispan.client.hotrod.value_size_estimate
- This hint allows sizing of byte buffers when serializing and deserializing values, to minimize array resizing.The default value for this property is
512
. infinispan.client.hotrod.socket_timeout
- This property defines the maximum socket read timeout before giving up waiting for bytes from the server.The default value for this property is
60000 (equals 60 seconds)
. infinispan.client.hotrod.protocol_version
- This property defines the protocol version that this client should use. Other valid values include 1.0.The default value for this property is
1.1
. infinispan.client.hotrod.connect_timeout
- This property defines the maximum socket connect timeout before giving up connecting to the server.The default value for this property is
60000 (equals 60 seconds)
.
11.6. Hot Rod Headers
11.6.1. Hot Rod Header Data Types
Table 11.1. Header Data Types
Data Type | Size | Details |
---|---|---|
vInt | Between 1-5 bytes. | Unsigned variable length integer values. |
vLong | Between 1-9 bytes. | Unsigned variable length long values. |
string | - | Strings are always represented using UTF-8 encoding. |
11.6.2. Request Header
Table 11.2. Request Header Fields
Field Name | Data Type/Size | Details |
---|---|---|
Magic | 1 byte | Indicates whether the header is a request header or response header. |
Message ID | vLong | Contains the message ID. Responses use this unique ID when responding to a request. This allows Hot Rod clients to implement the protocol in an asynchronous manner. |
Version | 1 byte | Contains the Hot Rod server version. |
Opcode | 1 byte | Contains the relevant operation code. In a request header, opcode can only contain the request operation codes. |
Cache Name Length | vInt | Stores the length of the cache name. If Cache Name Length is set to 0 and no value is supplied for Cache Name, the operation interacts with the default cache. |
Cache Name | string | Stores the name of the target cache for the specified operation. This name must match the name of a predefined cache in the cache configuration file. |
Flags | vInt | Contains a numeric value of variable length that represents flags passed to the system. Each bit represents a flag, except the most significant bit, which is used to determine whether more bytes must be read. Using a bit to represent each flag facilitates the representation of flag combinations in a condensed manner. |
Client Intelligence | 1 byte | Contains a value that indicates the client capabilities to the server. |
Topology ID | vInt | Contains the last known view ID in the client. Basic clients supply the value 0 for this field. Clients that support topology or hash information supply the value 0 until the server responds with the current view ID, which is subsequently used until a new view ID is returned by the server to replace the current view ID. |
Transaction Type | 1 byte | Contains a value that represents one of two known transaction types. Currently, the only supported value is 0 . |
Transaction ID | byte-array | Contains a byte array that uniquely identifies the transaction associated with the call. The transaction type determines the length of this byte array. If the value for Transaction Type was set to 0 , no Transaction ID is present. |
11.6.3. Response Header
Table 11.3. Response Header Fields
Field Name | Data Type | Details |
---|---|---|
Magic | 1 byte | Indicates whether the header is a request or response header. |
Message ID | vLong | Contains the message ID. This unique ID is used to pair the response with the original request. This allows Hot Rod clients to implement the protocol in an asynchronous manner. |
Opcode | 1 byte | Contains the relevant operation code. In a response header, opcode can only contain the response operation codes. |
Status | 1 byte | Contains a code that represents the status of the response. |
Topology Change Marker | 1 byte | Contains a marker byte that indicates whether the response is included in the topology change information. |
11.6.4. Topology Change Headers
11.6.4.1. About Topology Change Headers
topology ID
and the topology ID
sent by the client and, if the two differ, it returns a new topology ID
.
11.6.4.2. Topology Change Marker Values
Topology Change Marker
field in a response header:
Table 11.4. Topology Change Marker Field Values
Value | Details |
---|---|
0 | No topology change information is added. |
1 | Topology change information is added. |
11.6.4.3. Topology Change Headers for Topology-Aware Clients
Table 11.5. Topology Change Header Fields
Response Header Fields | Data Type/Size | Details |
---|---|---|
Response Header with Topology Change Marker | - | - |
Topology ID | vInt | - |
Num Servers in Topology | vInt | Contains the number of Hot Rod servers running in the cluster. This value can be a subset of the entire cluster if only some nodes are running Hot Rod servers. |
mX: Host/IP Length | vInt | Contains the length of the hostname or IP address of an individual cluster member. Variable length allows this element to include hostnames, IPv4 and IPv addresses. |
mX: Host/IP Address | string | Contains the hostname or IP address of an individual cluster member. The Hot Rod client uses this information to access the individual cluster member. |
mX: Port | Unsigned Short. 2 bytes | Contains the port used by Hot Rod clients to communicate with the cluster member. |
mX
, are repeated for each server in the topology. The first server in the topology's information fields will be prefixed with m1
and the numerical value is incremented by one for each additional server till the value of X
equals the number of servers specified in the num servers in topology
field.
11.6.4.4. Topology Change Headers for Hash Distribution-Aware Clients
Table 11.6. Topology Change Header Fields
Field | Data Type/Size | Details |
---|---|---|
Response Header with Topology Change Marker | - | - |
Topology ID | vInt | - |
Number Key Owners | Unsigned short. 2 bytes. | Contains the number of globally configured copies for each distributed key. Contains the value 0 if distribution is not configured on the cache. |
Hash Function Version | 1 byte | Contains a pointer to the hash function in use. Contains the value 0 if distribution is not configured on the cache. |
Hash Space Size | vInt | Contains the modulus used by JBoss Data Grid for all module arithmetic related to hash code generation. Clients use this information to apply the correct hash calculations to the keys. Contains the value 0 if distribution is not configured on the cache. |
Number servers in topology | vInt | Contains the number of Hot Rod servers running in the cluster. This value can be a subset of the entire cluster if only some nodes are running Hot Rod servers. This value also represents the number of host to port pairings included in the header. |
Number Virtual Nodes Owners | vInt | Contains the number of configured virtual nodes. Contains the value 0 if no virtual nodes are configured or if distribution is not configured on the cache. |
mX: Host/IP Length | vInt | Contains the length of the hostname or IP address of an individual cluster member. Variable length allows this element to include hostnames, IPv4 and IPv6 addresses. |
mX: Host/IP Address | string | Contains the hostname or IP address of an individual cluster member. The Hot Rod client uses this information to access the individual cluster member. |
mX: Port | Unsigned short. 2 bytes. | Contains the port used by Hot Rod clients to communicate with the cluster member. |
mX: Hashcode | 4 bytes. |
mX
, are repeated for each server in the topology. The first server in the topology's information fields will be prefixed with m1
and the numerical value is incremented by one for each additional server till the value of X
equals the number of servers specified in the num servers in topology
field.
11.7. Hot Rod Operations
11.7.1. Hot Rod Operations
- Get
- BulkGet
- GetWithVersion
- Put
- PutIfAbsent
- Remove
- RemoveIfUnmodified
- Replace
- ReplaceIfUnmodified
- Clear
- ContainsKey
- Ping
- Stats
11.7.2. Hot Rod Get Operation
Get
operation uses the following request format:
Table 11.7. Get Operation Request Format
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. The vInt data type is used because of its size (up to 6 bytes), which is larger than the size of Integer.MAX_VALUE . However, Java disallows single array sizes to exceed the size of Integer.MAX_VALUE . As a result, this vInt is also limited to the maximum size of Integer.MAX_VALUE . |
Key | Byte array | Contains a key, the corresponding value of which is requested. |
Table 11.8. Get Operation Response Format
Response Status | Details |
---|---|
0x00 | Successful operation. |
0x02 | The key does not exist. |
get
operation's response when the key is found is as follows:
Table 11.9. Get Operation Response Format
Field | Data Type | Details |
---|---|---|
Header | - | - |
Value Length | vInt | Contains the length of the value. |
Value | Byte array | Contains the requested value. |
11.7.3. Hot Rod BulkGet Operation
BulkGet
operation uses the following request format:
Table 11.10. BulkGet Operation Request Format
Field | Data Type | Details |
---|---|---|
Header | - | - |
Entry Count | vInt | Contains the maximum number of JBoss Data Grid entries to be returned by the server. The entry count value equals the sum of the key and the associated value. |
Table 11.11. BulkGet Operation Response Format
Field | Data Type | Details |
---|---|---|
Header | - | - |
More | vInt | Represents if more entries must be read from the stream. While More is set to 1 , additional entries follow until the value of More is set to 0 , which indicates the end of the stream. |
Key Size | - | Contains the size of the key. |
Key | - | Contains the key value. |
Value Size | - | Contains the size of the value. |
Value | - | Contains the value. |
More
, Key Size
, Key
, Value Size
and Value
entry is appended to the response.
11.7.4. Hot Rod GetWithVersion Operation
GetWithVersion
operation uses the following request format:
Table 11.12. GetWithVersion Operation Request Format
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. The vInt data type is used because of its size (up to 6 bytes), which is larger than the size of Integer.MAX_VALUE . However, Java disallows single array sizes to exceed the size of Integer.MAX_VALUE . As a result, this vInt is also limited to the maximum size of Integer.MAX_VALUE . |
Key | Byte array | Contains a key, the corresponding value of which is requested. |
Table 11.13. GetWithVersion Operation Response Format
Response Status | Details |
---|---|
0x00 | Successful operation. |
0x02 | The key does not exist. |
Table 11.14.
Field | Data Type/Size | Details |
---|---|---|
Entry Version | 8 bytes | Contains the unique value of an existing entry's modification. |
Value Length | vInt | Contains the length of the value. |
Value | Byte array | Contains the requested value. |
11.7.5. Hot Rod Put Operation
put
operation request format includes the following:
Table 11.15.
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | - | Contains the length of the key. |
Key | Byte array | Contains the key value. |
Lifespan | vInt | Contains the number of seconds before the entry expires. If the number of seconds exceeds thirty days, the value is treated as UNIX time (i.e. the number of seconds since the date 1/1/1970 ) as the entry lifespan. When set to the value 0 , the entry will never expire. |
Max Idle | vInt | Contains the number of seconds an entry is allowed to remain idle before it is evicted from the cache. If this entry is set to 0 , the entry is allowed to remain idle indefinitely without being evicted due to the max idle value. |
Value Length | vInt | Contains the length of the value. |
Value | Byte array | The requested value. |
Table 11.16.
Response Status | Details |
---|---|
0x00 | The value was successfully stored. |
ForceReturnPreviousValue
is passed, the previous value and key are returned. If the previous key and value do not exist, the value length would contain the value 0
.
11.7.6. Hot Rod PutIfAbsent Operation
putIfAbsent
operation request format includes the following:
Table 11.17. PutIfAbsent Operation Request Fields
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. |
Key | Byte array | Contains the key value. |
Lifespan | vInt | Contains the number of seconds before the entry expires. If the number of seconds exceeds thirty days, the value is treated as UNIX time (i.e. the number of seconds since the date 1/1/1970 ) as the entry lifespan. When set to the value 0 , the entry will never expire. |
Max Idle | vInt | Contains the number of seconds an entry is allowed to remain idle before it is evicted from the cache. If this entry is set to 0 , the entry is allowed to remain idle indefinitely without being evicted due to the max idle value. |
Value Length | vInt | Contains the length of the value. |
Value | Byte array | Contains the requested value. |
Table 11.18.
Response Status | Details |
---|---|
0x00 | The value was successfully stored. |
0x01 | The key was present, therefore the value was not stored. The current value of the key is returned. |
ForceReturnPreviousValue
is passed, the previous value and key are returned. If the previous key and value do not exist, the value length would contain the value 0
.
11.7.7. Hot Rod Remove Operation
Hot Rod
Remove
operation uses the following request format:
Table 11.19. Remove Operation Request Format
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. The vInt data type is used because of its size (up to 6 bytes), which is larger than the size of Integer.MAX_VALUE . However, Java disallows single array sizes to exceed the size of Integer.MAX_VALUE . As a result, this vInt is also limited to the maximum size of Integer.MAX_VALUE . |
Key | Byte array | Contains a key, the corresponding value of which is requested. |
Table 11.20. Remove Operation Response Format
Response Status | Details |
---|---|
0x00 | Successful operation. |
0x02 | The key does not exist. |
ForceReturnPreviousValue
is passed, the response header contains either:
- The value and length of the previous key.
- The value length
0
and the response status0x02
to indicate that the key does not exist.
ForceReturnPreviousValue
is passed. If the key does not exist or the previous value was null, the value length is 0
.
11.7.8. Hot Rod RemoveIfUnmodified Operation
RemoveIfUnmodified
operation request format includes the following:
Table 11.21. RemoveIfUnmodified Operation Request Fields
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. |
Key | Byte array | Contains the key value. |
Entry Version | 8 bytes | Uses the value returned by the GetWithVersion operation. |
Table 11.22. RemoveIfUnmodified Operation Response
Response Status | Details |
---|---|
0x00 | Returned status if the entry was replaced or removed. |
0x01 | Returns status if the entry replace or remove was unsuccessful because the key was modified. |
0x02 | Returns status if the key does not exist. |
ForceReturnPreviousValue
is passed, the previous value and key are returned. If the previous key and value do not exist, the value length would contain the value 0
.
11.7.9. Hot Rod Replace Operation
replace
operation request format includes the following:
Table 11.23. Replace Operation Request Fields
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. |
Key | Byte array | Contains the key value. |
Lifespan | vInt | Contains the number of seconds before the entry expires. If the number of seconds exceeds thirty days, the value is treated as UNIX time (i.e. the number of seconds since the date 1/1/1970 ) as the entry lifespan. When set to the value 0 , the entry will never expire. |
Max Idle | vInt | Contains the number of seconds an entry is allowed to remain idle before it is evicted from the cache. If this entry is set to 0 , the entry is allowed to remain idle indefinitely without being evicted due to the max idle value. |
Value Length | vInt | Contains the length of the value. |
Value | Byte array | Contains the requested value. |
Table 11.24. Replace Operation Response
Response Status | Details |
---|---|
0x00 | The value was successfully stored. |
0x01 | The value was not stored because the key does not exist. |
ForceReturnPreviousValue
is passed, the previous value and key are returned. If the previous key and value do not exist, the value length would contain the value 0
.
11.7.10. Hot Rod ReplaceIfUnmodified Operation
ReplaceIfUnmodified
operation request format includes the following:
Table 11.25. ReplaceIfUnmodified Operation Request Fields
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. |
Key | Byte array | Contains the key value. |
Lifespan | vInt | Contains the number of seconds before the entry expires. If the number of seconds exceeds thirty days, the value is treated as UNIX time (i.e. the number of seconds since the date 1/1/1970 ) as the entry lifespan. When set to the value 0 , the entry will never expire. |
Max Idle | vInt | Contains the number of seconds an entry is allowed to remain idle before it is evicted from the cache. If this entry is set to 0 , the entry is allowed to remain idle indefinitely without being evicted due to the max idle value. |
Entry Version | 8 bytes | Uses the value returned by the GetWithVersion operation. |
Value Length | vInt | Contains the length of the value. |
Value | Byte array | Contains the requested value. |
Table 11.26. ReplaceIfUnmodified Operation Response
Response Status | Details |
---|---|
0x00 | Returned status if the entry was replaced or removed. |
0x01 | Returns status if the entry replace or remove was unsuccessful because the key was modified. |
0x02 | Returns status if the key does not exist. |
ForceReturnPreviousValue
is passed, the previous value and key are returned. If the previous key and value do not exist, the value length would contain the value 0
.
11.7.11. Hot Rod Clear Operation
clear
operation format includes only a header.
Table 11.27. Clear Operation Response
Response Status | Details |
---|---|
0x00 | JBoss Data Grid was successfully cleared. |
11.7.12. Hot Rod ContainsKey Operation
ContainsKey
operation uses the following request format:
Table 11.28. ContainsKey Operation Request Format
Field | Data Type | Details |
---|---|---|
Header | - | - |
Key Length | vInt | Contains the length of the key. The vInt data type is used because of its size (up to 6 bytes), which is larger than the size of Integer.MAX_VALUE . However, Java disallows single array sizes to exceed the size of Integer.MAX_VALUE . As a result, this vInt is also limited to the maximum size of Integer.MAX_VALUE . |
Key | Byte array | Contains a key, the corresponding value of which is requested. |
Table 11.29. ContainsKey Operation Response Format
Response Status | Details |
---|---|
0x00 | Successful operation. |
0x02 | The key does not exist. |
11.7.13. Hot Rod Ping Operation
ping
is an application level request to check for server availability.
Table 11.30. Ping Operation Response
Response Status | Details |
---|---|
0x00 | Successful ping without any errors. |
11.7.14. Hot Rod Stats Operation
Table 11.31. Stats Operation Request Fields
Name | Details |
---|---|
timeSinceStart | Contains the number of seconds since Hot Rod started. |
currentNumberOfEntries | Contains the number of entries that currently exist in the Hot Rod server. |
totalNumberOfEntries | Contains the total number of entries stored in the Hot Rod server. |
stores | Contains the number of put operations attempted. |
retrievals | Contains the number of get operations attempted. |
hits | Contains the number of get hits. |
misses | Contains the number of get misses. |
removeHits | Contains the number of remove hits. |
removeMisses | Contains the number of removal misses. |
Table 11.32. Stats Operation Response
Name | Data Type | Details |
---|---|---|
Header | - | - |
Number of Stats | vInt | Contains the number of individual statistics returned. |
Name Length | vInt | Contains the length of the named statistic. |
Name | string | Contains the name of the statistic. |
Value Length | vInt | Contains the length of the value. |
Value | string | Contains the statistic value. |
Name Length
, Name
, Value Length
and Value
recur for each statistic requested.
11.7.15. Hot Rod Operation Values
11.7.15.1. Opcode Request and Response Values
opcode
values for a request header and their corresponding response header values:
Table 11.33. Opcode Request and Response Header Values
Operation | Request Operation Code | Response Operation Code |
---|---|---|
put | 0x01 | 0x02 |
get | 0x03 | 0x04 |
putIfAbsent | 0x05 | 0x06 |
replace | 0x07 | 0x08 |
replaceIfUnmodified | 0x09 | 0x0A |
remove | 0x0B | 0x0C |
removeIfUnmodified | 0x0D | 0x0E |
containsKey | 0x0F | 0x10 |
getWithVersion | 0x11 | 0x12 |
clear | 0x13 | 0x14 |
stats | 0x15 | 0x16 |
ping | 0x17 | 0x18 |
bulkGet | 0x19 | 0x1A |
opcode
value is 0x50
, it indicates an error response.
11.7.15.2. Magic Values
Magic
field in request and response headers:
Table 11.34. Magic Field Values
Value | Details |
---|---|
0xA0 | Cache request marker. |
0xA1 | Cache response marker. |
11.7.15.3. Status Values
Status
field in a response header:
Table 11.35. Status Values
Value | Details |
---|---|
0x00 | No error. |
0x01 | Not put/removed/replaced. |
0x02 | Key does not exist. |
0x81 | Invalid Magic value or Message ID. |
0x82 | Unknown command. |
0x83 | Unknown version. |
0x84 | Request parsing error. |
0x85 | Server error. |
0x86 | Command timed out. |
11.7.15.4. Transaction Type Values
Transaction Type
in a request header:
Table 11.36. Transaction Type Field Values
Value | Details |
---|---|
0 | Indicates a non-transactional call or that the client does not support transactions. If used, the TX_ID field is omitted. |
1 | Indicates X/Open XA transaction ID (XID). This value is currently not supported. |
11.7.15.5. Client Intelligence Values
Client Intelligence
in a request header:
Table 11.37. Client Intelligence Field Values
Value | Details |
---|---|
0x01 | Indicates a basic client that does not require any cluster or hash information. |
0x02 | Indicates a client that is aware of topology and requires cluster information. |
0x03 | Indicates a client that is aware of hash and distribution and requires both the cluster and hash information. |
11.7.15.6. Flag Values
flag
values in the request header:
Table 11.38. Flag Field Values
Value | Details |
---|---|
0x0001 | ForceReturnPreviousValue |
11.7.15.7. Hot Rod Error Handling
Table 11.39. Hot Rod Error Handling using Response Header Fields
Field | Data Type | Details |
---|---|---|
Error Opcode | - | Contains the error operation code. |
Error Status Number | - | Contains a status number that corresponds to the error opcode . |
Error Message Length | vInt | Contains the length of the error message. |
Error Message | string | Contains the actual error message. If an 0x84 error code returns, which indicates that there was an error in parsing the request, this field contains the latest version supported by the Hot Rod server. |
11.8. Examples
11.8.1. Put Request Example
put
request using Hot Rod:
Table 11.40. Put Request Example
Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
8 | 0xA0 | 0x09 | 0x41 | 0x01 | 0x07 | 0x4D ('M') | 0x79 ('y') | 0x43 ('C') |
16 | 0x61 ('a') | 0x63 ('c') | 0x68 ('h') | 0x65 ('e') | 0x00 | 0x03 | 0x00 | 0x00 |
24 | 0x00 | 0x05 | 0x48 ('H') | 0x65 ('e') | 0x6C ('l') | 0x6C ('l') | 0x6F ('o') | 0x00 |
32 | 0x00 | 0x05 | 0x57 ('W') | 0x6F ('o') | 0x72 ('r') | 0x6C ('l') | 0x64 ('d') | - |
Table 11.41. Example Request Field Names and Values
Field Name | Byte | Value |
---|---|---|
Magic | 0 | 0xA0 |
Version | 2 | 0x41 |
Cache Name Length | 4 | 0x07 |
Flag | 12 | 0x00 |
Topology ID | 14 | 0x00 |
Transaction ID | 16 | 0x00 |
Key | 18-22 | 'Hello' |
Max Idle | 24 | 0x00 |
Value | 26-30 | 'World' |
Message ID | 1 | 0x09 |
Opcode | 3 | 0x01 |
Cache Name | 5-11 | 'MyCache' |
Client Intelligence | 13 | 0x03 |
Transaction Type | 15 | 0x00 |
Key Field Length | 17 | 0x05 |
Lifespan | 23 | 0x00 |
Value Field Length | 25 | 0x05 |
put
request:
Table 11.42. Coded Response for the Sample Put Request
Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
8 | 0xA1 | 0x09 | 0x01 | 0x00 | 0x00 | - | - | - |
Table 11.43. Example Response Field Names and Values
Field Name | Byte | Value |
---|---|---|
Magic | 0 | 0xA1 |
Opcode | 2 | 0x01 |
Topology Change Marker | 4 | 0x00 |
Message ID | 1 | 0x09 |
Status | 3 | 0x00 |
11.9. Configure the Hot Rod Interface
11.9.1. About JBoss Data Grid Connectors
- The
hotrod-connector
element, which defines the configuration for a Hot Rod based connector. - The
memcached-connector
element, which defines the configuration for a memcached based connector. - The
rest-connector
element, which defines the configuration for a REST interface based connector.
11.9.2. Configure Hot Rod Connectors
hotrod-connector
element in JBoss Data Grid's Remote Client-Server Mode.
<subsystem xmlns="urn:jboss:domain:datagrid:1.0"> <hotrod-connector socket-binding="hotrod" cache-container="default" worker-threads="4" idle-timeout="-1" tcp-nodelay="true" send-buffer-size="0" receive-buffer-size="0" /> <topology-state-transfer lock-timeout="10000" replication-timeout="10000" update-timeout="30000" external-host="192.168.0.1" external-port="11222" lazy-retrieval="true" /> </subsystem>
11.9.3. Hot Rod Connector Attributes
The hotrod-connector
element defines the configuration elements for use with Hot Rod.
- The
socket-binding
parameter specifies the socket binding port used by the Hot Rod connector. This is a mandatory parameter. - The
cache-container
parameter names the cache container used by the Hot Rod connector. This is a mandatory parameter. - The
worker-threads
parameter specifies the number of worker threads available for the Hot Rod connector. The default value for this parameter is the number of cores available multiplied by two. This is an optional parameter. - The
idle-timeout
parameter specifies the time (in milliseconds) the connector can remain idle before the connection times out. The default value for this parameter is-1
, which means that no timeout period is set. This is an optional parameter. - The
tcp-nodelay
parameter specifies whether TCP packets will be delayed and sent out in batches. Valid values for this parameter aretrue
andfalse
. The default value for this parameter istrue
. This is an optional parameter. - The
send-buffer-size
parameter indicates the size of the send buffer for the Hot Rod connector. The default value for this parameter is the size of the TCP stack buffer. This is an optional parameter. - The
receive-buffer-size
parameter indicates the size of the receive buffer for the Hot Rod connector. The default value for this parameter is the size of the TCP stack buffer. This is an optional parameter.
The Topology-State-Transfer ElementThe
topology-state-transfer
element specifies the topology state transfer configurations for the Hot Rod connector. This element can only occur once within ahotrod-connector
element.- The
lock-timeout
parameter specifies the time (in milliseconds) after which the operation attempting to obtain a lock times out. The default value for this parameter is10
seconds. This is an optional parameter. - The
replication-timeout
parameter specifies the time (in milliseconds) after which the replication operation times out. The default value for this parameter is10
seconds. This is an optional parameter. - The
update-timeout
parameter specifies the time (in milliseconds) after which the update operation times out. The default value for this parameter is30
seconds. This is an optional parameter. - The
external-host
parameter specifies the hostname sent by the Hot Rod server to clients listed in the topology information. The default value for this parameter is the host address. This is an optional parameter. - The
external-port
parameter specifies the port sent by the Hot Rod server to clients listed in the topology information. The default value for this parameter is the configured port. This is an optional parameter. - The
lazy-retrieval
parameter indicates whether the Hot Rod connector will carry out retrieval operations lazily. The default value for this parameter istrue
. This is an optional parameter.
Chapter 12. The RemoteCache Interface
12.1. About the RemoteCache Interface
12.2. Create a New RemoteCacheManager
RemoteCacheManager
:
Properties props = new Properties(); props.put("infinispan.client.hotrod.server_list", "127.0.0.1:11222"); RemoteCacheManager manager = new RemoteCacheManager(props); RemoteCache defaultCache = manager.getCache();
Note
Hot Rod
with JBoss Data Grid, refer to the Developer Guide's Hot Rod Chapter.
Part III. Rolling Upgrades
Chapter 13. Rolling Upgrades in JBoss Data Grid
13.1. About Rolling Upgrades
13.2. Rolling Upgrades Using Hot Rod (Remote Client-Server Mode)
This procedure assumes you have a cluster already configured and running, and that it is using an older version of JBoss Data Grid. This cluster is referred to below as the "Source Cluster", where as the "Target Cluster" refers to the new cluster to which data will be migrated.
Begin a new cluster (Target Cluster)
Start the Target Cluster with the new version of JBoss Data Grid.Use either different network settings or JGroups cluster name to avoid overlap with the Source Cluster.Configure the Target Cluster with a
RemoteCacheStore
The Target Cluster is configured with aRemoteCacheStore
with the following settings for each cache to be migrated:servers
must point to the Source Cluster.cache name
must coincide with the name of the cache on the Source Cluster.hotrod-wrapping
must be enabled ("true"
).purge
must be disabled ("false"
).passivation
must be disabled ("false"
).
Figure 13.1. Configure the Target Cluster with a RemoteCacheStore
Note
Refer to the$JDG_HOME/server/docs/examples/configs/standalone-hotrod-rolling-upgrade.xml
file for a full example of the Target Cluster configuration for performing Rolling Upgrades.Target Cluster configuration example assumes the Source Cluster is running withstandalone.xml
configuration:<subsystem xmlns="urn:jboss:datagrid:infinispan:6.1" default-cache-container="local"> <cache-container name="local" default-cache="default"> <local-cache name="default" start="EAGER"> <locking isolation="NONE" acquire-timeout="30000" concurrency-level="1000" striping="false"/> <transaction mode="NONE"/> <remote-store cache="default" socket-timeout="60000" tcp-no-delay="true" hotrod-wrapping="true"> <remote-server outbound-socket-binding="remote-store-hotrod-server"/> </remote-store> </local-cache> </cache-container> <cache-container name="security"/> </subsystem>
Configure clients to point to the Target Cluster
Configure clients to point to the Target Cluster instead of the Source Cluster, restarting each client node one by one.Eventually all requests will be handled by the Target Cluster, which will lazily load data from the Source Cluster on demand. The Source Cluster is now theRemoteCacheStore
for the Target Cluster.Figure 13.2. Clients point to the Target Cluster with the Source Cluster as
RemoteCacheStore
for the Target Cluster.Dump the Source Cluster keyset
When all connections are using the Target Cluster, the keyset on the Source Cluster must be dumped. This can be done using either JMX or the CLI:JMX
Invoke therecordKnownGlobalKeyset
operation on theRollingUpgradeManager
MBean on the Source Cluster for every cache that needs to be migrated.CLI
Invoke theupgrade --dumpkeys
command on the Source Cluster for every cache that needs to be migrated, or use the--all
switch to dump all caches in the cluster.
Fetch remaining data from the Source Cluster
The Target Cluster now needs to fetch all remaining data from the Source Cluster. Again, this can be done using either JMX or CLI:JMX
Invoke thesynchronizeData
operation and specify thehotrod
parameter on theRollingUpgradeManager
MBean on the Target Cluster for every cache that needs to be migrated.CLI
Invoke theupgrade --synchronize=hotrod
command on the Target Cluster for every cache that needs to be migrated, or use the--all
switch to synchronize all caches in the cluster.
Disabling the
RemoteCacheStore
Once the Target Cluster has obtained all data from the Source Cluster, theRemoteCacheStore
on the Target Cluster must be disabled. This can be done as follows:JMX
Invoke thedisconnectSource
operation specifying thehotrod
parameter on theRollingUpgradeManager
MBean on the Target Cluster.CLI
Invoke theupgrade --disconnectsource=hotrod
command on the Target Cluster.
- Decommission the Source Cluster.
13.3. RollingUpgradeManager Operations
RollingUpgradeManager
Mbean handles the operations that allow data to be migrated from one version of JBoss Data Grid to another when performing rolling upgrades. The RollingUpgradeManager
operations are:
recordKnownGlobalKeyset
- retrieves the entire keyset from the cluster running on the old version of JBoss Data Grid.synchronizeData
- performs the migration of data from the Source Cluster to the Target Cluster, which is running the new version of JBoss Data Grid.disconnectSource
- disables the Source Cluster, the older version of JBoss Data Grid, once data migration to the Target Cluster is complete.
Part IV. The Infinispan CDI Module
Chapter 14. The Infinispan CDI Module
14.1. About Infinspan CDI
infinispan-cdi
module. The infinispan-cdi
module offers:
- Configuration and injection using the Cache API.
- A bridge between the cache listeners and the CDI event system. (future feature?)
- Partial support for the JCACHE caching annotations.
14.2. Using Infinispan CDI
14.2.1. Infinispan CDI Prerequisites
- Ensure that the most recent version of the infinispan-cdi module is used.
- Ensure that the correct dependency information is set.
14.2.2. Set the CDI Maven Dependency
pom.xml
file in your maven project:
<dependencies> ... <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-cdi</artifactId> <version>${infinispan.version}</version> </dependency> ... </dependencies>
infinispan-cdi
jar file is available at modules/infinispan-cdi
in the ZIP distribution.
14.3. Using the Infinispan CDI Module
14.3.1. Using the Infinispan CDI Module
- To configure and inject Infinispan caches into CDI Beans and Java EE components.
- To configure cache managers.
- To control storage and retrieval using CDI annotations.
14.3.2. Configure and Inject Infinispan Caches
14.3.2.1. Inject an Infinispan Cache
public class MyCDIBean { @Inject Cache<String, String> cache; }
14.3.2.2. Inject a Remote Infinispan Cache
public class MyCDIBean { @Inject RemoteCache<String, String> remoteCache; }
14.3.2.3. Set the Injection's Target Cache
14.3.2.3.1. Setting the Injection's Target Cache
- Create a qualifier annotation.
- Add a producer class.
- Inject the desired class.
14.3.2.3.2. Create a Qualifier Annotation
@javax.inject.Qualifier @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SmallCache {}
@SmallCache
qualifier to specify how to create specific caches.
14.3.2.3.3. Add a Producer Class
@SmallCache
qualifier (created in the previous step) specifies a way to create a cache:
import org.infinispan.configuration.cache.Configuration; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.cdi.ConfigureCache; import javax.enterprise.inject.Proces; public class CacheCreator { @ConfigureCache("smallcache") @SmallCache @Produces public Configuration specialCacheCfg() { return new ConfigurationBuilder() .eviction() .strategy(EvictionStrategy.LRU) .maxEntries(10) .build(); } }
@ConfigureCache
specifies the name of the cache.@SmallCache
is the cache qualifier.
14.3.2.3.4. Inject the Desired Class
@SmallCache
qualifier and the new producer class to inject a specific cache into the CDI bean as follows:
public class MyCDIBean { @Inject @SmallCache Cache<String, String> mySmallCache; }
14.3.3. Configure Cache Managers
14.3.3.1. Configuring Cache Managers with CDI
14.3.3.2. Specify the Default Configuration
public class Config { @Produces public Configuration defaultEmbeddedConfiguration () { return new ConfigurationBuilder() .eviction() .strategy(EvictionStrategy.LRU) .maxEntries(100) .build(); } }
Note
@Default
qualifier if no other qualifiers are provided.
@Produces
annotation is placed in a method that returns a Configuration instance, the method is invoked when a Configuration object is required.
14.3.3.3. Override the Creation of the Embedded Cache Manager
After a producer method is annotated, this method will be called when creating an EmbeddedCacheManager
, as follows:
public class Config { @Produces @ApplicationScoped public EmbeddedCacheManager defaultEmbeddedCacheManager Configuration cfg = new ConfigurationBuilder() .eviction() .strategy(EvictionStrategy.LRU) .maxEntries(150) .build(); return new DefaultCacheManager(cfg); } }
@ApplicationScoped
annotation specifies that the method is only called ocne.
The following configuration can be used to create an EmbeddedCacheManager
that can create clustered caches.
public class Config { @Produces @ApplicationScoped public EmbeddedCacheManager defaultClusteredCacheManager() { GlobalConfiguration g = new GlobalConfigurationBuilder() .clusteredDefault() .transport() .clusterName("InfinispanCluster") .build(); Configuration cfg = new ConfigurationBuilder() .eviction() .strategy(EvictionStrategy.LRU) .maxEntries(150) .build(); return new DefaultCacheManager(g, cfg); } }
The method annotated with @Produces
in the non clustered method generates Configuration
objects. The two methods in the clustered cache example annonated with @Produces
generate EmbeddedCacheManager
objects.
EmbeddedCacheManager
and injects it into the code at runtime.
... @Inject EmbeddedCacheManager cacheManager; ...
14.3.3.4. Configure a Remote Cache Manager
RemoteCacheManager
is configured in a manner similar to EmbeddedCacheManagers
, as follows:
public class Config { @Produces @ApplicationScoped public RemoteCacheManager defaultRemoteCacheManager() { return new RemoteCacheManager(ADDRESS, PORT); } }
14.3.3.5. Configure Multiple Cache Managers with a Single Class
public class Config { @Produces @ApplicationScoped public EmbeddedCacheManager defaultEmbeddedCacheManager() { Configuration cfg = new ConfigurationBuilder() .eviction() .strategy(EvictionStrategy.LRU) .maxEntries(150) .build(); return new DefaultCacheManager(cfg); } @Produces @ApplicationScoped @DefaultClustered public EmbeddedCacheManager defaultClusteredCacheManager() { GlobalConfiguration g = new GlobalConfigurationBuilder() .clusteredDefault() .transport() .clusterName("InfinispanCluster") .build(); Configuration cfg = new ConfigurationBuilder() .eviction() .strategy(EvictionStrategy.LRU) .maxEntries(150) .build(); return new DefaultCacheManager(g, cfg); } @Produces @ApplicationScoped @DefaultRemote public RemoteCacheManager defaultRemoteCacheManager() { return new RemoteCacheManager(ADDRESS, PORT); } @Produces @ApplicationScoped @RemoteCacheInDifferentDataCentre public RemoteCacheManager newRemoteCacheManager() { return new RemoteCacheManager(ADDRESS_FAR_AWAY, PORT); } }
14.3.4. Storage and Retrieval Using CDI Annotations
14.3.4.1. Configure Cache Annotations
javax.cache
package.
14.3.4.2. Enable Cache Annotations
beans.xml
file. Adding the following code adds interceptors such as the CacheResultInterceptor
, CachePutInterceptor
, CacheRemoveEntryInterceptor
and the CacheRemoveAllInterceptor
:
<beans xmlns="http://java.sun.som/xml/ns/javaee" xmlns:xsi="http://www/w3/org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd" > <interceptors> <class> org.infinispan.cdi.interceptor.CacheResultInterceptor </class> <class> org.infinispan.cdi.interceptor.CachePutInterceptor </class> <class> org.infinispan.cdi.interceptor.CacheRemoveEntryInterceptor </class> <class> org.infinispan.cdi.interceptor.CacheRemoveAllInterceptor </class> </interceptors> </beans>
14.3.4.3. Catch the Result of a Method Invocation
14.3.4.3.1. Catching the Result of a Method Invocation
public String toCelsiusFormatted(float fahrenheit) { return NumberFormat.getInstance() .format((fahrenheit * 5 / 9) - 32) + " degrees Celsius"; }
toCelsiusFormatted
method again and stores the result in the cache.
float f = getTemperatureInFahrenheit(); Cache<Float, String> fahrenheitToCelsiusCache = getCache(); String celsius = fahrenheitToCelsiusCache = get(f); if (celsius == null) { celsius = toCelsiusFormatted(f); fahrenheitToCelsiusCache.put(f, celsius); }
@CacheResult
annotation instead, as follows:
@javax.cache.interceptor.CacheResult public String toCelsiusFormatted(float fahrenheit) { return NumberFormat.getInstance() .format((fahrenheit * 5 / 9) - 32) + " degrees Celsius"; }
toCelsiusFormatted()
method call.
Note
14.3.4.3.2. Specify the Cache Used
cacheName
) to the @CacheResult
annotation to specify the cache to check for results of the method call:
@CacheResult(cacheName = "mySpecialCache") public void doSomething(String parameter) { ... }
14.3.4.3.3. Cache Keys for Cached Results
@CacheResult
annotation creates a key for the results fetched from a cache. The key consists of a combination of all parameters in the relevant method.
@CacheKeyParam
annotation as follows:
@CacheResult public void doSomething (@CacheKeyParam String p1, @CacheKeyParam String p2, String dontCare) { ... }
p1
and p2
are used to create the cache key. The value of dontCare
is not used when determining the cache key.
14.3.4.3.4. Generate a Custom Key
import javax.cache.annotation.CacheKey; import javax.cache.annotation.CacheKeyGenerator; import javax.cache.annotation.CacheKeyInvocationContext; import java.lang.annotation.Annotation; public class MyCacheKeyGenerator implements CacheKeyGenerator { @Override public CacheKey generateCacheKey(CacheKeyInvocationContext<? extends Annotation> ctx) { return new MyCacheKey( ctx.getAllParameters()[0].getValue() ); } }
cacheKeyGenerator
to the @CacheResult
annotation as follows:
@CacheResult(cacheKeyGenerator = MyCacheKeyGenerator.class) public void doSomething(String p1, String p2) { ... }
p1
contains the custom key.
14.3.4.3.5. CacheKey Implementation Code
import javax.cache.annotation.CacheKey; public class MyCacheKey implements CacheKey { private Object p; public CustomCacheKey(Object p) { this.p = p; } @Override public boolean equals(Object o) { ... } @Override public int hashCode() { ... } }
equals()
and hashCode()
methods must be correctly implemented for the CacheKey
to work as expected.
14.3.5. Cache Operations
14.3.5.1. Update a Cache Entry
@CachePut
annotation is invoked, a parameter (normally passed to the method annotated with @CacheValue
) is stored in the cache.
@CachePut
annotated method:
@CachePut (cacheName = "personCache") public void updatePerson (@CacheKeyParam long personId, @CacheValue Person newPerson) { ... }
cacheName
and cacheKeyGenerator
in the @CachePut
method. Additionally, some parameters in the invoked method may be annotated with @CacheKeyParam
to control key generation.
14.3.5.2. Remove an Entry from the Cache
@CacheRemoveEntry
annotated method and is used to remove an entry from the cache:
@CacheRemoveEntry (cacheName = "cacheOfPeople") public void changePersonName (@CacheKeyParam long personId, string newName { ... }
cacheName
and cacheKeyGenerator
attributes.
14.3.5.3. Clear the Cache
@CacheRemoveAll
method to clear all entries from the cache. An example of a method annotated with @CacheRemoveAll
is as follows
@CacheRemoveAll (cacheName = "statisticsCache") public void resetStatistics() { ... }
cacheName
attribute.
Part V. Querying in JBoss Data Grid
Chapter 15. The Query Module
15.1. About the Query Module
- Retrieve all red cars (an exact metadata match).
- Search for all books about a specific topic (full text search and relevance scoring).
Warning
15.2. Apache Lucene and Infinispan Query
- Apache Lucene is a document indexing tool and search engine. JBoss Data Grid uses Apache Lucene 3.6.
- Infinispan Query is a toolkit based on Hibernate Search that reduces Java objects into a format similar to a document, which is able to be indexed and queried by Apache Lucene.
Important
15.3. About Lucene Directory
- Ram - stores the index in a local map to the node. This index cannot be shared.
- File system - stores the index in a locally mounted file system. This could be a network shared file system, however sharing in this manner is not recommended.
- JBoss Data Grid - stores the indexes in a different set of dedicated JBoss Data Grid caches. These caches can be configured as replicated or distributed in order to share the index between nodes.
Note
Important
15.4. Infinispan Query
15.4.1. Infinispan Query in JBoss Data Grid
@Indexed
objects is the key used to store the value. How the key is indexed can still be customized by using a combination of @Transformable
, @ProvidedID
, custom types and custom FieldBridge
implementations.
@DocumentID
identifier does not apply to JBoss Data Grid values.
Important
15.4.2. Infinispan Query Dependencies for JBoss Data Grid
- JBoss Data Grid
- A JVM
- Maven
<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-query</artifactId> <version>${infinispan.version}</version> </dependency>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-search-infinispan</artifactId> <version>4.2.0.Final-redhat-1</version> </dependency>
<groupId>org.hibernate</groupId> <artifactId>hibernate-search-analyzers</artifactId> <version>4.2.0.Final-redhat-1</version>
.jar
files from the JBoss Data Grid distribution.
Important
15.4.3. Configuring Infinispan Query for JBoss Data Grid
- Enable the Infinispan Query default configuration and cluster-replicated index for JBoss Data Grid's Query Module, using either
"default"
or specifying the name of an index. The default configuration does not enable any form of persistence for the index.hibernate.search.[default|<indexname>].directory_provider infinispan
It is possible to use multiple named indexes, so configuration can be applied to all or overridden in a per-index base by using the index name.In order to enable a persistent index, either a JBoss Data Grid configuration file must be provided, or point to JNDI as described in Step 2. - Infinispan Query requires a
CacheManager
, which can be obtained in two ways.- Look up and reuse an existing
CacheManager
programmatically using Java Naming and Directory Interface (JNDI). To use this method, the following property must be set in addition to the property specified in Step 1:hibernate.search.[default|<indexname>].infinispan.cachemanager_jndiname = [jndiname]
- Start and manage a new
CacheManager
. To use a newCacheManager
apply the following:hibernate.search.[default|<indexname>].infinispan.configuration_resourcename = [infinispan configuration filename]
If both parameters are defined, the JNDI will be prioritized.If neither of these parameters are defined, Infinispan Query will use the default JBoss Data Grid configuration included inhibernate-search-infinispan.jar
, which does not store the index in a persistent cache store.
Important
15.5. Configuring the Query Module
15.5.1. Configure the Query Module
Search
capabilities using the SearchManager
, which exposes methods to perform queries.
Important
15.5.2. Configure Indexing using XML
<indexing ... />
element to the cache configuration in the Infinispan core configuration file, and optionally pass additional properties in the embedded Infinispan Query engine. For Example:
<?xml version="1.0" encoding="UTF-8"?> <infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:infinispan:config:5.2 http://www.infinispan.org/schemas/infinispan-config-5.2.xsd" xmlns="urn:infinispan:config:5.2"> <default> <indexing enabled="true" indexLocalOnly="true"> <properties> <property name="default.directory_provider" value="ram" /> </properties> </indexing> </default> </infinispan>
hibernate.search
is also a valid optional prefix for configuration property
keys.
Important
15.5.3. Configure Indexing Programmatically
Author
, which is stored in the grid and made searchable via two properties, without annotating the class.
SearchMapping mapping = new SearchMapping(); mapping.entity(Author.class).indexed().providedId() .property("name", ElementType.METHOD).field() .property("surname", ElementType.METHOD).field(); Properties properties = new Properties(); properties.put(org.hibernate.search.Environment.MODEL_MAPPING, mapping); properties.put("hibernate.search.[other options]", "[...]"); Configuration infinispanConfiguration = new ConfigurationBuilder() .indexing() .enable() .indexLocalOnly(true) .withProperties(properties) .build(); DefaultCacheManager cacheManager = new DefaultCacheManager(infinispanConfiguration); Cache<Long, Author> cache = cacheManager.getCache(); SearchManager sm = Search.getSearchManager(cache); Author author = new Author(1, "FirstName", "Surname"); cache.put(author.getId(), author); QueryBuilder qb = sm.buildQueryBuilderForClass(Author.class).get(); Query q = qb.keyword().onField("name").matching("FirstName").createQuery(); CacheQuery cq = sm.getQuery(q, Author.class); Assert.assertEquals(cq.getResultSize(), 1);
Important
15.5.4. Rebuilding the Index
- The definition of what is indexed in the types has changed.
- A parameter affecting how the index is defined, such as the
Analyser
changes. - The index is destroyed or corrupted, possibly due to a system administration error.
MassIndexer
and start it as follows:
SearchManager searchManager = Search.getSearchManager(cache); searchManager.getMassIndexer().start();
Note
MassIndexer
is implemented using MapReduce
, and is therefore only functional in distributed cache mode.
15.6. Annotating Objects and Storing Indexes
15.6.1. Annotating Objects for Infinispan Query
@Entity
@Indexed
@ProvidedId
@Field
.
@Entity @ProvidedId @Indexed public class Person implements Serializable { @Field(store = Store.YES) private String name; @Field(store = Store.YES) private String description; @Field(store = Store.YES) private int age; ... }
Important
15.6.2. Registering a Transformer via Annotations
org.infinispan.query.Transformer
.
org.infinispan.query.Transformer
:
@Transformable(transformer = CustomTransformer.class) public class CustomKey { ... } public class CustomTransformer implements Transformer { @Override public Object fromString(String s) { ... return new CustomKey(...); } @Override public String toString(Object customType) { CustomKey ck = (CustomKey) customType; return ... } }
A.equals( transformer.fromString( transformer.toString( A ) )
Important
15.7. Cache Modes and Storing Indexes
15.7.1. Storing Lucene Indexes
- simple, in-memory storage.
- file system storage.
<namedCache name="indexesInMemory"> <indexing enabled="true"> <properties> <property name= "default.directory_provider" value="ram"/> </properties> </indexing> </namedCache>
<namedCache name="indexesOnDisk"> <indexing enabled="true"> <properties> <property name= "default.directory_provider" value="filesystem"/> </properties> </indexing> </namedCache>
hibernate.search
is also a valid optional prefix for configuration property
keys.
Important
15.7.2. The Infinispan Directory
infinispan-directory
module.
infinispan-directory
allows Lucene to store indexes within the distributed data grid. This allows the indexes to be distributed , stored in-memory, and optionally written to disk using the cache store for durability.
<namedCache name="indexesInInfinispan"> <indexing enabled="true"> <properties> <property name= "default.directory_provider" value="infinispan"/> <property name= "default.exclusive_index_use" value="false"/> </properties> </indexing> </namedCache>
property
keys.
exclusive_index_use
must be set to "false"
and in most cases an alternative backend must be setup.
Important
15.7.3. Cache Modes and Managing Indexes
- Each node can maintain an individual copy of the global index.
- The index can be shared across all nodes.
Important
15.7.4. Storing Global Indexes Locally
- maintain its own index.
- use Lucene's in-memory or filesystem-based index directory.
Note
indexLocalOnly
attribute of the indexing
element must be set to "false"
in order for changes originating from elsewhere in the cluster are indexed.
<namedCache name="localCopyOfGlobalIndexes"> <clustering mode="replicated"/> <indexing enabled="true" indexLocalOnly="false"> <property name= "default.directory_provider" value="ram"/> </indexing> </namedCache>
property
keys.
Important
15.7.5. Sharing the Global Index
- The JBoss Data Grid directory provider. Either replicated or distributed cache modes can be used when sharing the indexes in this manner.
- A local filesystem-based index, which is periodically synchronized with other nodes using simple file copy. This requires a shared network drive configured externally.
indexLocalOnly
attribute of the indexing
element must be set to "true"
. For example:
<namedCache name="globalSharedIndexes"> <clustering mode="distributed"/> <indexing enabled="true" indexLocalOnly="true"> <property name= "default.directory_provider" value="infinispan"/> <property name= "default.exclusive_index_use" value="false"/> </indexing> </namedCache>
property
keys.
Important
15.8. Querying Example
15.8.1. The Query Module Example
@Entity @ProvidedId @Indexed public class Person implements Serializable { @Field(store = Store.YES) private String name; @Field private String description; @Field(store = Store.YES) private int age; ... }
SearchManager
and QueryBuilder
instance:
SearchManager manager= Search.getSearchManager(cache); QueryBuilder builder= sm.buildQueryBuilderForClass(Person.class) .get(); Query luceneQuery = builder.keyword() .onField("name") .matching("FirstName") .createQuery();
SearchManager
and QueryBuilder
are used to construct a Lucene query. The Lucene query is then passed to the SearchManager
to obtain a CacheQuery
instance:
CacheQuery query = manager.getQuery(luceneQuery); for (Object result: query) { System.out.println("Found " + result); }
CacheQuery
instance contains the results of the query, and can be used to produce a list or it can be used for repeat queries.
Important
Part VI. MapReduce and Distributed Tasks
Chapter 16. MapReduce
16.1. About MapReduce
- The user initiates a task on a cache instance, which runs on a cluster node (the master node).
- The master node receives the task input, divides the task, and sends tasks for map phase execution on the grid.
- Each node executes a
Mapper
function on its input, and returns intermediate results back to the master node.- If the
distributedReducePhase
parameter is set to"true"
, the map results are inserted in an intermediary cache, rather than being returned to the master node. - If a
Combiner
has been specified withtask.combinedWith(Reducer)
, theCombiner
is called on theMapper
results and the combiner's results are retured to the master node or inserted in the intermediary cache.
- The master node collects all intermediate results from the map phase and merges all intermediate values associated with the same intermediate key.
- If the
distributedReducePhase
parameter is set to"true"
, the merging of the intermediate values is done on each node, as theMapper
orCombiner
results are inserted in the intermediary cache.The master node only receives the intermediate keys.
- The master node sends intermediate key/value pairs for reduction on the grid.
- If the
distributedReducePhase
parameter is set to"false"
, the reduction phase is executed only on the master node.
- The final results of the reduction phase are returned.
- If the
distributedReducePhase
parameter is set to"true"
, the master node running the task receives all results from the reduction phase and returns the final result to the MapReduce task initiator. - If a
Collator
has been specified withtask.execute(Collator)
, theCollator
is executed on the reduction phase results, and theCollator
result is returned to the task initiator.
16.2. The MapReduce API
16.2.1. The MapReduce API
Mapper
Reducer
Collator
MapReduceTask
Mapper
class implementation is a component of MapReduceTask
, which is invoked once per input cache entry key/value pair. Map
is a the process of applying a given function to each element of a list, returning a list of results
Mapper
on a given cache entry key/value input pair. It then transforms this cache entry key/value pair into an intermediate key/value pair, which is emitted into the provided Collator
instance.
public interface Mapper<KIn, VIn, KOut, VOut> extends Serializable { /** * Invoked once for each input cache entry KIn,VOut pair. */ void map(KIn key, VIn value, Collector<KOut, VOut> collector);
Reducer
. JBoss Data Grid's distributed execution environment creates one instance of Reducer
per execution node.
public interface Reducer<KOut, VOut> extends Serializable { /** * Combines/reduces all intermediate values for a particular intermediate key to a single value. * <p> * */ VOut reduce(KOut reducedKey, Iterator<VOut> iter); }
Reducer
interface is used for Combiners
. A Combiner
is similar to a Reducer
, except that it must be able to work on partial results. The Combiner
is executed on the results of the Mapper
, on the same node, without considering the other nodes that might have generated values for the same intermediate key.
Combiners
only see a part of the intermediate values, they cannot be used in all scenarios, however when used they can reduce network traffic significantly.
Collator
coordinates results from Reducers
that have been executed on JBoss Data Grid, and assembles a final result that is delivered to the initiator of the MapReduceTask
. The Collator
is applied to the final map key/value result of MapReduceTask
.
public interface Reducer<KOut, VOut> extends Serializable { /** * Combines/reduces all intermediate values for a particular intermediate key to a single value. * <p> * */ VOut reduce(KOut reducedKey, Iterator<VOut> iter); }
16.2.2. MapReduceTask
MapReduceTask
is a distributed task, which unifies the Mapper
, Combiner
, Reducer
, and Collator
components into a cohesive computation, which can be parallelized and executed across a large-scale cluster.
new MapReduceTask(cache).mappedWith(new MyMapper()).combinedWith(new MyCombiner().reducedWith(new MyReducer()).execute(new MyCollator()).
MapReduceTask
requires a cache containing data that will be used as input for the task. The JBoss Data Grid execution environment will instantiate and migrate instances of provided Mappers
and Reducers
seamlessly across the nodes.
onKeys
method as an input key filter.
MapReduceTask
constructor parameters that determine how the intermediate values are processed:
distributedReducePhase
- When set to"false"
, the default setting, the reducers are only executed on the master node. If set to"true"
, the reducers are executed on every node in the cluster.useIntermediateSharedCache
- Only important ifdistributedReducePhase
is set to"true"
. If"true"
, which is the default setting, this task will share intermediate value cache with other executing MapReduceTasks on the grid. If set to"false"
, this task will use its own dedicated cache for intermediate values.
16.2.3. Mapper and CDI
Mapper
is invoked with appropriate input key/value pairs on an executing node, however JBoss Data Grid also provides a CDI injection for an input cache. The CDI injection can be used where additional data from the input cache is required in order to complete map transformation.
Mapper
is executed on a JBoss Data Grid executing node, the JBoss Data Grid CDI module provides an appropriate cache reference, which is injected to the executing Mapper
. To use the JBoss Data Grid CDI module with Mapper
:
- Declare a cache field in
Mapper
. - Annotate the cache field
Mapper
with@org.infinispan.cdi.Input
. - Annotate with mandatory
@Inject annotation
.
public class WordCountCacheInjectedMapper implements Mapper<String, String, String, Integer> { @Inject @Input private Cache<String, String> cache; @Override public void map(String key, String value, Collector<String, Integer> collector) { //use injected cache if needed StringTokenizer tokens = new StringTokenizer(value); while (tokens.hasMoreElements()) { for(String token : value.split("\\w")) { collector.emit(token, 1); } } }
16.3. MapReduceTask Distributed Execution
16.3.1. MapReduceTask Distributed Execution
- Mapping phase.
- Outgoing Key and Outgoing Value Migration.
- Reduce phase.
Procedure 16.1. Mapping Phase
- The input keys are grouped according to their owner nodes.
- On each node the
Mapper
function processes all key/value pairs local to that node. - The results of the mapping process are collected using a
Collector
. - If a
Reducer
is specified, it is applied to all intermediate values collected for each outgoing key (KOut
,VOut
).
Procedure 16.2. Outgoing Key and Outgoing Value Migration Phase
- Intermediate keys exposed by the
Mapper
are grouped by the intermediate outgoing key (KOut
values. This grouping preserves the keys, as the mapping phase, when applied to other nodes in the cluster, may generate identical intermediate keys. - Once the Reduce phase has been invoked, (as described in Step 4 of the Mapping Phase above), an underlying hashing mechanism, a temporary distributed cache, and a DeltaAware cache insertion mechanism are used to:
- hash the intermediate key
KOut
using its owner node. - migrate the hashed
KOut
key and its correspondingVOut
value to the same owner node.
- The list of
KOut
keys are returned to the master node.VOut
values are not returned as they are not required by the master node.
Procedure 16.3. Reduce Phase
KOut
keys are grouped according to owner node.- The reduce operation applies to each node and its input (grouped
KOut
keys) as follows:- The reduce operation locates the temporary distributed cache created during the migration phase on the target node.
- For each
KOut
key, a list ofVOut
values is taken from the temporary cache. - The
KOut
andVOut
values are wrapped in anIterator
and the reduce operation is applied to the result.
- The reduce operation generates a map where each key is
KOut
and each value isVOut
.Each node has its own map. - The maps from each node in the cluster are combined into a single map (
M
). - The MapReduce task returns map (
M
) to the node that initiated theMapReduce
task.
16.4. Map Reduce Example
- Key is a String.
- Each sentence is a String.
public class WordCountExample { /** * In this example replace c1 and c2 with * real Cache references * * @param args */ public static void main(String[] args) { Cache c1 = null; Cache c2 = null; c1.put("1", "Hello world here I am"); c2.put("2", "Infinispan rules the world"); c1.put("3", "JUDCon is in Boston"); c2.put("4", "JBoss World is in Boston as well"); c1.put("12","JBoss Application Server"); c2.put("15", "Hello world"); c1.put("14", "Infinispan community"); c2.put("15", "Hello world"); c1.put("111", "Infinispan open source"); c2.put("112", "Boston is close to Toronto"); c1.put("113", "Toronto is a capital of Ontario"); c2.put("114", "JUDCon is cool"); c1.put("211", "JBoss World is awesome"); c2.put("212", "JBoss rules"); c1.put("213", "JBoss division of RedHat "); c2.put("214", "RedHat community"); MapReduceTask<String, String, String, Integer> t = new MapReduceTask<String, String, String, Integer>(c1); t.mappedWith(new WordCountMapper()) .reducedWith(new WordCountReducer()); Map<String, Integer> wordCountMap = t.execute(); } static class WordCountMapper implements Mapper<String,String,String,Integer> { /** The serialVersionUID */ private static final long serialVersionUID = -5943370243108735560L; @Override public void map(String key, String value, Collector<String, Integer> c) { StringTokenizer tokens = new StringTokenizer(value); for(String token : value.split("\\w")) { collector.emit(token, 1); } } } static class WordCountReducer implements Reducer<String, Integer> { /** The serialVersionUID */ private static final long serialVersionUID = 1901016598354633256L; @Override public Integer reduce(String key, Iterator<Integer> iter) { int sum = 0; while (iter.hasNext()) { Integer i = (Integer) iter.next(); sum += i; } return sum; } } }
Collator
is defined, which will transform the result of MapReduceTask Map<KOut,VOut> into a String that is returned to a task invoker. The Collator
is a transformation function applied to a final result of MapReduceTask.
MapReduceTask<String, String, String, Integer> t = new MapReduceTask<String, String, String, Integer>(cache); t.mappedWith(new WordCountMapper()).reducedWith(new WordCountReducer()); String mostFrequentWord = t.execute( new Collator<String,Integer,String>() { @Override public String collate(Map<String, Integer> reducedResults) { String mostFrequent = ""; int maxCount = 0; for (Entry<String, Integer> e : reducedResults.entrySet()) { Integer count = e.getValue(); if(count > maxCount) { maxCount = count; mostFrequent = e.getKey(); } } return mostFrequent; } }); System.out.println("The most frequent word is " + mostFrequentWord);
Chapter 17. Distributed Execution
17.1. About Distributed Execution
ExecutorService
interface. Tasks submitted for execution are executed on an entire cluster of JBoss Data Grid nodes, rather than being executed in a local JVM.
- Each
DistributedExecutorService
is bound to a single cache. Tasks submitted have access to key/value pairs from that particular cache if the task submitted is an instance ofDistributedCallable
. - Every
Callable
,Runnable
, and/orDistributedCallable
submitted must be eitherSerializable
orExternalizable
, in order to prevent task migration to other nodes each time one of these tasks is performed. The value returned from aCallable
must also beSerializable
orExternalizable
.
17.2. DistributedCallable API
DistributedCallable
interface is a subtype of the existing Callable
from java.util.concurrent.package, and can be executed in a remote JVM and receive input from JBoss Data Grid. The DistributedCallable
interface is used to facilitate tasks that require access to JBoss Data Grid cache data.
DistributedCallable
API to execute a task, the task's main algorithm remains unchanged, however the input source is changed.
Callable
interface to describe task units must extend DistributedCallable
and use keys from JBoss Data Grid execution environment as input for the task. For example:
public interface DistributedCallable<K, V, T> extends Callable<T> { /** * Invoked by execution environment after DistributedCallable * has been migrated for execution to a specific Infinispan node. * * @param cache * cache whose keys are used as input data for this * DistributedCallable task * @param inputKeys * keys used as input for this DistributedCallable task */ public void setEnvironment(Cache<K, V> cache, Set<K> inputKeys); }
17.3. Callable and CDI
DistributedCallable
cannot be implemented or is not appropriate, and a reference to input cache used in DistributedExecutorService
is still required, there is an option to inject the input cache by CDI mechanism.
Callable
task arrives at a JBoss Data Grid executing node, JBoss Data Grid's CDI mechanism provides an appropriate cache reference, and injects it to the executing Callable
.
Callable
:
- Declare a
Cache
field inCallable>
and annotated withorg.infinispan.cdi.Input
- Include the mandatory
@Inject
annotation.
public class CallableWithInjectedCache implements Callable<Integer>, Serializable { @Inject @Input private Cache<String, String> cache; @Override public Integer call() throws Exception { //use injected cache reference return 1; } }
17.4. Distributed Task Failover
- Failover due to a node failure where a task is executing.
- Failover due to a task failure; for example, if a
Callable
task throws an exception.
Runnable
, Callable
, and DistributedCallable
tasks fail without invoking any failover mechanism.
Distributed
task on another random node if one is available.
DistributedExecutorService des = new DefaultExecutorService(cache); DistributedTaskBuilder<Boolean> taskBuilder = des.createDistributedTaskBuilder(new SomeCallable()); taskBuilder.failoverPolicy(DefaultExecutorService.RANDOM_NODE_FAILOVER); DistributedTask<Boolean> distributedTask = taskBuilder.build(); Future<Boolean> future = des.submit(distributedTask); Boolean r = future.get();
DistributedTaskFailoverPolicy
interface can also be implemented to provide failover management. For example:
/** * DistributedTaskFailoverPolicy allows pluggable fail over target selection for a failed remotely * executed distributed task. * */ public interface DistributedTaskFailoverPolicy { /** * As parts of distributively executed task can fail due to the task itself throwing an exception * or it can be an Infinispan system caused failure (e.g node failed or left cluster during task * execution etc). * * @param failoverContext * the FailoverContext of the failed execution * @return result the Address of the Infinispan node selected for fail over execution */ Address failover(FailoverContext context); /** * Maximum number of fail over attempts permitted by this DistributedTaskFailoverPolicy * * @return max number of fail over attempts */ int maxFailoverAttempts(); }
17.5. Distributed Task Execution Policy
DistributedTaskExecutionPolicy
allows tasks to specify a custom execution policy across the JBoss Data Grid cluster, by scoping execution of tasks to a subset of nodes.
DistributedTaskExecutionPolicy
can be used to manage task execution in the following cases:
- where a task is to be exclusively executed on a local network site instead of a backup remote network center.
- where you want to use only a dedicated subset of a certain JBoss Data Grid rack nodes for specific task execution.
DistributedExecutorService des = new DefaultExecutorService(cache); DistributedTaskBuilder<Boolean> taskBuilder = des.createDistributedTaskBuilder(new SomeCallable()); taskBuilder.executionPolicy(DistributedTaskExecutionPolicy.SAME_RACK); DistributedTask<Boolean> distributedTask = taskBuilder.build(); Future<Boolean> future = des.submit(distributedTask); Boolean r = future.get();
17.6. Distributed Execution Example
- As shown below, the area of a square is:Area of a Square (S) = 4r 2
- The following is an equation for the area of a circle:Area of a Circle (C) = π x r 2
- Isolate r 2 from the first equation:r 2 = S/4
- Inject this value of r^2 into the second equation to find a value for Pi:C = Sπ/4
- Isolating π in the equation results in:C = Sπ/44C = Sπ4C/S = π
public class PiAppx { public static void main (String [] arg){ List<Cache> caches = ...; Cache cache = ...; int numPoints = 10000000; int numServers = caches.size(); int numberPerWorker = numPoints / numServers; DistributedExecutorService des = new DefaultExecutorService(cache); long start = System.currentTimeMillis(); CircleTest ct = new CircleTest(numberPerWorker); List<Future<Integer>> results = des.submitEverywhere(ct); int countCircle = 0; for (Future<Integer> f : results) { countCircle += f.get(); } double appxPi = 4.0 * countCircle / numPoints; System.out.println("Distributed PI appx is " + appxPi + " completed in " + (System.currentTimeMillis() - start) + " ms"); } private static class CircleTest implements Callable<Integer>, Serializable { /** The serialVersionUID */ private static final long serialVersionUID = 3496135215525904755L; private final int loopCount; public CircleTest(int loopCount) { this.loopCount = loopCount; } @Override public Integer call() throws Exception { int insideCircleCount = 0; for (int i = 0; i < loopCount; i++) { double x = Math.random(); double y = Math.random(); if (insideCircle(x, y)) insideCircleCount++; } return insideCircleCount; } private boolean insideCircle(double x, double y) { return (Math.pow(x - 0.5, 2) + Math.pow(y - 0.5, 2)) <= Math.pow(0.5, 2); } } }
Part VII. Marshalling in JBoss Data Grid
Chapter 18. Marshalling
18.1. About Marshalling
18.2. Marshalling Benefits
- To transform data for relay to other JBoss Data Grid nodes within the cluster.
- To transform data to be stored in underlying cache stores.
18.3. About Marshalling Framework
java.io.ObjectOutput
and java.io.ObjectInput
implementations compared to the standard java.io.ObjectOutputStream
and java.io.ObjectInputStream
.
18.4. Support for Non-Serializable Objects
Serializable
or Externalizable
support into your classes, you could (as an example) use XStream to convert the non-serializable objects into a String that can be stored in JBoss Data Grid.
Note
18.5. Hot Rod and Marshalling
- All data stored by clients on the JBoss Data Grid server are provided either as a byte array, or in a primitive format that is marshalling compatible for JBoss Data Grid.On the server side of JBoss Data Grid, marshalling occurs where the data stored in primitive format are converted into byte array and replicated around the cluster or stored to a cache store. No marshalling configuration is required on the server side of JBoss Data Grid.
- At the client level, marshalling needs to have a
Marshaller
configuration element specified in the RemoteCacheManager configuration in order to serialize and deserialize POJOs.Due to Hot Rod's binary nature, it relies on marshalling to transform POJOs, specifically keys or values, into byte array.
18.6. Configuring the Marshaller using the RemoteCacheManager
infinispan.client.hotrod.marshaller
allows you to specify a custom Marshaller implementation to serialize and deserialize user objects.
marshaller
configuration element in the RemoteCacheManager, the value of which should be the name of the class implementing the Marshaller interface. The default value for this property is org.infinispan.marshall.jboss.GenericJBossMarshaller
.
Properties props = new Properties(); props.put("infinispan.client.hotrod.marshaller", "org.infinispan.marshall.jboss.GenericJBossMarshaller" RemoteCacheManager remoteCacheManager = new RemoteCacheManager(props);
Note
18.7. Troubleshooting
18.7.1. Marshalling Troubleshooting
java.io.NotSerializableException: java.lang.Object at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:857) at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:407) at org.infinispan.marshall.exts.ReplicableCommandExternalizer.writeObject(ReplicableCommandExternalizer.java:54) at org.infinispan.marshall.jboss.ConstantObjectTable$ExternalizerAdapter.writeObject(ConstantObjectTable.java:267) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:143) at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:407) at org.infinispan.marshall.jboss.JBossMarshaller.objectToObjectStream(JBossMarshaller.java:167) at org.infinispan.marshall.VersionAwareMarshaller.objectToBuffer(VersionAwareMarshaller.java:92) at org.infinispan.marshall.VersionAwareMarshaller.objectToByteBuffer(VersionAwareMarshaller.java:170) at org.infinispan.marshall.VersionAwareMarshallerTest.testNestedNonSerializable(VersionAwareMarshallerTest.java:415) Caused by: an exception which occurred: in object java.lang.Object@b40ec4 in object org.infinispan.commands.write.PutKeyValueCommand@df661da7 ... Removed 22 stack frames
java.lang.Object
instance within an org.infinispan.commands.write.PutKeyValueCommand
instance cannot be serialized because java.lang.Object@b40ec4
is not serializable.
DEBUG
or TRACE
logging levels are enabled, marshalling exceptions will contain toString()
representations of objects in the stack trace. The following is an example that depicts such a scenario:
java.io.NotSerializableException: java.lang.Object ... Caused by: an exception which occurred: in object java.lang.Object@b40ec4 -> toString = java.lang.Object@b40ec4 in object org.infinispan.commands.write.PutKeyValueCommand@df661da7 -> toString = PutKeyValueCommand{key=k, value=java.lang.Object@b40ec4, putIfAbsent=false, lifespanMillis=0, maxIdleTimeMillis=0}
java.io.IOException: Injected failue! at org.infinispan.marshall.VersionAwareMarshallerTest$1.readExternal(VersionAwareMarshallerTest.java:426) at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1172) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:273) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:210) at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85) at org.infinispan.marshall.jboss.JBossMarshaller.objectFromObjectStream(JBossMarshaller.java:210) at org.infinispan.marshall.VersionAwareMarshaller.objectFromByteBuffer(VersionAwareMarshaller.java:104) at org.infinispan.marshall.VersionAwareMarshaller.objectFromByteBuffer(VersionAwareMarshaller.java:177) at org.infinispan.marshall.VersionAwareMarshallerTest.testErrorUnmarshalling(VersionAwareMarshallerTest.java:431) Caused by: an exception which occurred: in object of type org.infinispan.marshall.VersionAwareMarshallerTest$1
IOException
was thrown when an instance of the inner class org.infinispan.marshall.VersionAwareMarshallerTest$1
is unmarshalled.
DEBUG
or TRACE
logging levels are enabled, the class type's classloader information is provided. An example of this classloader information is as follows:
java.io.IOException: Injected failue! ... Caused by: an exception which occurred: in object of type org.infinispan.marshall.VersionAwareMarshallerTest$1 -> classloader hierarchy: -> type classloader = sun.misc.Launcher$AppClassLoader@198dfaf ->...file:/opt/eclipse/configuration/org.eclipse.osgi/bundles/285/1/.cp/eclipse-testng.jar ->...file:/opt/eclipse/configuration/org.eclipse.osgi/bundles/285/1/.cp/lib/testng-jdk15.jar ->...file:/home/galder/jboss/infinispan/code/trunk/core/target/test-classes/ ->...file:/home/galder/jboss/infinispan/code/trunk/core/target/classes/ ->...file:/home/galder/.m2/repository/org/testng/testng/5.9/testng-5.9-jdk15.jar ->...file:/home/galder/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar ->...file:/home/galder/.m2/repository/org/easymock/easymockclassextension/2.4/easymockclassextension-2.4.jar ->...file:/home/galder/.m2/repository/org/easymock/easymock/2.4/easymock-2.4.jar ->...file:/home/galder/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar ->...file:/home/galder/.m2/repository/javax/xml/bind/jaxb-api/2.1/jaxb-api-2.1.jar ->...file:/home/galder/.m2/repository/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar ->...file:/home/galder/.m2/repository/javax/activation/activation/1.1/activation-1.1.jar ->...file:/home/galder/.m2/repository/jgroups/jgroups/2.8.0.CR1/jgroups-2.8.0.CR1.jar ->...file:/home/galder/.m2/repository/org/jboss/javaee/jboss-transaction-api/1.0.1.GA/jboss-transaction-api-1.0.1.GA.jar ->...file:/home/galder/.m2/repository/org/jboss/marshalling/river/1.2.0.CR4-SNAPSHOT/river-1.2.0.CR4-SNAPSHOT.jar ->...file:/home/galder/.m2/repository/org/jboss/marshalling/marshalling-api/1.2.0.CR4-SNAPSHOT/marshalling-api-1.2.0.CR4-SNAPSHOT.jar ->...file:/home/galder/.m2/repository/org/jboss/jboss-common-core/2.2.14.GA/jboss-common-core-2.2.14.GA.jar ->...file:/home/galder/.m2/repository/org/jboss/logging/jboss-logging-spi/2.0.5.GA/jboss-logging-spi-2.0.5.GA.jar ->...file:/home/galder/.m2/repository/log4j/log4j/1.2.14/log4j-1.2.14.jar ->...file:/home/galder/.m2/repository/com/thoughtworks/xstream/xstream/1.2/xstream-1.2.jar ->...file:/home/galder/.m2/repository/xpp3/xpp3_min/1.1.3.4.O/xpp3_min-1.1.3.4.O.jar ->...file:/home/galder/.m2/repository/com/sun/xml/bind/jaxb-impl/2.1.3/jaxb-impl-2.1.3.jar -> parent classloader = sun.misc.Launcher$ExtClassLoader@1858610 ->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/localedata.jar ->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/sunpkcs11.jar ->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/sunjce_provider.jar ->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/dnsns.jar ... Removed 22 stack frames
18.7.2. State Receiver EOFExceptions
2010-12-09 10:26:21,533 20267 ERROR [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (STREAMING_STATE_TRANSFER-sender-1,Infinispan-Cluster,NodeJ-2368:) Caught while responding to state transfer request org.infinispan.statetransfer.StateTransferException: java.util.concurrent.TimeoutException: Could not obtain exclusive processing lock at org.infinispan.statetransfer.StateTransferManagerImpl.generateState(StateTransferManagerImpl.java:175) at org.infinispan.remoting.InboundInvocationHandlerImpl.generateState(InboundInvocationHandlerImpl.java:119) at org.infinispan.remoting.transport.jgroups.JGroupsTransport.getState(JGroupsTransport.java:586) at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.handleUpEvent(MessageDispatcher.java:691) at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.up(MessageDispatcher.java:772) at org.jgroups.JChannel.up(JChannel.java:1465) at org.jgroups.stack.ProtocolStack.up(ProtocolStack.java:954) at org.jgroups.protocols.pbcast.FLUSH.up(FLUSH.java:478) at org.jgroups.protocols.pbcast.STREAMING_STATE_TRANSFER$StateProviderHandler.process(STREAMING_STATE_TRANSFER.java:653) at org.jgroups.protocols.pbcast.STREAMING_STATE_TRANSFER$StateProviderThreadSpawner$1.run(STREAMING_STATE_TRANSFER.java:582) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:680) Caused by: java.util.concurrent.TimeoutException: Could not obtain exclusive processing lock at org.infinispan.remoting.transport.jgroups.JGroupsDistSync.acquireProcessingLock(JGroupsDistSync.java:71) at org.infinispan.statetransfer.StateTransferManagerImpl.generateTransactionLog(StateTransferManagerImpl.java:202) at org.infinispan.statetransfer.StateTransferManagerImpl.generateState(StateTransferManagerImpl.java:165) ... 12 more
EOFException
, displayed as follows, when failing to read the transaction log that was not written by the sender:
2010-12-09 10:26:21,535 20269 TRACE [org.infinispan.marshall.VersionAwareMarshaller] (Incoming-2,Infinispan-Cluster,NodeI-38030:) Log exception reported java.io.EOFException: Read past end of file at org.jboss.marshalling.AbstractUnmarshaller.eofOnRead(AbstractUnmarshaller.java:184) at org.jboss.marshalling.AbstractUnmarshaller.readUnsignedByteDirect(AbstractUnmarshaller.java:319) at org.jboss.marshalling.AbstractUnmarshaller.readUnsignedByte(AbstractUnmarshaller.java:280) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:207) at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85) at org.infinispan.marshall.jboss.GenericJBossMarshaller.objectFromObjectStream(GenericJBossMarshaller.java:175) at org.infinispan.marshall.VersionAwareMarshaller.objectFromObjectStream(VersionAwareMarshaller.java:184) at org.infinispan.statetransfer.StateTransferManagerImpl.processCommitLog(StateTransferManagerImpl.java:228) at org.infinispan.statetransfer.StateTransferManagerImpl.applyTransactionLog(StateTransferManagerImpl.java:250) at org.infinispan.statetransfer.StateTransferManagerImpl.applyState(StateTransferManagerImpl.java:320) at org.infinispan.remoting.InboundInvocationHandlerImpl.applyState(InboundInvocationHandlerImpl.java:102) at org.infinispan.remoting.transport.jgroups.JGroupsTransport.setState(JGroupsTransport.java:603) ...
Part VIII. Transactions
Chapter 19. Transactions
19.1. About Java Transaction API Transactions
- First, it retrieves the transactions currently associated with the thread.
- If not already done, it registers
XAResource
with the transaction manager to receive notifications when a transaction is committed or rolled back.
Important
ExceptionTimeout
where JBoss Data Grid is Unable to acquire lock after {time} on key {key} for requester {thread}
, enable transactions. This occurs because non-transactional caches acquire locks on each node they write on. Using transactions prevents deadlocks because caches acquire locks on a single node. This problem is resolved in JBoss Data Grid 6.1.
19.2. Transactions Spanning Multiple Cache Instances
19.3. Transaction/Batching and Invalidation Messages
Chapter 20. The Transaction Manager
20.1. About JTA Transaction Manager Lookup Classes
TransactionManagerLookup
interface. When initialized, the cache creates an instance of the specified class and invokes its getTransactionManager()
method to locate and return a reference to the Transaction Manager.
Table 20.1. Transaction Manager Lookup Classes
Class Name | Details |
---|---|
org.infinispan.transaction.lookup.DummyTransactionManagerLookup | Used primarily for testing environments. This testing transaction manager is not for use in a production environment and is severely limited in terms of functionality, specifically for concurrent transactions and recovery. |
org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup | The default transaction manager when JBoss Data Grid runs in a standalone environment. It is a fully functional JBoss Transactions based transaction manager that overcomes the functionality limits of the DummyTransactionManager . |
org.infinispan.transaction.lookup.GenericTransactionManagerLookup | Used to locate transaction managers in most Java EE application servers. If no transaction manager is located, it defaults to DummyTransactionManager . |
org.infinispan.transaction.lookup.JBossTransactionManagerLookup | Locates a transaction manager within a JBoss Application Server instance. |
20.2. Obtain the Transaction Manager From the Cache
Procedure 20.1. Obtain the Transaction Manager from the Cache
- Define a
transactionManagerLookupClass
by adding the following property to yourBasicCacheContainer
's configuration location properties:Configuration config = new ConfigurationBuilder() ... .transaction().transactionManagerLookup(new GenericTransactionManagerLookup())
- Call
TransactionManagerLookup.getTransactionManager
as follows:TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
20.3. Transaction Manager and XAResources
XAResource
implementation to run XAResource.recover
on it.
20.4. Obtain a XAResource Reference
XAResource
, use the following API:
XAResource xar = cache.getAdvancedCache().getXAResource();
20.5. Default Distributed Transaction Behavior
XAResource
. In situations where JBoss Data Grid does not need to be a participant in a transaction, it can be notified about the lifecycle status (for example, prepare, complete, etc.) of the transaction via a synchronization.
20.6. Transaction Synchronization
20.6.1. About Transaction Synchronizations
Chapter 21. Deadlock Detection
21.1. About Deadlock Detection
disabled
by default.
21.2. Enable Deadlock Detection
disabled
by default but can be enabled and configured for each cache using the namedCache
configuration element by adding the following:
<deadlockDetection enabled="true" spinDuration="1000"/>
Note
Part IX. Listeners and Notifications
Chapter 22. Listeners and Notifications
22.1. About the Listener API
22.2. Listener Example
@Listener public class PrintWhenAdded { @CacheEntryCreated public void print(CacheEntryCreatedEvent event) { System.out.println("New entry " + event.getKey() + " created in the cache"); } }
22.3. Cache Entry Modified Listener Configuration
Cache.get()
when isPre
(an Event method) is false
. For more information about isPre()
, refer to the JBoss Data Grid API Documentation's listing for the org.infinispan.notifications.cachelistener.event
package.
CacheEntryModifiedEvent.getValue()
to retrieve the new value of the modified entry.
22.4. Notifications
22.4.1. About Listener Notifications
@Listener
. A Listenable is an interface that denotes that the implementation can have listeners attached to it. Each listener is registered using methods defined in the Listenable.
22.4.2. About Cache-level Notifications
22.4.3. Cache Manager-level Notifications
- Nodes joining or leaving a cluster;
- The starting and stopping of caches
22.4.4. About Synchronous and Asynchronous Notifications
@Listener (sync = false)public class MyAsyncListener { .... }
<asyncListenerExecutor/>
element in the configuration file to tune the thread pool that is used to dispatch asynchronous notifications.
22.5. Notifying Futures
22.5.1. About NotifyingFutures
Futures
, but a sub-interface known as a NotifyingFuture
. Unlike a JDK Future
, a listener can be attached to a NotifyingFuture
to notify the user about a completed future.
Note
NotifyingFutures
are only available in Library mode.
22.5.2. NotifyingFutures Example
NotifyingFutures
in JBoss Data Grid:
FutureListener futureListener = new FutureListener() { public void futureDone(Future future) { try { future.get(); } catch (Exception e) { // Future did not complete successfully System.out.println("Help!"); } } }; cache.putAsync("key", "value").attachListener(futureListener);
Part X. The Infinispan CLI
Chapter 23. The Infinispan CLI
23.1. About the Infinispan CLI
infinispan-cli-server-$VERSION.jar
) includes an interpreter for commands and must be included in the application.
Important
23.2. Start the CLI (Server)
standalone
and cluster
files. For Linux, use the standlaone.sh
or clustered.sh
script and for Windows, use the standalone.bat
or clustered.bat
file.
23.3. Start the CLI (Client)
ispn-cli
file at bin/
. For Linux, run bin/ispn-cli.sh
and for Windows, run bin/ispn-cli.bat
.
23.4. CLI Client Switches for the Command Line
Table 23.1. CLI Client Command Line Switches
Short Option | Long Option | Description |
---|---|---|
-c | --connect=${URL} | Connects to a running JBoss Data Grid instance. For example, for JMX over RMI use jmx://[username[:password]]@host:port[/container[/cache]] and for JMX over JBoss Remoting use remoting://[username[:password]]@host:port[/container[/cache]] |
-f | --file=${FILE} | Read the input from the specified file rather than using interactive mode. If the value is set to - then the stdin is used as the input. |
-h | --help | Displays the help information. |
-v | --version | Displays the CLI version information. |
23.5. Connect to the Application
[disconnected//]> connect jmx://localhost:12000 [jmx://localhost:12000/MyCacheManager/>
Note
12000
depends on the value the JVM is started with. For example, starting the JVM with the -Dcom.sun.management.jmxremote.port=12000
command line parameter uses this port, but otherwise a random port is chosen. When the remoting protocol (remoting://localhost:9999
) is used, the JBoss Data Grid server administration port is used (the default is port 9999
).
CacheManager
.
cache
command to select a cache before performing cache operations. The CLI supports tab completion, therefore using the cache
and pressing the tab button displays a list of active caches:
[[jmx://localhost:12000/MyCacheManager/> cache ___defaultcache namedCache [jmx://localhost:12000/MyCacheManager/]> cache ___defaultcache [jmx://localhost:12000/MyCacheManager/___defaultcache]>
23.6. CLI Commands
23.6.1. The abort Command
abort
command aborts a running batch initiated using the start
command. Batching must be enabled for the specified cache. The following is a usage example:
[jmx://localhost:12000/MyCacheManager/namedCache]> start [jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> abort [jmx://localhost:12000/MyCacheManager/namedCache]> get a null
23.6.2. The begin Command
begin
command starts a transaction. This command requires transactions enabled for the cache it targets. An example of this command's usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> begin [jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> put b b [jmx://localhost:12000/MyCacheManager/namedCache]> commit
23.6.3. The cache Command
cache
command specifies the default cache used for all subsequent operations. If invoked without any parameters, it shows the currently selected cache. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> cache ___defaultcache [jmx://localhost:12000/MyCacheManager/___defaultcache]> cache ___defaultcache [jmx://localhost:12000/MyCacheManager/___defaultcache]>
23.6.4. The clear Command
clear
command clears all content from the cache. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> clear [jmx://localhost:12000/MyCacheManager/namedCache]> get a null
23.6.5. The commit Command
commit
command commits changes to an ongoing transaction. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> begin [jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> put b b [jmx://localhost:12000/MyCacheManager/namedCache]> commit
23.6.6. The container Command
container
command selects the default cache container (cache manager). When invoked without any parameters, it lists all available containers. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> container MyCacheManager OtherCacheManager [jmx://localhost:12000/MyCacheManager/namedCache]> container OtherCacheManager [jmx://localhost:12000/OtherCacheManager/]>
23.6.7. The create Command
create
command creates a new cache based on the configuration of an existing cache definition. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> create newCache like namedCache [jmx://localhost:12000/MyCacheManager/namedCache]> cache newCache [jmx://localhost:12000/MyCacheManager/newCache]>
23.6.8. The disconnect Command
disconnect
command disconnects the currently active connection, which allows the CLI to connect to another instance. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> disconnect [disconnected//]
23.6.9. The encoding Command
encoding
command sets a default codec to use when reading and writing entries to and from a cache. If invoked with no arguments, the currently selected codec is displayed. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> encoding none [jmx://localhost:12000/MyCacheManager/namedCache]> encoding --list memcached hotrod none rest [jmx://localhost:12000/MyCacheManager/namedCache]> encoding hotrod
23.6.10. The end Command
end
command ends a running batch initiated using the start
command. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> start [jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> end [jmx://localhost:12000/MyCacheManager/namedCache]> get a a
23.6.11. The evict Command
evict
command evicts an an entry associated with a specific key from the cache. An example of it usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> evict a
23.6.12. The get Command
get
command shows the value associated with a specified key. For primitive types and Strings, the get
command prints the default representation. For other objects, a JSON representation of the object is printed. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> get a a
23.6.13. The info Command
info
command displaysthe configuration of a selected cache or container. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> info GlobalConfiguration{asyncListenerExecutor=ExecutorFactoryConfiguration{factory=org.infinispan.executors.DefaultExecutorFactory@98add58}, asyncTransportExecutor=ExecutorFactoryConfiguration{factory=org.infinispan.executors.DefaultExecutorFactory@7bc9c14c}, evictionScheduledExecutor=ScheduledExecutorFactoryConfiguration{factory=org.infinispan.executors.DefaultScheduledExecutorFactory@7ab1a411}, replicationQueueScheduledExecutor=ScheduledExecutorFactoryConfiguration{factory=org.infinispan.executors.DefaultScheduledExecutorFactory@248a9705}, globalJmxStatistics=GlobalJmxStatisticsConfiguration{allowDuplicateDomains=true, enabled=true, jmxDomain='jboss.infinispan', mBeanServerLookup=org.jboss.as.clustering.infinispan.MBeanServerProvider@6c0dc01, cacheManagerName='local', properties={}}, transport=TransportConfiguration{clusterName='ISPN', machineId='null', rackId='null', siteId='null', strictPeerToPeer=false, distributedSyncTimeout=240000, transport=null, nodeName='null', properties={}}, serialization=SerializationConfiguration{advancedExternalizers={1100=org.infinispan.server.core.CacheValue$Externalizer@5fabc91d, 1101=org.infinispan.server.memcached.MemcachedValue$Externalizer@720bffd, 1104=org.infinispan.server.hotrod.ServerAddress$Externalizer@771c7eb2}, marshaller=org.infinispan.marshall.VersionAwareMarshaller@6fc21535, version=52, classResolver=org.jboss.marshalling.ModularClassResolver@2efe83e5}, shutdown=ShutdownConfiguration{hookBehavior=DONT_REGISTER}, modules={}, site=SiteConfiguration{localSite='null'}}
23.6.14. The locate Command
locate
command displays the physical location of a specified entry in a distributed cluster. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> locate a [host/node1,host/node2]
23.6.15. The put Command
put
command inserts an entry into the cache. If a mapping exists for a key, the put
command overwrites the old value. The CLI allows control over the type of data used to store the key and value. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> put b 100 [jmx://localhost:12000/MyCacheManager/namedCache]> put c 4139l [jmx://localhost:12000/MyCacheManager/namedCache]> put d true [jmx://localhost:12000/MyCacheManager/namedCache]> put e { "package.MyClass": {"i": 5, "x": null, "b": true } }
put
can specify a life span and maximum idle time value as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> put a a expires 10s [jmx://localhost:12000/MyCacheManager/namedCache]> put a a expires 10m maxidle 1m
23.6.16. The replace Command
replace
command replaces an existing entry in the cache with a specified new value. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> replace a b [jmx://localhost:12000/MyCacheManager/namedCache]> get a b [jmx://localhost:12000/MyCacheManager/namedCache]> replace a b c [jmx://localhost:12000/MyCacheManager/namedCache]> get a c [jmx://localhost:12000/MyCacheManager/namedCache]> replace a b d [jmx://localhost:12000/MyCacheManager/namedCache]> get a c
23.6.17. The rollback Command
rollback
command rolls back any changes made by an ongoing transaction. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> begin [jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> put b b [jmx://localhost:12000/MyCacheManager/namedCache]> rollback
23.6.18. The site Command
site
command performs administration tasks related to cross-datacentre replication. This command also retrieves information about the status of a site and toggles the status of a site. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> site --status NYC online [jmx://localhost:12000/MyCacheManager/namedCache]> site --offline NYC ok [jmx://localhost:12000/MyCacheManager/namedCache]> site --status NYC offline [jmx://localhost:12000/MyCacheManager/namedCache]> site --online NYC
23.6.19. The start Command
start
command initiates a batch of operations. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> start [jmx://localhost:12000/MyCacheManager/namedCache]> put a a [jmx://localhost:12000/MyCacheManager/namedCache]> put b b [jmx://localhost:12000/MyCacheManager/namedCache]> end
23.6.20. The stats Command
stats
command displays statistics for the cache. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> stats Statistics: { averageWriteTime: 143 evictions: 10 misses: 5 hitRatio: 1.0 readWriteRatio: 10.0 removeMisses: 0 timeSinceReset: 2123 statisticsEnabled: true stores: 100 elapsedTime: 93 averageReadTime: 14 removeHits: 0 numberOfEntries: 100 hits: 1000 } LockManager: { concurrencyLevel: 1000 numberOfLocksAvailable: 0 numberOfLocksHeld: 0 }
23.6.21. The upgrade Command
upgrade
command implements the rolling upgrade procedure. For details about rolling upgrades, refer to Section 13.1, “About Rolling Upgrades”
upgrade
command's use is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> upgrade --synchronize=hotrod --all [jmx://localhost:12000/MyCacheManager/namedCache]> upgrade --disconnectsource=hotrod --all
23.6.22. The version Command
version
command displays version information for the CLI client and server. An example of its usage is as follows:
[jmx://localhost:12000/MyCacheManager/namedCache]> version Client Version 5.2.1.Final Server Version 5.2.1.Final
Appendix A. Revision History
Revision History | |||
---|---|---|---|
Revision 6.1.0-23.400 | 2013-10-31 | Rüdiger Landmann | |
| |||
Revision 6.1.0-23 | Wed Oct 09 2013 | Misha Husnain Ali | |
|