forked from redis/redis
-
Notifications
You must be signed in to change notification settings - Fork 2
Lookahead pre-fetching #413
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
Open
sundb
wants to merge
76
commits into
unstable
Choose a base branch
from
command-lookahead-prefetch
base: unstable
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
76 commits
Select commit
Hold shift + click to select a range
3e2e1ba
lookahead
sundb 2481632
Fix complain
sundb 742cb79
Revert code in processInputBuffer to avoid too many conflicts
sundb e0ff33a
Rename CLIENT_IN_PREFETCH to CLIENT_IN_MEMORY_PREFETCH
sundb 77d7c5b
no longer use flags instead of read_error for pendingCommand
sundb 4de9dd9
Update comment
sundb 2094895
Remove unused code
sundb 1222287
Remove unused code
sundb 682b40a
Rename methods
sundb bcfcf93
Refine
sundb 13dd132
Fix the issue that read_error wasn't handled correctly with io thread
sundb 7bffad2
Remove consumePendingCommand()
sundb 60be3f4
Fix mistake comment out
sundb 16d2682
Move the calucation of lookahead outside of if
sundb f080aa6
Avoid the client calling the shutdownCommand again after unblocking a…
sundb 1888ca1
Reset client for blocked shutdown client
sundb 61d639a
Fix race condition for DefaultUser->flags
sundb 77c2b72
Make user->flags atomic
sundb 59ed640
Revert strchr()
sundb ed08a67
Add update_slot_stats argument to update cluster slot stats for prepa…
sundb 4dd99d4
call clusterSlotStatsAddNetworkBytesInForUserClient() before resetCli…
sundb 8cfae3f
use the slot from preprocess() in getNodeByQuery()
sundb 5c9460a
add CLIENT_READ_CROSS_SLOT for isClientReadErrorFatal()
sundb 02ede13
add CLIENT_READ_CROSS_SLOT for isClientReadErrorFatal()
sundb d205048
simplify the using of isClientReadErrorFatal()
sundb 3911dc1
cache the key result int pending command
sundb 7f8aabf
Smoking test
sundb 2b01213
Fix client not being properly reset after shutdown cancellation
sundb c1ebab3
Cleanup
sundb 4e6a357
Fix unnecessary memory prefetch when iothread is disabled
sundb 0250415
Use cached getKeysResult for other places
sundb 47a20c4
Update outdated comment
sundb 3687e98
Merge remote-tracking branch 'origin/fix-unblock-shutdown' into comma…
sundb 1ad4005
Change the way to get getKeysResult in preprocess()
sundb c046a62
delay the execution of preprocessCommand if possible
sundb 5d69e99
Merge remote-tracking branch 'origin/unstable' into command-lookahead…
sundb a636e93
Remove unnecessary changes
sundb 423cc20
Set pcmd->flags to 0 after calling command filter
sundb 2f99832
Update src/server.h
sundb 07e3ab5
Update src/server.h
sundb 3cc52a6
spell
sundb 04e383b
Merge remote-tracking branch 'origin/unstable' into command-lookahead…
sundb c5defde
Skip CLIENT_UNBLOCKED client for processInputBuffer()
sundb 894938c
Remove unused code
sundb 56a71bc
Fix wrongly last_cmd in preprocessCommand()
sundb ce3eb45
Add pending command pool
sundb 199510b
Free pending command pool if idle for 2 secs
sundb e3cf556
Change the client's pending command pool to global pending command pool
sundb 4e99598
Update comment
sundb efe3a39
Refine comment
sundb c547e8c
Incr the max size of pendimg command pool, and shrink it regular
sundb 1d8c292
Simplify the code
sundb 1cb020a
indentation
sundb 2255dda
Merge remote-tracking branch 'origin/unstable' into command-lookahead…
sundb 45d3cd4
code style
sundb 7ca5db7
Defensively prevent the cmd pool from shrinking too small
sundb a0674a1
Apply suggestion from @ShooterIT
sundb a5eee02
Apply suggestion from @ShooterIT
sundb b97101d
Apply suggestion from @ShooterIT
sundb 8984656
Avoid partial prefetch and incr client if success
sundb 3f1c108
Fix the missing of handing the CLIENT_READ_CROSS_SLOT read error
sundb 0c8c77c
Update src/networking.c
sundb 6d34543
defer releasing pending command
sundb e6f606c
Refine
sundb 8f7041e
Add comment
sundb f7c8e38
Add test for CROSSSLOT Keys
sundb a538c22
Add test for the expansion and shrinking of pending command pool
sundb b92cce8
Fix spell and test failure
sundb 46850c2
Merge remote-tracking branch 'origin/unstable' into command-lookahead…
sundb 0779f1f
eliminate CLIENT_IN_MEMORY_PREFETCH
sundb 1804bbc
General deferred free object
sundb 7b976d8
Fix wrongly c->deferred_objects_num++
sundb f156460
unnecessary change
sundb 6a5d7eb
code style
sundb 0d34e6a
Rename freeClientDeferredObject to freeDeferredObject to avoid confusion
sundb 1a874f1
code review
sundb File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1086,6 +1086,31 @@ void clusterCommand(client *c) { | |
} | ||
} | ||
|
||
/* Extract slot number from keys in a keys_result structure and return to caller. | ||
* Returns INVALID_CLUSTER_SLOT if keys belong to different slots (cross-slot error), | ||
* or if there are no keys. | ||
*/ | ||
int extractSlotFromKeysResult(robj **argv, getKeysResult *keys_result) { | ||
if (keys_result->numkeys == 0) | ||
return INVALID_CLUSTER_SLOT; | ||
|
||
if (!server.cluster_enabled) | ||
return 0; | ||
|
||
int first_slot = INVALID_CLUSTER_SLOT; | ||
for (int j = 0; j < keys_result->numkeys; j++) { | ||
robj *this_key = argv[keys_result->keys[j].pos]; | ||
int this_slot = (int)keyHashSlot((char*)this_key->ptr, sdslen(this_key->ptr)); | ||
|
||
if (first_slot == INVALID_CLUSTER_SLOT) | ||
first_slot = this_slot; | ||
else if (first_slot != this_slot) { | ||
return INVALID_CLUSTER_SLOT; | ||
} | ||
} | ||
return first_slot; | ||
} | ||
|
||
/* Return the pointer to the cluster node that is able to serve the command. | ||
* For the function to succeed the command should only target either: | ||
* | ||
|
@@ -1118,13 +1143,16 @@ void clusterCommand(client *c) { | |
* | ||
* CLUSTER_REDIR_DOWN_STATE and CLUSTER_REDIR_DOWN_RO_STATE if the cluster is | ||
* down but the user attempts to execute a command that addresses one or more keys. */ | ||
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, uint64_t cmd_flags, int *error_code) { | ||
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, | ||
getKeysResult *keys_result, uint8_t read_error, uint64_t cmd_flags, int *error_code) | ||
{ | ||
clusterNode *myself = getMyClusterNode(); | ||
clusterNode *n = NULL; | ||
robj *firstkey = NULL; | ||
int multiple_keys = 0; | ||
multiState *ms, _ms; | ||
multiCmd mc; | ||
pendingCommand mc; | ||
pendingCommand *mcp = &mc; | ||
Comment on lines
+1154
to
+1155
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't see that we're using the pre-calculated slot number. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done with 8cfae3f |
||
int i, slot = 0, migrating_slot = 0, importing_slot = 0, missing_keys = 0, | ||
existing_keys = 0; | ||
int pubsubshard_included = 0; /* Flag to indicate if a pubsub shard cmd is included. */ | ||
|
@@ -1152,24 +1180,35 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in | |
* structure if the client is not in MULTI/EXEC state, this way | ||
* we have a single codepath below. */ | ||
ms = &_ms; | ||
_ms.commands = &mc; | ||
_ms.commands = &mcp; | ||
_ms.count = 1; | ||
|
||
/* Properly initialize the fake pendingCommand */ | ||
initPendingCommand(&mc); | ||
mc.argv = argv; | ||
mc.argc = argc; | ||
mc.cmd = cmd; | ||
mc.slot = hashslot ? *hashslot : INVALID_CLUSTER_SLOT; | ||
mc.read_error = read_error; | ||
if (keys_result) { | ||
mc.keys_result = *keys_result; | ||
mc.flags |= PENDING_CMD_KEYS_RESULT_VALID; | ||
} | ||
} | ||
|
||
/* Check that all the keys are in the same hash slot, and obtain this | ||
* slot and the node associated. */ | ||
for (i = 0; i < ms->count; i++) { | ||
struct redisCommand *mcmd; | ||
robj **margv; | ||
int margc, numkeys, j; | ||
int margc, j; | ||
keyReference *keyindex; | ||
|
||
mcmd = ms->commands[i].cmd; | ||
margc = ms->commands[i].argc; | ||
margv = ms->commands[i].argv; | ||
pendingCommand *pcmd = ms->commands[i]; | ||
|
||
mcmd = pcmd->cmd; | ||
margc = pcmd->argc; | ||
margv = pcmd->argv; | ||
|
||
/* Only valid for sharded pubsub as regular pubsub can operate on any node and bypasses this layer. */ | ||
if (!pubsubshard_included && | ||
|
@@ -1178,14 +1217,29 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in | |
pubsubshard_included = 1; | ||
} | ||
|
||
/* If we have a cached keys result from preprocessCommand(), use it. | ||
* Otherwise, extract keys result. */ | ||
int use_cache_keys_result = pcmd->flags & PENDING_CMD_KEYS_RESULT_VALID; | ||
getKeysResult result = GETKEYS_RESULT_INIT; | ||
numkeys = getKeysFromCommand(mcmd,margv,margc,&result); | ||
if (use_cache_keys_result) | ||
result = pcmd->keys_result; | ||
else | ||
getKeysFromCommand(mcmd,margv,margc,&result); | ||
keyindex = result.keys; | ||
|
||
for (j = 0; j < numkeys; j++) { | ||
for (j = 0; j < result.numkeys; j++) { | ||
/* The command has keys and was checked for cross-slot between its keys in preprocessCommand() */ | ||
if (pcmd->read_error == CLIENT_READ_CROSS_SLOT) { | ||
/* Error: multiple keys from different slots. */ | ||
if (error_code) | ||
*error_code = CLUSTER_REDIR_CROSS_SLOT; | ||
return NULL; | ||
} | ||
|
||
robj *thiskey = margv[keyindex[j].pos]; | ||
int thisslot = keyHashSlot((char*)thiskey->ptr, | ||
sdslen(thiskey->ptr)); | ||
int thisslot = pcmd->slot; | ||
if (thisslot == INVALID_CLUSTER_SLOT) | ||
thisslot = keyHashSlot((char*)thiskey->ptr, sdslen(thiskey->ptr)); | ||
|
||
if (firstkey == NULL) { | ||
/* This is the first key we see. Check what is the slot | ||
|
@@ -1199,7 +1253,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in | |
* not trapped earlier in processCommand(). Report the same | ||
* error to the client. */ | ||
if (n == NULL) { | ||
getKeysFreeResult(&result); | ||
if (!use_cache_keys_result) getKeysFreeResult(&result); | ||
if (error_code) | ||
*error_code = CLUSTER_REDIR_DOWN_UNBOUND; | ||
return NULL; | ||
|
@@ -1222,7 +1276,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in | |
* the same key/channel as the first we saw. */ | ||
if (slot != thisslot) { | ||
/* Error: multiple keys from different slots. */ | ||
getKeysFreeResult(&result); | ||
if (!use_cache_keys_result) getKeysFreeResult(&result); | ||
if (error_code) | ||
*error_code = CLUSTER_REDIR_CROSS_SLOT; | ||
return NULL; | ||
|
@@ -1247,7 +1301,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in | |
else existing_keys++; | ||
} | ||
} | ||
getKeysFreeResult(&result); | ||
if (!use_cache_keys_result) getKeysFreeResult(&result); | ||
} | ||
|
||
/* No key at all in command? then we can serve the request | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 have two concerns that i'd like you to look into: