EVALSHA allows to run if all commands are readonly in replica
Search before asking
- [x] I had searched in the issues and found no similar issues.
Motivation
Redis allows the EVALSHA/EVAL command to run the read-only commands in replica, but Kvrocks don't. So we would like to support this to keep consistent behavior with Redis.
For more context, please refer to: https://lists.apache.org/thread/f6n8qpl2fnho472b63o7r4d7ygsqz3t4
Solution
No response
Are you willing to submit a PR?
- [ ] I'm willing to submit a PR!
Hi @git-hulk ,
It seems that Apache James is pending by this issue.
I want to try with my best on this issue and hope it could help. 😊
Best Regards, Edward
@LindaSummer Assigned, thank you!
Hi @git-hulk ,
I have read through redis code and kvrocks code and found the difference.
Kvrocks checks the script command EVALSHA/EVAL and EVALSHA_RO/EVAL_RO before script execution.
Redis discards the command's read or write attribution and check the command invoked by lua script in runtime.
Here is redis logic.
It is called by lua_pcall in lua runtime.
struct redisCommand *cmd = lookupCommand(c->argv, c->argc);
......
......
if (scriptVerifyWriteCommandAllow(run_ctx, err) != C_OK) {
goto error;
}
It checks the command which are called by lua script in runtime.
For example, if we run EVAL "return redis.call('GET', KEYS[1])" 1 mykey, redis will check GET during execution rather than EVAL ahead of script execution.
In kvrocks, I plan to add logic here and add a new option restrict-ro-script.
If it is enabled, we will check the script command like EVAL and EVAL_RO before executing the script with current behavior.
If it is disabled, we will bypass the EVAL_RO to EVAL and pass the node's role to lua context and check the command's behavior in runtime.
Before implementation, I would like to share my draft idea and please let me know if this idea has any problem.
Wish you a good day! 😊
Best Regards, Edward
@LindaSummer Sounds good to me, thank you!
从服务器无法使用 LUA 代码,即使设置 slave-read-only no ,依然会报错: READONLY You can't write against a read only slave
这个问题大概几时能解决?
Sorry for the delay on this problem. I will continue working on this issue in recent.
@haodiao For read-only commands, I think you can use EVAL_RO and EVALSHA_RO in replica.
@PragmaTwice 在 从服务器 上无法使用 script load ,那怎么使用 evalsha_ro 呢?
You can:
- use EVAL_RO instead;
- use EVALSHA_RO in replica after SCRIPT LOAD in master.
- use EVALSHA_RO in replica after SCRIPT LOAD in master.
原来可以这样的啊,这我到没有测试过,但我记得 redis 在 主服务器 上 script load 的 lua 是不会同步到 从服务器 上的。
有时间我去修改一下我的代码了,感谢!
You can also use FUNCTION LOAD and FCALL_RO.
在这里我报告一个 bug 吧,不想再开一个issues 了,问题就是,使用 msgpack 编码之后,在 kvrocks lua 中无法解包。
当 msgpack 编码的数组中包含有二进制的元素,那么使用 local ok, unpacked = pcall(cmsgpack.unpack, data) 无法解包 ok=false,unpacked 打印出错误 Bad data format in input.
当 msgpack 编码的数组中不包含二进制元素,那么就能成功的解包。