From cafa1a86ebfe96a6513bbe8291c25aa62f4a0b6d Mon Sep 17 00:00:00 2001 From: Ryan Emerson Date: Mon, 5 Jan 2026 08:53:59 +0000 Subject: [PATCH] Disable state transfer for session caches when persistent sessions are enabled Closes #44518 Signed-off-by: Ryan Emerson Signed-off-by: Alexander Schwartz Co-authored-by: Alexander Schwartz --- .../upgrading/topics/changes/changes-26_5_0.adoc | 9 ++++++++- .../getting-started-scaling-and-tuning.adoc | 3 --- .../spi/infinispan/impl/embedded/CacheConfigurator.java | 4 ++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc b/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc index 53134230521..a28189482ed 100644 --- a/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc +++ b/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc @@ -195,7 +195,14 @@ See the link:{upgradingguide_link}[{upgradingguide_name}] for details on how to For each expired user session there is a new user event `USER_SESSION_DELETED` fired. As part of this change, the process now deletes rows from the table in small batches, instead of issuing a delete statements that affects the whole table. This should allow for better response times when there are a lot of sessions in the table. -=== Organization custom attribute named 'id' behavior change +=== Embedded cache state-transfer disabled for session caches with persistence + +When persistent sessions are enabled, session data is available in the database and Infinispan session caches are configured to have `num_owners=1`. +Consequently, state-transfer for embedded caches provides no additional availability for session data, whilst adding significant overhead when {project_name} nodes leave or join the cluster. +Therefore, we now disable state-transfer when the persistent-user-session feature is enabled. +Similarly, we now also disable state-transfer for offline session caches when the persistent-user-session feature is disabled. + +=== Organization custom attribute named `id` behavior change Organizations can have custom attributes named `id`. When both organization attributes and organization ID are included in tokens via the organization membership mapper configuration, the organization ID will override any custom `id` attribute value. Previously, the organization ID was added first and could be overridden by custom attributes. diff --git a/docs/guides/getting-started/getting-started-scaling-and-tuning.adoc b/docs/guides/getting-started/getting-started-scaling-and-tuning.adoc index 7dd8bbca5b8..ba433534ada 100644 --- a/docs/guides/getting-started/getting-started-scaling-and-tuning.adoc +++ b/docs/guides/getting-started/getting-started-scaling-and-tuning.adoc @@ -54,9 +54,6 @@ To avoid losing service availability when a whole cluster is unavailable, see th Horizontal autoscaling allows for adding or removing {project_name} instances on demand. Keep in mind that startup times will not be instantaneous and that optimized images should be used to minimize the start time. -When using the embedded Infinispan cache cluster, dynamically adding or removing cluster members requires Infinispan to perform a rebalancing of the Infinispan caches, which can get expensive if many entries exist in those caches. -To minimize this time we limit number of entries in session related caches to 10000 by default. Note, this optimization is possible only if `persistent-user-sessions` feature is not explicitly disabled in your configuration. - On Kubernetes, the Keycloak custom resource is scalable meaning that it can be targeted by the https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/[built-in autoscaler]. For example to scale on average CPU utilization: [source,yaml] diff --git a/model/infinispan/src/main/java/org/keycloak/spi/infinispan/impl/embedded/CacheConfigurator.java b/model/infinispan/src/main/java/org/keycloak/spi/infinispan/impl/embedded/CacheConfigurator.java index 0c79d8e6910..62c942d74b2 100644 --- a/model/infinispan/src/main/java/org/keycloak/spi/infinispan/impl/embedded/CacheConfigurator.java +++ b/model/infinispan/src/main/java/org/keycloak/spi/infinispan/impl/embedded/CacheConfigurator.java @@ -253,6 +253,8 @@ public final class CacheConfigurator { builder.clustering().hash().numOwners(1); if (sessionCaches.contains(name)) { configureSessionExpirationReaper(builder); + // Disable state-transfer to reduce the overhead of new nodes joining + builder.clustering().stateTransfer().fetchInMemoryState(false); } } } @@ -304,6 +306,8 @@ public final class CacheConfigurator { builder.clustering().hash().numOwners(1); } configureSessionExpirationReaper(builder); + // Disable state-transfer to reduce the overhead of new nodes joining + builder.clustering().stateTransfer().fetchInMemoryState(false); } }