Hi all, Does the Redis ticket registry support Redis Cluster mode (not Sentinel) in order to provide high availability?
The following link has mentioned that Redis can support Sentinel, but not mention Cluster for configuration. https://fawnoos.com/2022/06/02/ticket-registry-options/ I have tried to config my CAS server to connect to one Redis Cluster (one master one slave) but no luck. Once I shut down the master node then the service was down immediately and the CAS kept showing the error log below: cas-overlay-cas-1 | 2023-08-17 10:05:11,262 WARN [io.lettuce.core.protocol.ConnectionWatchdog] - <Cannot reconnect to [XXX.XXX.XXX.XXX:6379]: finishConnect(..) failed: Connection refused: / XXX.XXX.XXX.XXX:6379> cas-overlay-cas-1 | 2023-08-17 10:05:31,081 ERROR [org.apereo.cas.ticket.registry.DefaultTicketRegistryCleaner] - <Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Comma nd timed out after 1 minute(s); nested exception is org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s)> cas-overlay-cas-1 | org.springframework.data.redis.connection.ClusterCommandExecutionFailureException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s); nested exception is org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.collectResults(ClusterCommandExecutor.java:267) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandAsyncOnNodes(ClusterCommandExecutor.java:210) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnAllNodes(ClusterCommandExecutor.java:178) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.lettuce.LettuceClusterKeyCommands.keys(LettuceClusterKeyCommands.java:90) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.DefaultedRedisConnection.keys(DefaultedRedisConnection.java:123) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.core.RedisTemplate.lambda$keys$14(RedisTemplate.java:896) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.core.RedisTemplate.keys(RedisTemplate.java:896) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.apereo.cas.ticket.registry.RedisTicketRegistry.getKeysStream(RedisTicketRegistry.java:198) ~[cas-server-support-redis-ticket-registry-6.6.10.jar!/:6.6.10] cas-overlay-cas-1 | at org.apereo.cas.ticket.registry.RedisTicketRegistry.getKeysStream(RedisTicketRegistry.java:194) ~[cas-server-support-redis-ticket-registry-6.6.10.jar!/:6.6.10] cas-overlay-cas-1 | at org.apereo.cas.ticket.registry.RedisTicketRegistry.stream(RedisTicketRegistry.java:164) ~[cas-server-support-redis-ticket-registry-6.6.10.jar!/:6.6.10] cas-overlay-cas-1 | at org.apereo.cas.ticket.registry.DefaultTicketRegistryCleaner.cleanInternal(DefaultTicketRegistryCleaner.java:63) ~[cas-server-core-tickets-api-6.6.10.jar!/:6.6.10] cas-overlay-cas-1 | at org.apereo.cas.ticket.registry.DefaultTicketRegistryCleaner.clean(DefaultTicketRegistryCleaner.java:41) ~[cas-server-core-tickets-api-6.6.10.jar!/:6.6.10] cas-overlay-cas-1 | at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] cas-overlay-cas-1 | at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] cas-overlay-cas-1 | at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] cas-overlay-cas-1 | at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] cas-overlay-cas-1 | at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at com.sun.proxy.$Proxy318.clean(Unknown Source) ~[?:?] cas-overlay-cas-1 | at org.apereo.cas.config.CasCoreTicketsSchedulingConfiguration$TicketRegistryCleanerScheduler.lambda$clean$0(CasCoreTicketsSchedulingConfiguration.java:104) ~[cas-server-core-tickets-6.6.10. jar!/:6.6.10] cas-overlay-cas-1 | at org.apereo.cas.util.function.FunctionUtils.doAndHandle(FunctionUtils.java:313) ~[cas-server-core-util-api-6.6.10.jar!/:6.6.10] cas-overlay-cas-1 | at org.apereo.cas.config.CasCoreTicketsSchedulingConfiguration$TicketRegistryCleanerScheduler.clean(CasCoreTicketsSchedulingConfiguration.java:104) ~[cas-server-core-tickets-6.6.10.jar!/:6.6 .10] cas-overlay-cas-1 | at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] cas-overlay-cas-1 | at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] cas-overlay-cas-1 | at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] cas-overlay-cas-1 | at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] cas-overlay-cas-1 | at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.3.22.jar!/:5.3.22] cas-overlay-cas-1 | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[?:?] cas-overlay-cas-1 | at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[?:?] cas-overlay-cas-1 | at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[?:?] cas-overlay-cas-1 | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[?:?] cas-overlay-cas-1 | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[?:?] cas-overlay-cas-1 | at java.lang.Thread.run(Thread.java:829) ~[?:?] cas-overlay-cas-1 | Suppressed: org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) cas-overlay-cas-1 | at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:70) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.convertToDataAccessException(ClusterCommandExecutor.java:332) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnSingleNode(ClusterCommandExecutor.java:142) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnSingleNode(ClusterCommandExecutor.java:118) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.lambda$executeCommandAsyncOnNodes$0(ClusterCommandExecutor.java:207) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?] cas-overlay-cas-1 | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[?:?] cas-overlay-cas-1 | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[?:?] cas-overlay-cas-1 | at java.lang.Thread.run(Thread.java:829) ~[?:?] cas-overlay-cas-1 | Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) cas-overlay-cas-1 | at io.lettuce.core.internal.ExceptionFactory.createTimeoutException(ExceptionFactory.java:59) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at io.lettuce.core.internal.Futures.awaitOrCancel(Futures.java:246) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:75) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at com.sun.proxy.$Proxy343.keys(Unknown Source) ~[?:?] cas-overlay-cas-1 | at org.springframework.data.redis.connection.lettuce.LettuceClusterKeyCommands.lambda$keys$0(LettuceClusterKeyCommands.java:90) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnSingleNode(ClusterCommandExecutor.java:139) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | ... 6 more cas-overlay-cas-1 | Caused by: org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) cas-overlay-cas-1 | at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:70) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.convertToDataAccessException(ClusterCommandExecutor.java:332) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnSingleNode(ClusterCommandExecutor.java:142) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnSingleNode(ClusterCommandExecutor.java:118) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.lambda$executeCommandAsyncOnNodes$0(ClusterCommandExecutor.java:207) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?] cas-overlay-cas-1 | ... 3 more cas-overlay-cas-1 | Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) cas-overlay-cas-1 | at io.lettuce.core.internal.ExceptionFactory.createTimeoutException(ExceptionFactory.java:59) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at io.lettuce.core.internal.Futures.awaitOrCancel(Futures.java:246) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:75) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80) ~[lettuce-core-6.2.0.RELEASE.jar!/:6.2.0.RELEASE] cas-overlay-cas-1 | at com.sun.proxy.$Proxy343.keys(Unknown Source) ~[?:?] cas-overlay-cas-1 | at org.springframework.data.redis.connection.lettuce.LettuceClusterKeyCommands.lambda$keys$0(LettuceClusterKeyCommands.java:90) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnSingleNode(ClusterCommandExecutor.java:139) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnSingleNode(ClusterCommandExecutor.java:118) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at org.springframework.data.redis.connection.ClusterCommandExecutor.lambda$executeCommandAsyncOnNodes$0(ClusterCommandExecutor.java:207) ~[spring-data-redis-2.7.2.jar!/:2.7.2] cas-overlay-cas-1 | at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?] cas-overlay-cas-1 | ... 3 more Not sure my expectation is correct or not, but I would expect the CAS server would make the connection to both master and slave nodes. If one node is died then the CAS server can automatically use the other node for connection. But this seems not the case. If Redis Cluster can be supported, may I know what config are required? Below are the configuration that I am trying, which is able to connect to the master node but not the slave one if the master node is died: cas.ticket.registry.redis.cluster.password= cas.ticket.registry.redis.cluster.nodes[0].name=xxx.master.com cas.ticket.registry.redis.cluster.nodes[0].host=xxx.master.com cas.ticket.registry.redis.cluster.nodes[0].port=6379 cas.ticket.registry.redis.cluster.nodes[0].replica-of=0 cas.ticket.registry.redis.cluster.nodes[0].type=MASTER cas.ticket.registry.redis.cluster.nodes[1].name=xxx.slave.com cas.ticket.registry.redis.cluster.nodes[1].host=xxx.slave .com cas.ticket.registry.redis.cluster.nodes[1].port=6379 cas.ticket.registry.redis.cluster.nodes[1].replica-of=0 cas.ticket.registry.redis.cluster.nodes[1].type=SLAVE cas.ticket.registry.redis.database=0 cas.ticket.registry.redis.enabled=true cas.ticket.registry.redis.pool.enabled=false cas.ticket.registry.redis.host=xxx.master.com cas.ticket.registry.redis.port=6379 cas.ticket.registry.redis.use-ssl=false Thx a lot. ------------------------------------------------------------------------------ Disclaimer This message (including any attachments) may contain confidential information intended for a specific individual and/or purpose. If you are not the intended recipient, please delete this message and notify the sender and the University immediately. Any disclosure, copying, or distribution of this message, or the taking of any action based on it, is prohibited as it may be unlawful. In addition, the University specifically denies any responsibility for the accuracy or quality of information obtained through University E-mail Facilities. Any views and opinions expressed in the email(s) are those of the author(s), and do not necessarily represent the views and opinions of the University. The University accepts no liability whatsoever for any losses or damages that may be incurred or caused to any party as a result of the use of such information. -- - Website: https://apereo.github.io/cas - Gitter Chatroom: https://gitter.im/apereo/cas - List Guidelines: https://goo.gl/1VRrw7 - Contributions: https://goo.gl/mh7qDG --- You received this message because you are subscribed to the Google Groups "CAS Community" group. To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+unsubscr...@apereo.org. To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/3880ceef-a7ce-49f8-8107-32c075343cbfn%40apereo.org.