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.

Reply via email to