-
会话存储在数据库中并在内存中缓存
-
集群重启后会话仍然可用
-
更低的内存使用量
-
更高的数据库使用量
2024 年 12 月 17 日,作者:Michal Hajas
Keycloak 26 现在默认使用持久用户会话功能。在这篇博文中,我们将揭示我们引入此功能的背景原因、有哪些替代方案以及未来发展方向。
本节提供关于会话存储类型以及在 Keycloak 26 中何时应使用它们的 TLDR 指南。以下各节将详细介绍每种存储类型以及引入或放弃每种存储类型的理由。
站点数量 | 会话存储 | 特性 | 何时使用 | 启用 Keycloak CLI 选项 |
---|---|---|---|---|
单站点 |
持久会话 |
|
|
无需额外配置 |
会话存储在内存中 |
|
|
--features-disabled="persistent-user-sessions" |
|
会话存储在外部 Infinispan 中 |
|
|
--features="clusterless" --features-disabled="persistent-user-sessions" |
|
会话存储在内存和外部 Infinispan 中 |
|
|
--features="cache-embedded-remote-store" --features-disabled="persistent-user-sessions" |
|
多站点 (指南) |
持久用户会话 |
|
|
--features="multi-site" |
会话存储在外部 Infinispan 中 |
|
|
--features="multi-site,clusterless" --features-disabled="persistent-user-sessions" |
在早期的 Keycloak 版本中,所有会话都只存储在嵌入式 Infinispan 中 - 分布式缓存中每个 Keycloak 节点的内存中(每个 Keycloak 节点存储一部分会话,每个会话至少存在于 2 个节点中)。这在会话数量较少到中等的单站点环境中运行良好,并且该设置能够抵抗一个 Keycloak 节点故障而不会丢失任何数据。如果我们增加存储每个会话的节点数量,则可以扩展到多个节点。
当更多节点发生故障或整个站点发生故障时,问题就出现了。用户要求更具弹性的设置。为此,我们引入了跨站点功能的预览版。对会话数据的影响是我们将其复制到 4 个位置 - 2 个 Keycloak 集群和 2 个 Infinispan 集群。这些位置中的每一个都需要存储所有会话,以便能够搜索/查询它们。
最初,此设置的性能不是很好,其中一个原因是我们需要同步复制数据 4 次以保持系统处于正确的状态。由于这种糟糕的性能,我们最初想要放弃该功能,但是由于社区的强烈兴趣,我们决定改进该功能。经过多次优化和性能调整,我们能够在 Keycloak 24 中以 multi-site
的名称发布此功能,该功能允许主-备设置。此架构将一些数据异步复制到第二个 Keycloak 集群,因此,我们无法以主-主方式使用此设置。
即使通过此设置我们更具弹性,但当整个部署崩溃时,我们仍然会丢失会话,例如在更新期间。我们收到了很多关于此问题的投诉。
这就是持久会话作为解决这两个问题的救星而出现的原因 - 异步更新复制到另一个站点和会话丢失。其想法是将会话存储在数据库中 - 会话的真实来源。我们已经将离线会话存储在数据库中,因此我们重用了这个概念,并引入了一个名为持久用户会话的新功能,该功能现在在 Keycloak 26 中默认启用。
几乎每个进入 Keycloak 的请求都需要检查会话是否存在、是否有效,并且通常还需要更新其有效期限。这使得会话成为读写密集型对象,数据库是否是存储它们的正确位置这个问题是合理的。
在撰写这篇博文时,我们没有收到任何报告表明持久用户会话存在性能问题,而且看起来优点克服了缺点。尽管如此,我们还有一个实验模式下的附加功能供您评估。如上所述,Keycloak 24 中多站点设置的一些问题是我们需要将会话复制到 4 个位置,并且第二个 Keycloak 集群异步接收一些更新。这也可以通过仅将会议存储在外部 Infinispan 中来解决,因为会话仅复制两次而不是四次。此外,由于我们不需要将更改复制到 Keycloak 节点,因此不再使用异步复制。Infinispan 还为搜索会话提供了查询和索引功能,避免了存储在嵌入式 Infinispan 中的会话所需的顺序扫描。请注意,这是一个实验性功能,因此尚未完全完成和性能优化。我们渴望听到您的反馈,以了解持久用户会话在哪些方面失败,以及纯 Infinispan 会话存储可以在哪些方面发挥作用。
由于我们无法在没有适当弃用期的情况下从上面的列表中删除任何选项,因此所有选项仍然可以在 Keycloak 26 中使用,但是,其中一些选项比其他选项更受青睐。
这是 Keycloak 26 中的默认设置。
这是 Keycloak 26 之前版本中使用的默认设置,目前可能是所有设置中最常用的。建议切换到持久用户会话,并且在 Keycloak 26 中无需额外配置即可自动完成切换。但是,如果您在使用持久用户会话时遇到一些问题(渴望在此处听到您的反馈 here),并且您不介意在重启时丢失会话,则可以通过禁用 persistent-user-sessions
功能来启用此设置。
bin/kc.[sh|bat] build --features-disabled="persistent-user-sessions"
这是上面提到的实验性设置。要配置此项,请禁用 persistent-user-sessions
并启用 clusterless
功能。
bin/kc.[sh|bat] build --features="clusterless" --features-disabled="persistent-user-sessions"
此设置使用旨在用于多站点的功能,但是,这也经常在单站点中使用,因为它具有在 Keycloak 重启时不会丢失会话的优点。我们认为持久用户会话使此设置过时,Keycloak 将拒绝使用此设置启动并显示此消息:Remote stores are not supported for embedded caches….
。此功能已弃用,将在下一个 Keycloak 主要版本中删除。要运行此配置,请禁用 persistent-user-sessions
,启用 cache-embedded-remote-store
功能并相应地配置嵌入式 Infinispan。
bin/kc.[sh|bat] build --features="cache-embedded-remote-store" --features-disabled="persistent-user-sessions"
在多站点中运行 Keycloak 需要两个构建块,以使数据在两个站点中可用和同步。同步复制的数据库和每个站点中的外部 Infinispan,并启用跨站点复制。整个设置在此处描述 here。从存储会话的角度来看,该设置始终强制使用持久用户会话功能,并且会话仅存储在数据库中,而不在 Keycloak 的内存中缓存。要配置此项,请启用 multi-site
功能。
bin/kc.[sh|bat] build --features="multi-site"
也可以评估为单站点描述的实验性 clusterless
功能在多站点中的应用。在此设置中,会话不存储在数据库中,而是存储在外部 Infinispan 中。请注意,这是一个实验性功能,因此尚未完全记录和性能优化。要配置此项,请禁用 persistent-user-sessions
并启用 multi-site
和 clusterless
功能。
bin/kc.[sh|bat] build --features="multi-site,clusterless" --features-disabled="persistent-user-sessions"
如果您对此有任何疑问或反馈,请前往以下 GitHub 讨论区
在这种情况下,外部 Infinispan 不用于存储会话,但是,我们仍然需要它用于两个 Keycloak 站点之间的通信,例如,用于失效消息、用于后台任务的同步以及用于存储某些对象(通常是短期的对象),例如身份验证会话、登录失败或操作令牌。