Merge 7e1d2ea96f
into 804110a487
This commit is contained in:
commit
d9397b8b05
|
@ -354,11 +354,11 @@ endif
|
|||
|
||||
REDIS_SERVER_NAME=redis-server$(PROG_SUFFIX)
|
||||
REDIS_SENTINEL_NAME=redis-sentinel$(PROG_SUFFIX)
|
||||
REDIS_SERVER_OBJ=threads_mngr.o adlist.o quicklist.o ae.o anet.o dict.o kvstore.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o cluster_legacy.o crc16.o endianconv.o slowlog.o eval.o bio.o rio.o rand.o memtest.o syscheck.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o tracking.o socket.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o resp_parser.o call_reply.o script_lua.o script.o functions.o function_lua.o commands.o strl.o connection.o unix.o logreqres.o
|
||||
REDIS_SERVER_OBJ=threads_mngr.o adlist.o quicklist.o ae.o anet.o dict.o kvstore.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o cluster_legacy.o endianconv.o slowlog.o eval.o bio.o rio.o rand.o memtest.o syscheck.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o tracking.o socket.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o resp_parser.o call_reply.o script_lua.o script.o functions.o function_lua.o commands.o strl.o connection.o unix.o logreqres.o
|
||||
REDIS_CLI_NAME=redis-cli$(PROG_SUFFIX)
|
||||
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o redisassert.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o strl.o cli_commands.o
|
||||
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o redisassert.o crcspeed.o crc64.o siphash.o monotonic.o cli_common.o mt19937-64.o strl.o cli_commands.o
|
||||
REDIS_BENCHMARK_NAME=redis-benchmark$(PROG_SUFFIX)
|
||||
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o redisassert.o release.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o strl.o
|
||||
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o redisassert.o release.o crcspeed.o crc64.o siphash.o monotonic.o cli_common.o mt19937-64.o strl.o
|
||||
REDIS_CHECK_RDB_NAME=redis-check-rdb$(PROG_SUFFIX)
|
||||
REDIS_CHECK_AOF_NAME=redis-check-aof$(PROG_SUFFIX)
|
||||
ALL_SOURCES=$(sort $(patsubst %.o,%.c,$(REDIS_SERVER_OBJ) $(REDIS_CLI_OBJ) $(REDIS_BENCHMARK_OBJ)))
|
||||
|
|
|
@ -21,33 +21,6 @@
|
|||
* Key space handling
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/* We have 16384 hash slots. The hash slot of a given key is obtained
|
||||
* as the least significant 14 bits of the crc16 of the key.
|
||||
*
|
||||
* However, if the key contains the {...} pattern, only the part between
|
||||
* { and } is hashed. This may be useful in the future to force certain
|
||||
* keys to be in the same node (assuming no resharding is in progress). */
|
||||
unsigned int keyHashSlot(char *key, int keylen) {
|
||||
int s, e; /* start-end indexes of { and } */
|
||||
|
||||
for (s = 0; s < keylen; s++)
|
||||
if (key[s] == '{') break;
|
||||
|
||||
/* No '{' ? Hash the whole key. This is the base case. */
|
||||
if (s == keylen) return crc16(key,keylen) & 0x3FFF;
|
||||
|
||||
/* '{' found? Check if we have the corresponding '}'. */
|
||||
for (e = s+1; e < keylen; e++)
|
||||
if (key[e] == '}') break;
|
||||
|
||||
/* No '}' or nothing between {} ? Hash the whole key. */
|
||||
if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF;
|
||||
|
||||
/* If we are here there is both a { and a } on its right. Hash
|
||||
* what is in the middle between { and }. */
|
||||
return crc16(key+s+1,e-s-1) & 0x3FFF;
|
||||
}
|
||||
|
||||
/* If it can be inferred that the given glob-style pattern, as implemented in
|
||||
* stringmatchlen() in util.c, only can match keys belonging to a single slot,
|
||||
* that slot is returned. Otherwise -1 is returned. */
|
||||
|
@ -969,7 +942,7 @@ 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, int *error_code) {
|
||||
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *error_code, uint64_t cmd_flags) {
|
||||
clusterNode *myself = getMyClusterNode();
|
||||
clusterNode *n = NULL;
|
||||
robj *firstkey = NULL;
|
||||
|
@ -1101,7 +1074,6 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
|||
* without redirections or errors in all the cases. */
|
||||
if (n == NULL) return myself;
|
||||
|
||||
uint64_t cmd_flags = getCommandFlags(c);
|
||||
/* Cluster is globally down but we got keys? We only serve the request
|
||||
* if it is a read command and when allow_reads_when_down is enabled. */
|
||||
if (!isClusterHealthy()) {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef __CLUSTER_H
|
||||
#define __CLUSTER_H
|
||||
|
||||
#include "crc16.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Redis cluster exported API.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
@ -33,6 +35,34 @@ struct clusterState;
|
|||
#define CLUSTER_MODULE_FLAG_NO_REDIRECTION (1<<2)
|
||||
|
||||
/* ---------------------- API exported outside cluster.c -------------------- */
|
||||
|
||||
/* We have 16384 hash slots. The hash slot of a given key is obtained
|
||||
* as the least significant 14 bits of the crc16 of the key.
|
||||
*
|
||||
* However, if the key contains the {...} pattern, only the part between
|
||||
* { and } is hashed. This may be useful in the future to force certain
|
||||
* keys to be in the same node (assuming no resharding is in progress). */
|
||||
static inline unsigned int keyHashSlot(char *key, int keylen) {
|
||||
int s, e; /* start-end indexes of { and } */
|
||||
|
||||
for (s = 0; s < keylen; s++)
|
||||
if (key[s] == '{') break;
|
||||
|
||||
/* No '{' ? Hash the whole key. This is the base case. */
|
||||
if (likely(s == keylen)) return crc16(key,keylen) & 0x3FFF;
|
||||
|
||||
/* '{' found? Check if we have the corresponding '}'. */
|
||||
for (e = s+1; e < keylen; e++)
|
||||
if (key[e] == '}') break;
|
||||
|
||||
/* No '}' or nothing between {} ? Hash the whole key. */
|
||||
if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF;
|
||||
|
||||
/* If we are here there is both a { and a } on its right. Hash
|
||||
* what is in the middle between { and }. */
|
||||
return crc16(key+s+1,e-s-1) & 0x3FFF;
|
||||
}
|
||||
|
||||
/* functions requiring mechanism specific implementations */
|
||||
void clusterInit(void);
|
||||
void clusterInitLast(void);
|
||||
|
@ -105,11 +135,10 @@ long long clusterNodeReplOffset(clusterNode *node);
|
|||
clusterNode *clusterLookupNode(const char *name, int length);
|
||||
|
||||
/* functions with shared implementations */
|
||||
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *ask);
|
||||
clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *ask, uint64_t cmd_flags);
|
||||
int clusterRedirectBlockedClientIfNeeded(client *c);
|
||||
void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_code);
|
||||
void migrateCloseTimedoutSockets(void);
|
||||
unsigned int keyHashSlot(char *key, int keylen);
|
||||
int patternHashSlot(char *pattern, int length);
|
||||
int isValidAuxString(char *s, unsigned int length);
|
||||
void migrateCommand(client *c);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "server.h"
|
||||
#ifndef CRC16_H
|
||||
#define CRC16_H
|
||||
|
||||
/*
|
||||
* Copyright 2001-2010 Georges Menie (www.menie.org)
|
||||
|
@ -79,10 +80,11 @@ static const uint16_t crc16tab[256]= {
|
|||
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
|
||||
};
|
||||
|
||||
uint16_t crc16(const char *buf, int len) {
|
||||
int counter;
|
||||
static inline uint16_t crc16(const char *buf, int len) {
|
||||
uint16_t crc = 0;
|
||||
for (counter = 0; counter < len; counter++)
|
||||
for (int counter = 0; counter < len; counter++)
|
||||
crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF];
|
||||
return crc;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6497,7 +6497,8 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
|
|||
/* Duplicate relevant flags in the module client. */
|
||||
c->flags &= ~(CLIENT_READONLY|CLIENT_ASKING);
|
||||
c->flags |= ctx->client->flags & (CLIENT_READONLY|CLIENT_ASKING);
|
||||
if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,&error_code) !=
|
||||
const uint64_t cmd_flags = getCommandFlags(c);
|
||||
if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,&error_code, cmd_flags) !=
|
||||
getMyClusterNode())
|
||||
{
|
||||
sds msg = NULL;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
|
||||
#include "fmacros.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -43,6 +42,7 @@
|
|||
#include "cli_common.h"
|
||||
#include "mt19937-64.h"
|
||||
#include "cli_commands.h"
|
||||
#include "crc16.h"
|
||||
|
||||
#define UNUSED(V) ((void) V)
|
||||
|
||||
|
@ -279,8 +279,6 @@ size_t redis_strlcpy(char *dst, const char *src, size_t dsize);
|
|||
|
||||
static void cliPushHandler(void *, void *);
|
||||
|
||||
uint16_t crc16(const char *buf, int len);
|
||||
|
||||
static long long ustime(void) {
|
||||
struct timeval tv;
|
||||
long long ust;
|
||||
|
|
|
@ -470,8 +470,9 @@ static int scriptVerifyClusterState(scriptRunCtx *run_ctx, client *c, client *or
|
|||
/* Duplicate relevant flags in the script client. */
|
||||
c->flags &= ~(CLIENT_READONLY | CLIENT_ASKING);
|
||||
c->flags |= original_c->flags & (CLIENT_READONLY | CLIENT_ASKING);
|
||||
const uint64_t cmd_flags = getCommandFlags(c);
|
||||
int hashslot = -1;
|
||||
if (getNodeByQuery(c, c->cmd, c->argv, c->argc, &hashslot, &error_code) != getMyClusterNode()) {
|
||||
if (getNodeByQuery(c, c->cmd, c->argv, c->argc, &hashslot, &error_code, cmd_flags) != getMyClusterNode()) {
|
||||
if (error_code == CLUSTER_REDIR_DOWN_RO_STATE) {
|
||||
*err = sdsnew(
|
||||
"Script attempted to execute a write command while the "
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "syscheck.h"
|
||||
#include "threads_mngr.h"
|
||||
#include "fmtargs.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
|
@ -3927,7 +3926,7 @@ int processCommand(client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t cmd_flags = getCommandFlags(c);
|
||||
const uint64_t cmd_flags = getCommandFlags(c);
|
||||
|
||||
int is_read_command = (cmd_flags & CMD_READONLY) ||
|
||||
(c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_READONLY));
|
||||
|
@ -3982,7 +3981,7 @@ int processCommand(client *c) {
|
|||
{
|
||||
int error_code;
|
||||
clusterNode *n = getNodeByQuery(c,c->cmd,c->argv,c->argc,
|
||||
&c->slot,&error_code);
|
||||
&c->slot,&error_code, cmd_flags);
|
||||
if (n == NULL || !clusterNodeIsMyself(n)) {
|
||||
if (c->cmd->proc == execCommand) {
|
||||
discardTransaction(c);
|
||||
|
|
|
@ -3353,7 +3353,6 @@ int bzmpopGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResult
|
|||
int setGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResult *result);
|
||||
int bitfieldGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResult *result);
|
||||
|
||||
unsigned short crc16(const char *buf, int len);
|
||||
|
||||
/* Sentinel */
|
||||
void initSentinelConfig(void);
|
||||
|
|
Loading…
Reference in New Issue