1

I am trying to setup a replicated Infinispan embedded cache.

When using the demo code for programatically setup the cache, everything works, as expected (https://github.com/infinispan/infinispan-simple-tutorials/tree/main/infinispan-embedded/cache-replicated)

Now, I want to configure it to use a defined list of initial hosts.

So, I changed slightly the code to be :

public class TestGenerate
{
    public static void main(String[] args) throws InterruptedException
    {
        // Setup up a clustered cache manager
        GlobalConfigurationBuilder global = GlobalConfigurationBuilder.defaultClusteredBuilder();
        GlobalConfiguration globalConfiguration = global.transport().defaultTransport().addProperty("configurationFile", "jgroups.xml").build();
        // Initialize the cache manager
        DefaultCacheManager cacheManager = new DefaultCacheManager(globalConfiguration);
        // Create a replicated synchronous configuration
        ConfigurationBuilder builder = new ConfigurationBuilder();
        builder.clustering().cacheMode(CacheMode.REPL_SYNC);
        Configuration cacheConfig = builder.build();
        // Create a cache
        Cache<String, String> cache = cacheManager.administration()
                .withFlags(CacheContainerAdmin.AdminFlag.VOLATILE)
                .getOrCreateCache("cache", cacheConfig);

        // Store the current node address in some random keys
        for(int i=0; i < 10; i++) {
            cache.put(UUID.randomUUID().toString(), cacheManager.getNodeAddress());
        }
        // Display the current cache contents for the whole cluster
        System.out.println("--------------- whole cluster");
        cache.entrySet().forEach(entry -> System.out.printf("%s = %s\n", entry.getKey(), entry.getValue()));
        // Display the current cache contents for this node
        System.out.println("--------------- this node");
        cache.getAdvancedCache().withFlags(Flag.SKIP_REMOTE_LOOKUP)
                .entrySet().forEach(entry -> System.out.printf("%s = %s\n", entry.getKey(), entry.getValue()));


        Thread.currentThread().join();
    }
}

My JGroups configuration file is very minimal :

<config xmlns="urn:org:jgroups"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd">

   <TCP bind_port="7950" />
   <TCPPING initial_hosts="192.168.42.100[7950],192.165.10.52[7950]"/>
</config>

The problem is that the cache doesn't start :

sept. 21, 2021 1:49:01 PM org.infinispan.factories.GlobalComponentRegistry preStart
INFO: ISPN000128: Infinispan version: Infinispan 'Taedonggang' 12.1.7.Final
sept. 21, 2021 1:49:01 PM org.infinispan.marshall.core.impl.DelegatingUserMarshaller start
INFO: ISPN000556: Starting user marshaller 'org.infinispan.commons.marshall.ImmutableProtoStreamMarshaller'
sept. 21, 2021 1:49:01 PM org.infinispan.remoting.transport.jgroups.JGroupsTransport start
INFO: ISPN000078: Starting JGroups channel ISPN
sept. 21, 2021 1:49:02 PM org.infinispan.remoting.transport.jgroups.JGroupsTransport startJGroupsChannelIfNeeded
INFO: ISPN000079: Channel ISPN local address is null, physical addresses are [192.168.42.100:7950]
sept. 21, 2021 1:49:02 PM org.infinispan.remoting.transport.jgroups.JGroupsTransport stop
INFO: ISPN000080: Disconnecting JGroups channel ISPN
Exception in thread "main" org.infinispan.manager.EmbeddedCacheManagerStartupException: org.infinispan.commons.CacheConfigurationException: Error starting component org.infinispan.topology.ClusterTopologyManager
    at org.infinispan.manager.DefaultCacheManager.internalStart(DefaultCacheManager.java:755)
    at org.infinispan.manager.DefaultCacheManager.start(DefaultCacheManager.java:718)
    at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:296)
    at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:219)
    at TestGenerate.main(TestGenerate.java:43)
Caused by: org.infinispan.commons.CacheConfigurationException: Error starting component org.infinispan.topology.ClusterTopologyManager
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.startWrapper(BasicComponentRegistryImpl.java:572)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.access$700(BasicComponentRegistryImpl.java:30)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl$ComponentWrapper.running(BasicComponentRegistryImpl.java:787)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.startDependencies(BasicComponentRegistryImpl.java:622)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.doStartWrapper(BasicComponentRegistryImpl.java:586)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.startWrapper(BasicComponentRegistryImpl.java:564)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.access$700(BasicComponentRegistryImpl.java:30)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl$ComponentWrapper.running(BasicComponentRegistryImpl.java:787)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.startDependencies(BasicComponentRegistryImpl.java:622)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.doStartWrapper(BasicComponentRegistryImpl.java:586)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.startWrapper(BasicComponentRegistryImpl.java:564)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.access$700(BasicComponentRegistryImpl.java:30)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl$ComponentWrapper.running(BasicComponentRegistryImpl.java:787)
    at org.infinispan.factories.AbstractComponentRegistry.internalStart(AbstractComponentRegistry.java:354)
    at org.infinispan.factories.AbstractComponentRegistry.start(AbstractComponentRegistry.java:250)
    at org.infinispan.manager.DefaultCacheManager.internalStart(DefaultCacheManager.java:750)
    ... 4 more
Caused by: java.lang.NullPointerException: Cannot invoke "Object.equals(Object)" because the return value of "org.infinispan.remoting.transport.Transport.getAddress()" is null
    at org.infinispan.topology.TopologyManagementHelper.executeOnCoordinator(TopologyManagementHelper.java:83)
    at org.infinispan.topology.ClusterTopologyManagerImpl.fetchRebalancingStatusFromCoordinator(ClusterTopologyManagerImpl.java:162)
    at org.infinispan.topology.ClusterTopologyManagerImpl.start(ClusterTopologyManagerImpl.java:153)
    at org.infinispan.topology.CorePackageImpl$3.start(CorePackageImpl.java:74)
    at org.infinispan.topology.CorePackageImpl$3.start(CorePackageImpl.java:58)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.invokeStart(BasicComponentRegistryImpl.java:604)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.doStartWrapper(BasicComponentRegistryImpl.java:595)
    at org.infinispan.factories.impl.BasicComponentRegistryImpl.startWrapper(BasicComponentRegistryImpl.java:564)
    ... 19 more

If I use the demo code, the getAddress() method will indeed return something (my hostname and a number), but with the modification, the address is indeed null.

Do I have to setup manually the address ? How ?

EDIT : after some search, when I use the demo code, the receiveClusterView(View) method from JGroupsTransport class is called before the executeOnCoordinator(...) method in TopologyManagementHelper class, this set the address.

When using my xml configuration file, the receiveClusterView(view) is not called before the executeOnCoordinator() method, and as such the getAddress() fails.

Environment :

infinispan-core v12.1.7.Final

jgroups v4.2.12.Final (as dependcy from maven)

adopt-openjdk v15.0.2

macOS Big Sur

iXô
  • 1,133
  • 1
  • 16
  • 39

2 Answers2

2

Your configuration is too minimalist :)

Infinispan requires JGroups Group Membership and Reliable Transmission to work properly.

Also, failure detection may be useful to have if you don't want to lose data on nodes crashing.

pruivo
  • 1,214
  • 7
  • 7
  • Thanks a lot for you reply. Is there a possibility to find a sample configuration file ? – iXô Sep 22 '21 at 09:59
  • 1
    Infinispan ships some default JGroups configurations. Check them here: https://github.com/infinispan/infinispan/tree/main/core/src/main/resources/default-configs. In addition, https://infinispan.org/docs/stable/titles/embedding/embedding.html#using-jgroups-default-stacks_cluster-transport shows how to use them or customize them if required. – pruivo Sep 22 '21 at 10:05
  • Thanks a lot, I did try one of this file, it failed about some xml fields that were not valid, maybe I wasn't using the right version at this time. – iXô Sep 22 '21 at 10:24
  • Last question, can we mix UDP and TCP mode in the same config file ? – iXô Sep 22 '21 at 10:27
  • 1
    no, only one transport per configuration. – pruivo Sep 22 '21 at 10:35
1

To avoid having to come up with a full valid JGroups stack, I'd use inheritance on top of one of the provided stacks

<infinispan>
    <jgroups>
        <!-- Creates a custom JGroups stack named "my-stack". -->
        <!-- Inherits properties from the default TCP stack. -->
        <stack name="my-stack" extends="tcp">
            <!-- Uses TCPPING as the discovery mechanism instead of MPING -->
            <TCPPING initial_hosts="192.168.42.100[7950],192.165.10.52[7950]"
               stack.combine="REPLACE"
               stack.position="MPING" />
        </stack>
     </jgroups>
     <cache-container name="default" statistics="true">
         <!-- Uses "my-stack" for cluster transport. -->
         <transport cluster="${infinispan.cluster.name}"
             stack="my-stack"
             node-name="${infinispan.node.name:}"/>
     </cache-container>
</infinispan>

Refer to https://infinispan.org/docs/stable/titles/embedding/embedding.html#jgroups-default_cluster-transport for more details

Tristan Tarrant
  • 1,299
  • 6
  • 6
  • Very interesting, do you know how I could perform the same without using a configuration file ? I setup my embedded infinispan programmatically. – iXô Sep 22 '21 at 10:32
  • No, that functionality is part of the Infinispan configuration parser, not of JGroups'. You will have to supply a "complete" configuration based on the default ones: https://github.com/infinispan/infinispan/tree/main/core/src/main/resources/default-configs – Tristan Tarrant Sep 22 '21 at 12:39