Redis Configuration
Rqueue stores tasks, and it’s transient state in Redis. We can configure Application to use one redis connection for Rqueue and another one for Application, this will allow complete isolation of Redis connection and usage.
Redis Connection Configuration
All Rqueue data is stored in Redis database. As an application developer, you have the flexibility to specify which redis cluster/server should be used by Rqueue. You need to specify redis connection via container factory’s method setRedisConnectionFactory
.
While creating redis connection factory you must use readFrom MASTER_PREFERRED
otherwise application won’t start.
Standalone Redis
@Configuration
public class RqueueConfiguration {
// this property must be set to true if you're using webflux or reactive redis
@Value("${rqueue.reactive.enabled:false}")
private boolean reactiveEnabled;
@Bean
public SimpleRqueueListenerContainerFactory simpleRqueueListenerContainerFactory() {
LettuceClientConfiguration lettuceClientConfiguration =
LettuceClientConfiguration.builder().readFrom(ReadFrom.MASTER_PREFERRED).build();
// Stand alone redis configuration, Set fields of redis configuration
RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration();
// set properties of redis configuration as you need.
// Create lettuce connection factory
LettuceConnectionFactory redisConnectionFactory = new LettuceConnectionFactory(redisConfiguration, lettuceClientConfiguration);
redisConnectionFactory.afterPropertiesSet();
SimpleRqueueListenerContainerFactory factory = new SimpleRqueueListenerContainerFactory();
factory.setRedisConnectionFactory(redisConnectionFactory);
// if reactive redis is enabled set the correct connection factory
if (reactiveEnabled) {
factory.setReactiveRedisConnectionFactory(lettuceConnectionFactory);
}
// set other properties as you see
return factory;
}
}
Redis Cluster
For Redis cluster you should use Lettuce client as Jedis client does not support EVALSHA
request.
@Configuration
public class RqueueConfiguration {
// this property must be set to true if you're using webflux or reactive redis
@Value("${rqueue.reactive.enabled:false}")
private boolean reactiveEnabled;
@Bean
public SimpleRqueueListenerContainerFactory simpleRqueueListenerContainerFactory() {
// here always use MASTER_PREFERRED otherwise it will to start
LettuceClientConfiguration lettuceClientConfiguration =
LettuceClientConfiguration.builder().readFrom(ReadFrom.MASTER_PREFERRED).build();
// add all nodes
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
List<RedisNode> redisNodes = new ArrayList<>();
redisNodes.add(new RedisNode("127.0.0.1", 9000));
redisNodes.add(new RedisNode("127.0.0.1", 9001));
redisNodes.add(new RedisNode("127.0.0.1", 9002));
redisNodes.add(new RedisNode("127.0.0.1", 9003));
redisNodes.add(new RedisNode("127.0.0.1", 9004));
redisNodes.add(new RedisNode("127.0.0.1", 9005));
redisClusterConfiguration.setClusterNodes(redisNodes);
// create lettuce connection factory
LettuceConnectionFactory lettuceConnectionFactory =
new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
lettuceConnectionFactory.afterPropertiesSet();
SimpleRqueueListenerContainerFactory simpleRqueueListenerContainerFactory =
new SimpleRqueueListenerContainerFactory();
simpleRqueueListenerContainerFactory.setRedisConnectionFactory(lettuceConnectionFactory);
// set polling interval, by default its 5 seconds
simpleRqueueListenerContainerFactory.setPollingInterval(Constants.ONE_MILLI);
// if reactive redis is enabled set the correct connection factory
if (reactiveEnabled) {
simpleRqueueListenerContainerFactory.setReactiveRedisConnectionFactory(
lettuceConnectionFactory);
}
// set any other property if you need
// return connection factory
return simpleRqueueListenerContainerFactory;
}
}
Redis Sentinel
Redis sentinel can be configured similar to Standalone redis.
@Configuration
public class RedisClusterBaseApplication{
@Bean
public SimpleRqueueListenerContainerFactory simpleRqueueListenerContainerFactory() {
LettuceClientConfiguration lettuceClientConfiguration =
LettuceClientConfiguration.builder().readFrom(ReadFrom.MASTER_PREFERRED).build();
// Sentinel redis configuration, Set fields of redis configuration
RedisSentinelConfiguration redisConfiguration = new RedisSentinelConfiguration();
// Create lettuce connection factory
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisConfiguration, lettuceClientConfiguration);
lettuceConnectionFactory.afterPropertiesSet();
SimpleRqueueListenerContainerFactory simpleRqueueListenerContainerFactory =
new SimpleRqueueListenerContainerFactory();
simpleRqueueListenerContainerFactory.setRedisConnectionFactory(lettuceConnectionFactory);
simpleRqueueListenerContainerFactory.setPollingInterval(Constants.ONE_MILLI);
if (reactiveEnabled) {
simpleRqueueListenerContainerFactory.setReactiveRedisConnectionFactory(
lettuceConnectionFactory);
}
return simpleRqueueListenerContainerFactory;
}
}
Redis connection failure and retry
All Redis commands failure would be retried in 5 seconds, to change that we can set back off to some different value.
class RqueueConfiguration {
@Bean
public SimpleRqueueListenerContainerFactory simpleRqueueListenerContainerFactory() {
SimpleRqueueListenerContainerFactory factory = new SimpleRqueueListenerContainerFactory();
//...
// set back off time to 100 milli second
factory.setBackOffTime(100);
return factory;
}
}
Redis Key configuration
Rqueue uses multiple Redis data types like SET
, ZSET
, LIST
etc. Generally, you should not delete or change any Rqueue related redis keys. As developer mistake happens, one mistake can lead to deletion of all tasks. Due to this Rqueue prefix all of it’s key.
rqueue.key.prefix
: Prefix for every key used by Rqueuerqueue.cluster.mode
: Whether your Redis database is cluster or not, by default it’s assumed cluster mode. Rqueue usesLua
script for atomic operation, changing from non-cluster to cluster can lead toCross Slot
error.rqueue.simple.queue.prefix:queue
: Prefix to be used for the simple queue (LIST
), by default it usedqueue
, so each key would look like__rq::queue::XYZ
rqueue.scheduled.queue.prefix
: Prefix to be used for the delayed queue (ZSET
), by default it’s configured to used-queue::
, therefor each scheduledZSET
key would look like__rq::d-queue::XYZ
rqueue.scheduled.queue.channel.prefix
: Rqueue communicates with Redis using Redis pub/sub for some use cases, this channel is used when the message from scheduled queue must be moved to simple queue for processing. Default value isp-channel
.rqueue.processing.queue.name.prefix
: Prefix to be used for the processing queue (ZSET
), by default it’s configured to usep-queue::
, there for each processingZSET
key would look like__rq::p-queue::XYZ
. This queue is used to provide at least once message delivery.rqueue.processing.queue.channel.prefix
: Rqueue communicates with Redis using Redis pub/sub for some use cases, this channel is used when the message from processing queue must be moved to origin queue, this happens when the listener dies in between. Default value isp-channel
.rqueue.queues.key.suffix
: Key to be used fot storing all active queues, default value isqueues
.rqueue.lock.key.prefix
: The key prefix to be used for locking, default value islock::
rqueue.queue.stat.key.prefix
: The key prefix to be used for storing queue metrics, default value isq-stat
.rqueue.queue.config.key.prefix
: The key prefix to be used for storing listener configuration, default value isq-config
.