mirror of
https://github.com/fluencelabs/redis
synced 2025-06-16 10:41:22 +00:00
Use the RSC to replicate EVALSHA unmodified.
This commit uses the Replication Script Cache in order to avoid translating EVALSHA into EVAL whenever possible for both the AOF and slaves.
This commit is contained in:
@ -655,6 +655,10 @@ void scriptingInit(void) {
|
||||
* to global variables. */
|
||||
scriptingEnableGlobalsProtection(lua);
|
||||
|
||||
/* Initialize the Replication Script Cache for EVALSHA propagation to
|
||||
* slaves and AOF. */
|
||||
replicationScriptCacheInit();
|
||||
|
||||
server.lua = lua;
|
||||
}
|
||||
|
||||
@ -931,23 +935,29 @@ void evalGenericCommand(redisClient *c, int evalsha) {
|
||||
luaReplyToRedisReply(c,lua);
|
||||
}
|
||||
|
||||
/* If we have slaves attached we want to replicate this command as
|
||||
* EVAL instead of EVALSHA. We do this also in the AOF as currently there
|
||||
* is no easy way to propagate a command in a different way in the AOF
|
||||
* and in the replication link.
|
||||
/* EVALSHA should be propagated to Slave and AOF file as full EVAL, unless
|
||||
* we are sure that the script was already in the context of all the
|
||||
* attached slaves *and* the current AOF file if enabled.
|
||||
*
|
||||
* IMPROVEMENT POSSIBLE:
|
||||
* 1) Replicate this command as EVALSHA in the AOF.
|
||||
* 2) Remember what slave already received a given script, and replicate
|
||||
* the EVALSHA against this slaves when possible.
|
||||
*/
|
||||
* To do so we use a cache of SHA1s of scripts that we already propagated
|
||||
* as full EVAL, that's called the Replication Script Cache.
|
||||
*
|
||||
* For repliation, everytime a new slave attaches to the master, we need to
|
||||
* flush our cache of scripts that can be replicated as EVALSHA, while
|
||||
* for AOF we need to do so every time we rewrite the AOF file. */
|
||||
if (evalsha) {
|
||||
robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);
|
||||
if (!replicationScriptCacheExists(c->argv[1]->ptr)) {
|
||||
/* This script is not in our script cache, replicate it as
|
||||
* EVAL, then add it into the script cache, as from now on
|
||||
* slaves and AOF know about it. */
|
||||
robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);
|
||||
|
||||
redisAssertWithInfo(c,NULL,script != NULL);
|
||||
rewriteClientCommandArgument(c,0,
|
||||
resetRefCount(createStringObject("EVAL",4)));
|
||||
rewriteClientCommandArgument(c,1,script);
|
||||
replicationScriptCacheAdd(c->argv[1]->ptr);
|
||||
redisAssertWithInfo(c,NULL,script != NULL);
|
||||
rewriteClientCommandArgument(c,0,
|
||||
resetRefCount(createStringObject("EVAL",4)));
|
||||
rewriteClientCommandArgument(c,1,script);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user