-
Notifications
You must be signed in to change notification settings - Fork 677
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
Add new replicate module API to bypass command validation #1357
base: unstable
Are you sure you want to change the base?
Conversation
18763c9
to
c54ba74
Compare
typedef enum { | ||
VALKEYMODULE_FLAG_DEFAULT = 0, /* Default behavior */ | ||
VALKEYMODULE_FLAG_SKIP_VALIDATION, /* Skip validation */ | ||
} ValkeyModuleFlag; |
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.
Can I get some suggestions if this naming is too general
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.
Is there benefit set the flag as enum, more flags later? Can we just use int skip (0 for non-skip, 1 for skip) ?
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.
It's always complicated to have types like this in the module API. I believe we support backward and forward compatiblity for modules. I mean, a module built with the valkeymodule.h from Valkey 10 can run on Valkey 9 and vice versa. A module can check if some function exists in the current server by checking if the function is NULL, like if (ValkeyModule_ReplicateWithFlag != NULL) ...
, but to check which flags are valid in an enum, we don't have a way for modules to check that.
I think Wen's suggestion with an int
is simpler, but an even simpler API is to just add ValkeyModule_ReplicateWithoutValidataion
. WDYT?
Internally, we can use an enum or int, but that's doesn't have to be part of the API.
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.
I think ValkeyModule_ReplicateWithoutValidataion
is also good idea
Signed-off-by: Seungmin Lee <[email protected]>
c54ba74
to
24e6573
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## unstable #1357 +/- ##
============================================
+ Coverage 70.62% 70.77% +0.14%
============================================
Files 117 117
Lines 63313 63324 +11
============================================
+ Hits 44716 44817 +101
+ Misses 18597 18507 -90
|
Open a pr for documentation of this: valkey-io/valkey-doc#192 |
typedef enum { | ||
VALKEYMODULE_FLAG_DEFAULT = 0, /* Default behavior */ | ||
VALKEYMODULE_FLAG_SKIP_VALIDATION, /* Skip validation */ | ||
} ValkeyModuleFlag; |
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.
Is there benefit set the flag as enum, more flags later? Can we just use int skip (0 for non-skip, 1 for skip) ?
@@ -1092,6 +1097,8 @@ VALKEYMODULE_API int (*ValkeyModule_StringToStreamID)(const ValkeyModuleString * | |||
VALKEYMODULE_API void (*ValkeyModule_AutoMemory)(ValkeyModuleCtx *ctx) VALKEYMODULE_ATTR; | |||
VALKEYMODULE_API int (*ValkeyModule_Replicate)(ValkeyModuleCtx *ctx, const char *cmdname, const char *fmt, ...) | |||
VALKEYMODULE_ATTR; | |||
VALKEYMODULE_API int (*ValkeyModule_ReplicateWithFlag)(ValkeyModuleCtx *ctx, ValkeyModuleFlag flag, const char *cmdname, const char *fmt, ...) |
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.
If ValkeyModuleFlag can be set as int, here we can pass int value;
/* Helper function for VM_Replicate and VM_ReplicateWithFlag to replicate the specified command | ||
* and arguments to replicas and AOF, as effect of execution of the calling command implementation. | ||
* Skip command validation if the ValkeyModuleFlag is set to VALKEYMODULE_FLAG_SKIP_VALIDATION. */ | ||
int moduleReplicate(ValkeyModuleCtx *ctx, ValkeyModuleFlag flag, const char *cmdname, const char *fmt, va_list ap) { |
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.
Pls move this function to just above the VM_Replicate, reference the function zsetInitLexRange. It is a helper function too.
The PR comes from a performance issue about current VM_Replicated, then could you pls provide the result how much performance improvement on this PR? |
I don't see notable performance improvement in the multiple tests (1. benchmark 2. CPU utilization, 3. CPU profiling with perf) so I wonder if it is worth introducing this new API. @hwware @hpatro 1. BenchmarkWith validation
Bypass validation
2. CPU utilization
With validation
Bypass validation
3. Performance profiling with
|
@valkey-io/core-team Do you think this is a proper solution? |
I added another CPU utilization test to push around 90% |
Issue #1175
Problem
Performance degradation occurs due to the sanity check(lookupCommandByCString) in the VM_Replicate function, which converts const char* into sds and free them for command dictionary lookup. This check is mainly used for debugging purpose, but it is unnecessary for trusted modules. The user seeks a way to bypass this check for performance gains.
Solution
Adding a module API with flags (preferably enums, e.g., SKIP_VALIDATION) allows trusted modules to bypass validation for performance improvements while retaining flexibility for handling failure scenarios on replicas.
Test
Unit test
Follow-up work
Valkey document update required: https://valkey.io/topics/modules-api-ref/#section-commands-replication-api