-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support lua script in pika #1724
Conversation
@@ -0,0 +1,43 @@ | |||
#ifndef PIKA_SCRIPT_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#pragma once
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
目前pika头文件都是用宏的方式,不过采取两种都使用应该是保险方案?可以参考这个回答 https://www.zhihu.com/question/40990594
@@ -454,6 +471,9 @@ class Cmd : public std::enable_shared_from_this<Cmd> { | |||
bool is_admin_require() const; | |||
bool is_single_slot() const; | |||
bool is_multi_slot() const; | |||
bool is_script() const; | |||
bool is_sort_for_script() const; | |||
bool is_random() const; | |||
bool HashtagIsConsistent(const std::string& lhs, const std::string& rhs) const; | |||
uint64_t GetDoDuration() const { return do_duration_; }; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the provided code patch, here are some observations regarding bug risks and improvement suggestions:
-
In the
CmdFlagsMask
enumeration, the flag values assigned tokCmdFlagsMaskRandom
,kCmdFlagsMaskSortForScript
, andkCmdFlagsMaskScript
are incorrect. They should be8192
,16384
, and32768
respectively, instead of4096
,8192
, and16384
. -
In the
CmdFlags
enumeration, the flagsKCmdFlagsNoRandom
,KCmdFlagsNoSortForScript
, andKCmdFlagsScript
should have a value of8192
,16384
, and0
respectively, instead of being assigned values within the range of other flags. -
The
is_script()
,is_sort_for_script()
, andis_random()
methods are missing their implementations. They can be implemented by checking the command flags using bitwise operations. -
The
CmdRes
enum does not seem to be used in the provided code patch. If it is used elsewhere, ensure that all the necessary error cases are handled properly.
Apart from these specific points, a comprehensive code review would require examining the entire project or context in which this code patch is being applied. It's important to review the rest of the codebase for any potential issues related to error handling, memory management, concurrency, security, and overall design.
@@ -30,6 +31,106 @@ PikaClientConn::PikaClientConn(int fd, const std::string& ip_port, net::Thread* | |||
auth_stat_.Init(); | |||
} | |||
|
|||
// 主从redis.call的命令都从这里执行, 特别注意从的eval命令会调用redis.call | |||
std::shared_ptr<Cmd> PikaClientConn::DoCmdInLua(const PikaCmdArgsType& argv, const std::string& opt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DoCmdLua是DoCmd的改造,主节点和从节点的redis.call都是调用这个函数进行参数检查的, 我去掉了一些在lua里不需要的检查比如说auth,pubsub这些, 各位大佬看看有没有不合理的地方
目前的主从方案是 |
@@ -454,6 +473,9 @@ class Cmd : public std::enable_shared_from_this<Cmd> { | |||
bool is_admin_require() const; | |||
bool is_single_slot() const; | |||
bool is_multi_slot() const; | |||
bool is_script() const; | |||
bool is_sort_for_script() const; | |||
bool is_random() const; | |||
bool HashtagIsConsistent(const std::string& lhs, const std::string& rhs) const; | |||
uint64_t GetDoDuration() const { return do_duration_; }; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code patch includes the following changes:
- Added constants for Lua script commands, such as
eval
,evalsha
, andscript
. - Added new command flags related to scripts and sorting (
kCmdFlagsMaskSortForScript
,kCmdFlagsMaskScript
,KCmdFlagsNoSortForScript
,KCmdFlagsSortForScript
). - Added new error codes for invalid key numbers and missing script (
kInvalidKeyNums
,kNoScript
). - Modified the
CmdRes
class to handle the new error codes. - Added member functions to the
Cmd
class to check if a command is a script, sort for script, or random.
Without seeing the complete context and usage of these changes, it's challenging to provide specific bug risks or improvement suggestions. However, here are some general recommendations:
- Review the usage of the new Lua script-related commands and ensure they are correctly implemented and utilized in your codebase.
- Verify that the new command flags (
kCmdFlagsMaskSortForScript
,kCmdFlagsMaskScript
, etc.) are used consistently throughout the codebase to ensure accurate command classification and handling. - Test the error handling logic in the
CmdRes
class to ensure it behaves as expected for the new error codes introduced. - Consider adding comments or documentation to explain the purpose and usage of the new constants, flags, and error codes to improve code understandability.
- Conduct thorough testing to ensure the correctness and stability of the modified code.
Remember, a thorough code review requires a comprehensive understanding of the entire codebase, its requirements, and its objectives. Therefore, consider seeking feedback from domain experts or experienced developers who are familiar with the project to obtain a more nuanced and informed review.
src/pika_server.cc
Outdated
std::shared_lock l(dbs_rw_, std::defer_lock); | ||
// TODO improve and find other deadlock | ||
if (!lua_calling_) { | ||
l.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在执行EVAL的时候会拿dbs_rw_
写锁,然后如果redis.call执行某个命令调用的函数也需要拿这个锁的话, 就会死锁, 加了这个检查, 各位可以看看哪些命令需要进入的函数还可能拿锁
目前实现的功能已经跑过单测,具体在 |
# Set it to 0 or a negative value for unlimited execution without warnings. | ||
lua-time-limit : 5000 | ||
|
||
|
||
# The [password of administrator], which is empty by default. | ||
# [NOTICE] If this admin password is the same as user password (including both being empty), | ||
# the value of userpass will be ignored and all users are considered as administrators, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code patch you provided appears to be modifying a configuration file for Redis. Here is a brief review of the changes made:
- A new configuration parameter
lua-time-limit
has been added with a value of5000
. This parameter sets the maximum execution time (in milliseconds) for Lua scripts in Redis.
Improvement suggestions:
-
It is generally a good practice to include comments that explain the purpose and usage of each configuration parameter. You may consider adding comments describing the functionality of
lua-time-limit
and its recommended values. -
It's important to carefully choose the value for
lua-time-limit
based on your specific requirements and workload. Consider evaluating the average execution time of your Lua scripts and setting a value that allows sufficient time for them to complete without causing timeouts.
Bug risks:
Without additional context or access to the entire codebase, it is difficult to identify other bugs or issues. A code review typically involves examining the code logic, error handling, security considerations, and performance optimizations. If you have specific concerns or need assistance with a particular section of code, please provide more information.
@@ -73,6 +74,8 @@ class PikaClientConn : public net::RedisConn { | |||
|
|||
std::shared_ptr<Cmd> DoCmd(const PikaCmdArgsType& argv, const std::string& opt, | |||
const std::shared_ptr<std::string>& resp_ptr); | |||
std::shared_ptr<Cmd> DoCmdInLua(const PikaCmdArgsType& argv, const std::string& opt, | |||
const std::shared_ptr<std::string>& resp_ptr); | |||
|
|||
void ProcessSlowlog(const PikaCmdArgsType& argv, uint64_t start_us, uint64_t do_duration); | |||
void ProcessMonitor(const PikaCmdArgsType& argv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the code patch you provided, here are some observations and suggestions:
-
In the
PikaClientConn
class:- The
DealMessage
function is currently not implemented (return 0;
). Make sure this function is implemented correctly to handle Redis commands. - The
DoBackgroundTask
andDoExecTask
functions are declared as static but not defined in the provided code. Make sure they are defined appropriately. - The
ExecRedisCmdInLua
function is declared but not implemented in the provided code. Implement this function if it's intended to be used. - Consider marking the
IsPubSub()
function as a const member function since it doesn't modify the object's state. - The
GetCurrentTable()
function is modified to be a const member function. This change allows calling the function on const objects ofPikaClientConn
. - It seems that the
SetWriteCompleteCallback
function is missing in the provided code.
- The
-
The
DoCmd
andDoCmdInLua
functions are introduced but not implemented in the provided code. Implement these functions based on your requirements. -
Additional context or code may be necessary to provide a more thorough code review and identify potential bugs or improvements effectively.
Please make sure to complete the missing implementations and consider providing more details if there are other specific concerns or issues in your code.
#1445
目前跑通了执行脚本的过程, 还有细节需要添加。
EVAL命令原理:
将接受到的脚本注册成一个lua里的新函数,拿db写锁住整个pika的读写流程保证原子性,调用新注册的函数运行用户的脚本片段, 函数返回结果会转成字符串传回客户端。
lua环境里有预先注册的
redis.call
函数, 脚本运行redis.call
的时候相当于调用LuaRedisGenericCommand
函数, 从lua里获取参数执行DoCmd
, 由于这个时候可能还有在拿db读锁, 所以加了个检查避免重新拿锁。命令相关逻辑执行完后,将返回结果转成lua类型返回。Fixes: #1445