dragonflydb / dragonfly

A modern replacement for Redis and Memcached
https://www.dragonflydb.io/
Other
25.96k stars 954 forks source link

lua scripts readonly error on slave replica #4130

Closed imhun closed 2 days ago

imhun commented 1 week ago

Describe the bug A clear and concise description of what the bug is.

org.redisson.client.RedisException: ERR Error running script (call to 149c5a8bf18676fd99e9e6e24923bd64d9b62f94): @user_script:2: -READONLY You can't write against a read only replica.. channel: [id: 0xd5d027a5, L:/100.64.0.3:58328 - R:dev.ip.local/172.18.78.49:16380] command: (EVAL), params: [if ((redis.call('exists', KEYS[1]) == 0) or (redis.call('hexists', KEYS[1], ARGV[2]) == 1)) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, fabric.Lock.OPERATION_LOG.lock, 5000, 2f3c8128-65f1-42e8-8b6a-4c910db0b75d:183], promise: java.util.concurrent.CompletableFuture@2b83f94d[Not completed, 1 dependents] at org.redisson.client.handler.CommandDecoder

To Reproduce Steps to reproduce the behavior: lua scripts:

if ((redis.call('exists', KEYS[1]) == 0) or (redis.call('hexists', KEYS[1], ARGV[2]) == 1)) then 
redis.call('hincrby', KEYS[1], ARGV[2], 1); 
redis.call('pexpire', KEYS[1], ARGV[1]); 
return nil; 
end;
return redis.call('pttl', KEYS[1]);

See error @user_script:2: -READONLY You can't write against a read only replica.. channel

Expected behavior no error

Environment (please complete the following information):

Reproducible Code Snippet

# Minimal code snippet to reproduce this bug

Additional context Add any other context about the problem here.

romange commented 1 week ago

Why it is a bug? hincrby and pexpire are not allowed on replica.

imhun commented 1 week ago

that should be sent to the primary, and the client does not know which is the primary or replica

romange commented 1 week ago

sounds like a configuration issue with your client then. you should connect it to the primary

imhun commented 1 week ago

lettuce client 6.3 spring boot 3.3 configuration is as follows

image

the following error occurs when the application is started

Caused by: io.lettuce.core.RedisReadOnlyException: READONLY You can't write against a read only replica.
    at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:144)
    at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:116)
    at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120)
    at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111)
    at io.lettuce.core.protocol.CommandWrapper.complete(CommandWrapper.java:63)
    at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:745)
    at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:680)
    at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:597)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)

and redis doesn't have that problem

Is there any special configuration required for dragonflydb?

romange commented 1 week ago

no, if your client is connected to dragonfly to port 16380 and this dragonfly is a master it should just work.

can you post redis-cli -p 16380 -a <passwrd> -h dev.ip.local INFO ALL here?

romange commented 2 days ago

it does not look like a bug with Dragonfly, but if you think it is please provide a minimal reproducible example for us to understand the problem. Closing for now.