Keycloak - Infinispan Redis 缓存存储 [英] Keycloak - Infinispan Redis cache store

查看:67
本文介绍了Keycloak - Infinispan Redis 缓存存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Currently setting up a keycloak cluster in standalone-ha mode, to be able to run on docker swarm. In keycloak, the user sessions are cached in an embedded infinispan store and infinispan can be configured to be a distributed cache across the cluster.

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

I have also set the owner to be 2, but the problem is that.. during scale-down, there is a possibility for the user-sessions to be lost, If both the owners containing the cache are killed during scale-down.

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

I have also read about Infinispan Redis cache store, but I am not sure how to configure this.

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

Question 1: Is it possible to configure Keycloak Infinispan to user a Redis Store ?

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

Question 2: If this is not possible, is there a way that one could overcome this problem ?

任何建议都会有所帮助.

Any suggestions would be helpful.

推荐答案

由于这个 PR https://github.com/keycloak/keycloak/commit/056ba75a72b1595ca9fa471f5693201fd5b2c7ae 默认情况下(Keycloak 最新版本 6.0.1)使用 InfinispanChangelogBasedTransaction.java 的 Infinispan Connection SPICacheDecorator.java 有一个非常特殊的用途,它会skipCacheStore.这意味着无论你是否配置了持久化存储,该存储都将被忽略.

Due to this PR https://github.com/keycloak/keycloak/commit/056ba75a72b1595ca9fa471f5693201fd5b2c7ae by default (Keycloak latest release 6.0.1) the Infinispan Connection SPI which uses InfinispanChangelogBasedTransaction.java has a very particular use of a CacheDecorator.java which will skipCacheStore. This means that no matter if you configure a store with persistence the store will be ignored.

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

In order to achieve what you want, besides configuring the store, you would have to customize most of the SPIs here https://github.com/keycloak/keycloak/tree/master/model/infinispan/src/main/resources/META-INF/services in order to make sure that Keycloak will be using the cache store.

这也不容易,因为这个过程涉及很多额外的好处,例如,因为 Keycloak 使用 Jboss 的 Marshaller,如果你定制这个 SPI,你将不得不带来大部分 org.keycloak.models.sessions.infinispan 打包并注册您的模块,以确保 Wildfly 能够看到要编组的实体.

This will also not be easy since there are a lot of perks involved into the process, for example, since Keycloak is using the Marshaller of Jboss, if you customize this SPIs you would have to bring most of the org.keycloak.models.sessions.infinispan package and register your module to make sure that Wildfly will be able to see the entities to marshall.

另一件事是,您应该使用 Redis 配置大多数指向一个公共数据库的缓存,除了 authenticationSessions 不能与 sessions 位于同一数据库中, 否则会出现RootAuthenticationSessionEntity被找到但预期为SessionEntityWrapper之类的冲突.

Another thing is that you should, with Redis, configure most of the caches pointing to one common database, except the authenticationSessions which cannot be in the same database as sessions, otherwise, there will be conflicts like the RootAuthenticationSesssionEntity being found but expected to be SessionEntityWrapper.

重新开始,过程会很痛苦,但如果你敢于去做,我就是这样实现的:

To resume, the process will be painfull, but if you want to dare and do it, this is how I achieved it:

  • 引入了自定义的 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 基本上是原始存储的精简版本,但我不需要 Sentinel 或服务器模式我只想连接到主机、端口和数据库.

The RedisCacheStoreConfigurationBuilder that you see there is basically a stripped-down version of the original store but I don't need Sentinel or Server mode I just want to connect to a host, port, and database.

然后我基本上复制了 org.keycloak.models.sessions.infinispan 删除与删除缓存相关的所有内容,而不是通常使用没有装饰器的缓存来跳过缓存存储.

Then I basically copied the org.keycloak.models.sessions.infinispan removing everything related to remove cache, and instead of using normally the cache without the decorator to skipCacheStore.

如果我能帮上什么忙,请告诉我,我会准备一篇更详细地说明如何做到这一点的帖子,还包括一个包含我正在谈论的代码的存储库.如果有人还在尝试这个,请告诉我更多.

Let me know if I can help with something, I will most prepare a post that instructs more detailed how to do this, involving also a repository that will contain the codes that I am talking about. Please let me know more if someone is still trying this.

这篇关于Keycloak - Infinispan Redis 缓存存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆