Keycloak - Infinispan Redis 缓存存储

问题描述 投票:0回答:3

目前正在以standalone-ha模式设置keycloak集群,以便能够在docker swarm上运行。在 keycloak 中,用户会话缓存在嵌入式 infinispan 存储中,并且 infinispan 可以配置为跨集群的分布式缓存。

我也将所有者设置为2,但问题是..在缩小规模期间,如果包含缓存的两个所有者在缩小期间都被杀死,则用户会话可能会丢失。

我还阅读了有关 Infinispan Redis 缓存存储的信息,但我不确定如何配置它。

问题1: 是否可以配置 Keycloak Infinispan 以使用 Redis 存储?

问题2: 如果这是不可能的,有没有办法可以克服这个问题?

任何建议都会有帮助。

jboss wildfly infinispan keycloak
3个回答
8
投票

由于此 PR https://github.com/keycloak/keycloak/commit/056ba75a72b1595ca9fa471f5693201fd5b2c7ae 默认情况下(Keycloak 最新版本 6.0.1),使用

Infinispan Connection SPI
InfinispanChangelogBasedTransaction.java
CacheDecorator.java 具有非常特殊的用途
这将
skipCacheStore
。这意味着无论您是否配置具有持久性的存储,该存储都将被忽略。

为了实现你想要的,除了配置商店之外,你还必须在这里自定义大部分SPI https://github.com/keycloak/keycloak/tree/master/model/infinispan/src/main/resources /META-INF/services 以确保 Keycloak 将使用缓存存储。

这也不容易,因为这个过程涉及很多额外的好处,例如,由于 Keycloak 使用 Jboss 的 Marshaller,如果您自定义此 SPI,则必须携带大部分

org.keycloak.models.sessions.infinispan
包并注册您的模块,以确保 Wildfly 能够看到要编组的实体。

还有一点就是,使用Redis,你应该配置大部分缓存指向同一个数据库,除了

authenticationSessions
,不能与
sessions
在同一个数据库,否则会出现像
RootAuthenticationSesssionEntity
那样的冲突被发现但预计会
SessionEntityWrapper

要恢复,过程会很痛苦,但如果你想敢做,我就是这样实现的:

  • 引入了自定义 InfinispanConnectionProviderFactory,以便能够完全使用 infinispan 配置,然后配置我的容器,例如:
private Configuration getRedisConfiguration(int database) {
    ConfigurationBuilder cb = new ConfigurationBuilder();
    cb.persistence()
      .passivation(false)
      .addStore(RedisCacheStoreConfigurationBuilder.class)
      .ignoreModifications(false)
      .fetchPersistentState(false)
      .purgeOnStartup(false)
      .preload(false)
      .shared(true)
      .addProperty("host", System.getenv("REDIS_HOST"))
      .addProperty("port", System.getenv("REDIS_PORT"))
      .addProperty("database", String.valueOf(database));

    return cb.build();
  }

您看到的

RedisCacheStoreConfigurationBuilder
基本上是原始商店的精简版本,但我不需要哨兵或服务器模式,我只想连接到主机、端口和数据库。

然后我基本上复制了

org.keycloak.models.sessions.infinispan
删除与删除缓存相关的所有内容,而不是正常使用没有装饰器的缓存来跳过CacheStore。

如果我可以提供帮助,请告诉我,我最会准备一篇文章,指导更详细的操作方法,还涉及一个包含我正在讨论的代码的存储库。如果有人仍在尝试此操作,请告诉我更多信息。


2
投票

当期望动态扩展大型系统时,期望避免这种在配置中注册可用节点列表的约束。所以 Redis 节点发现在这里是一个好处。

Infinispan 本身支持 Redis Store 作为扩展,实现 SPI 并添加 XML 实体以简化配置:

但是 WildFly infinispan 子系统尚不支持此扩展 - 因为 Keycloak 依赖于 WildFly。

因此,我希望通过以下任务使 Infinispan Redis Store 可用于 WildFly,以及 Keycloak:

工作正在进行中,可能会发布代码和配置。


1
投票

在 Infinispan 背后使用 Redis 存储有什么特殊原因吗?

更简单的解决方案可能是将持久性配置为文件或共享数据库。对于这样的缓存用例,基于文件的持久性可能就足够了。有关使用基于文件的持久性配置 Infinispan 的示例,请参阅此处。或者,您可以存储到共享数据库,例如Postgresql,但这需要更多设置(例如参见参考卡)。

© www.soinside.com 2019 - 2024. All rights reserved.