spring-data-redis icon indicating copy to clipboard operation
spring-data-redis copied to clipboard

RedisTemplate.execute doesn't allow to specify action type and treats operation type as "read" by default

Open mykhailokulakov opened this issue 2 years ago • 2 comments

Hi! I'm using a master/replica scheme with "read from replica" client property enabled.

var masterReplicaConfiguration =  new RedisStaticMasterReplicaConfiguration(masterNode.getHost(), masterNode.getPort());
redisProperties
    .getReplicas()
    .forEach(
        replica -> {
          RedisNode node = RedisNode.fromString(replica.getHost());
          masterReplicaConfiguration.addNode(node.getHost(), node.getPort());
        });

LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigBuilder =
    LettuceClientConfiguration.builder().readFrom(ReadFrom.REPLICA_PREFERRED);

And I've tried to use custom distributed lock implementation, which is based on Redis scripts, like

private static final String LOCK_SCRIPT = "return redis.call('SET', KEYS[1], ARGV[1], 'PX', tonumber(ARGV[2]), 'NX') and true or false";

@Override
protected String acquire(final String key, final String storeId, final String token, final long expiration) {
  final List<String> singletonKeyList = Collections.singletonList(storeId + ":" + key);
  final boolean locked = stringRedisTemplate.execute(lockScript, singletonKeyList, token, String.valueOf(expiration));
  ...
}

It seems that "execute" is treated as a read operation by default, so it throws:

Caused by: <#029e4a23> org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisReadOnlyException: READONLY You can't write against a read only replica. script: 15df23044ffd4f2723d9689555be4a5cccac4154, on @user_script:1.
	at o.s.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:54)

Is it possible to expose any options when calling RedisTemplate.execute to flag the operation as READ_WRITE, such as with Redissons RScript.Mode?

mykhailokulakov avatar Jun 23 '23 11:06 mykhailokulakov

Right now, we do not expose evalReadOnly methods. Since both clients support that functionality, we could introduce read-only/read-write flavors to scripts so that clustered runtimes can route commands accordingly.

mp911de avatar Jun 28 '23 08:06 mp911de

It should help us with this issue. Thanks!

mykhailokulakov avatar Jun 28 '23 08:06 mykhailokulakov