Skip to content

Commit

Permalink
Infinispan cross-site replication failover configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
karesti committed Jun 28, 2023
1 parent e59f6d4 commit 3c7a3a1
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 1 deletion.
51 changes: 50 additions & 1 deletion docs/src/main/asciidoc/infinispan-client-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,56 @@ quarkus.infinispan-client.client-intelligence=BASIC <2>
Use Infinispan Dev Services to run a server and connect without configuration.
====

=== Configuring backup clusters in Cross-Site Replication
In High Availability production deployments, it is common to have multiple Infinispan Clusters that are
distributed across various Data Centers worldwide. Infinispan offers the capability to connect these clusters and
configure backups between them. This enables seamless switching between clusters through both automated and manual
methods using a single connection. To achieve this, it is necessary to configure the client to direct to the backup
clusters.

[source,properties]
----
quarkus.infinispan-client.hosts=host1:11222,host2:3122 <1>
quarkus.infinispan-client.username=admin
quarkus.infinispan-client.password=password
quarkus.infinispan-client.backup-cluster.nyc-site.hosts=nyc1:11222,nyc2:21222,nyc3:31222 <2>
quarkus.infinispan-client.backup-cluster.nyc-site.client-intelligence=BASIC <3>
quarkus.infinispan-client.backup-cluster.lon-site.hosts=lon1:11222,lon2:21222,lon3:31222 <4>
----
<1> Sets Infinispan Server address list, separated with commas. This is the default cluster.
<2> Configures a backup site 'nyc-site' with the provided address list
<3> Configures a backup site 'nyc-site' with the provided client intelligence
<4> Configures an additional backup site 'lon-site' with the provided address list

Based on the provided configuration, in the event of the default cluster becoming unavailable, the client will
seamlessly transition to one of the accessible backup clusters.
Additionally, there is also the option to manually switch the client to an alternate cluster:

[source,java]
----
@ApplicationScoped
public class InfinispanExample {
@Inject
RemoteCacheManager cacheManager;
public void doSomething() {
cacheManager.switchToCluster("nyc-site"); //<1>
cacheManager.switchToCluster("lon-site"); //<2>
cacheManager.switchToDefaultCluster(); //<3>
}
}
----
<1> The client connects to the 'nyc-site'.
<2> The client connects to the 'lon-site'.
<3> The client connects to the default site.

[NOTE]
====
Cross-site replication is a powerful feature offered by Infinispan that facilitates data backup between clusters
situated in geographically diverse data centers, even spanning across various cloud providers.
Learn more in the link:https://infinispan.org/docs/stable/titles/xsite/xsite.html[Infinispan documentation].
====

=== Default and named connections
This extension lets you configure a _default_ Infinispan client connections and _named_ ones.
Named connections are essential to connect to multiple Infinispan clusters.
Expand Down Expand Up @@ -163,7 +213,6 @@ the traces from the Infinispan Client to the Server.
This behavior can be disabled via the property `quarkus.infinispan-client.tracing.propagation.enabled`

=== Creating caches from the client

When a cache is accessed from the client, if the cache does not exist in the Infinispan Server and you want
to create it on first access, use one of the following properties:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ public void infinispanConnectionConfiguration() {
assertThat(configuration.security().ssl().provider()).isEqualTo("SSL_prov");
assertThat(configuration.security().ssl().protocol()).isEqualTo("SSL_protocol");
assertThat(configuration.security().ssl().ciphers()).containsExactlyInAnyOrder("SSL_cipher1", "SSL_cipher2");
assertThat(configuration.clusters().size()).isEqualTo(1);
assertThat(configuration.clusters().get(0).getClusterName()).isEqualTo("bsite");
assertThat(configuration.clusters().get(0).getCluster().get(0).host()).isEqualTo("bsite1");
assertThat(configuration.clusters().get(0).getCluster().get(0).port()).isEqualTo(32111);
assertThat(configuration.clusters().get(0).getClientIntelligence()).isEqualTo(ClientIntelligence.BASIC);

assertThat(configuration.remoteCaches().get("cache1").configuration()).isEqualTo("<replicated-cache/>");
assertThat(configuration.remoteCaches().get("cache1").nearCacheBloomFilter()).isTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ quarkus.infinispan-client.trust-store-type=JCEKS
quarkus.infinispan-client.ssl-provider=SSL_prov
quarkus.infinispan-client.ssl-protocol=SSL_protocol
quarkus.infinispan-client.ssl-ciphers=SSL_cipher1,SSL_cipher2
quarkus.infinispan-client.backup-cluster.bsite.hosts=bsite1:32111
quarkus.infinispan-client.backup-cluster.bsite.client-intelligence=BASIC

# cache 1 config
quarkus.infinispan-client.cache.cache1.configuration=<replicated-cache/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.RemoteCounterManagerFactory;
import org.infinispan.client.hotrod.configuration.ClientIntelligence;
import org.infinispan.client.hotrod.configuration.ClusterConfigurationBuilder;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.client.hotrod.impl.ConfigurationProperties;
import org.infinispan.client.hotrod.logging.Log;
Expand Down Expand Up @@ -289,6 +291,17 @@ private ConfigurationBuilder builderFromProperties(String infinispanClientName,
}
}

for (Map.Entry<String, InfinispanClientRuntimeConfig.BackupClusterConfig> backupCluster : infinispanClientRuntimeConfig.backupCluster
.entrySet()) {
InfinispanClientRuntimeConfig.BackupClusterConfig backupClusterConfig = backupCluster.getValue();
ClusterConfigurationBuilder clusterConfigurationBuilder = builder.addCluster(backupCluster.getKey());
clusterConfigurationBuilder.addClusterNodes(backupClusterConfig.hosts);
if (backupClusterConfig.clientIntelligence.isPresent()) {
clusterConfigurationBuilder.clusterClientIntelligence(
ClientIntelligence.valueOf(backupClusterConfig.clientIntelligence.get()));
}
}

return builder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@ public class InfinispanClientRuntimeConfig {
@ConfigItem
public Map<String, InfinispanClientRuntimeConfig.RemoteCacheConfig> cache = new HashMap<>();

/**
* // @formatter:off
* Configures cross site replication from the client with the provided configuration.
* This allows automatic failover when a site is down, as well as switching manual with methods like:
* <code>
* cacheManager.switchToDefaultCluster();
* cacheManager.switchToCluster('clusterName')
* </code>
* // @formatter:on
*/
@ConfigItem
public Map<String, InfinispanClientRuntimeConfig.BackupClusterConfig> backupCluster = new HashMap<>();

@ConfigGroup
public static class RemoteCacheConfig {

Expand Down Expand Up @@ -233,6 +246,33 @@ public static class RemoteCacheConfig {
public Optional<Boolean> nearCacheUseBloomFilter;
}

@ConfigGroup
public static class BackupClusterConfig {
// @formatter:off
/**
* Sets the host name/port to connect to. Each one is separated by a semicolon (eg. hostA:11222;hostB:11222).
*/
// @formatter:on
@ConfigItem
public String hosts;

// @formatter:off
/**
* Sets client intelligence used by authentication
* Available values:
* * `BASIC` - Means that the client doesn't handle server topology changes and therefore will only use the list
* of servers supplied at configuration time.
* * `TOPOLOGY_AWARE` - Use this provider if you don't want the client to present any certificates to the
* remote TLS host.
* * `HASH_DISTRIBUTION_AWARE` - Like `TOPOLOGY_AWARE` but with the additional advantage that each request
* involving keys will be routed to the server who is the primary owner which improves performance
* greatly. This is the default.
*/
// @formatter:on
@ConfigItem(defaultValue = "HASH_DISTRIBUTION_AWARE")
Optional<String> clientIntelligence;
}

@Override
public String toString() {
return "InfinispanClientRuntimeConfig{" +
Expand Down

0 comments on commit 3c7a3a1

Please sign in to comment.