summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadelyn Olson <matolson@amazon.com>2019-05-30 11:50:31 -0700
committerMadelyn Olson <matolson@amazon.com>2019-12-16 23:33:16 -0800
commitc95a582a749a83b117bdd51f4a7a29a616a0bf3c (patch)
tree3abe10c1373dd06bada31b717e57ed207b3d2113
parente9b99c78dfd338ecf3c5b7b69318c10ce9dead03 (diff)
downloadredis-c95a582a749a83b117bdd51f4a7a29a616a0bf3c.tar.gz
Add configuration option for allowing reads on cluster down
-rw-r--r--redis.conf16
-rw-r--r--src/cluster.c13
-rw-r--r--src/config.c2
-rw-r--r--src/server.h2
4 files changed, 30 insertions, 3 deletions
diff --git a/redis.conf b/redis.conf
index d37760176..870849a79 100644
--- a/redis.conf
+++ b/redis.conf
@@ -1194,6 +1194,22 @@ lua-time-limit 5000
#
# cluster-replica-no-failover no
+# This option, when set to yes, allows nodes to serve read traffic while the
+# the cluster is in a down state, as long as it believes it owns the slots.
+#
+# This is useful for two cases. The first case is for when an application
+# doesn't require consistency of data during node failures or network partitions.
+# One example of this is a cache, where as long as the node has the data it
+# should be able to serve it.
+#
+# The second use case is for configurations that don't meet the recommended
+# three shards but want to enable cluster mode and scale later. A
+# master outage in a 1 or 2 shard configuration causes a read/write outage to the
+# entire cluster without this option set, with it set there is only a write outage.
+# Without a quorum of masters, slot ownership will not change automatically.
+#
+# cluster-allow-reads-when-down no
+
# In order to setup your cluster make sure to read the documentation
# available at http://redis.io web site.
diff --git a/src/cluster.c b/src/cluster.c
index 9e6ddb2c4..4024035e9 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -5595,8 +5595,12 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
* without redirections or errors in all the cases. */
if (n == NULL) return myself;
- /* Cluster is globally down but we got keys? We can't serve the request. */
- if (server.cluster->state != CLUSTER_OK) {
+ /* 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 ((server.cluster->state != CLUSTER_OK) &&
+ !(server.cluster_allow_reads_when_down && ((cmd->flags & CMD_READONLY)
+ || (cmd->proc == evalCommand) || (cmd->proc == evalShaCommand))))
+ {
if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE;
return NULL;
}
@@ -5701,7 +5705,10 @@ int clusterRedirectBlockedClientIfNeeded(client *c) {
dictEntry *de;
dictIterator *di;
- /* If the cluster is down, unblock the client with the right error. */
+ /* If the cluster is down, unblock the client with the right error.
+ * If the cluster is configured to allow reads on cluster down, we
+ * still want to emit this error since a write will be required
+ * to unblock them which may never come. */
if (server.cluster->state == CLUSTER_FAIL) {
clusterRedirectClient(c,NULL,0,CLUSTER_REDIR_DOWN_STATE);
return 1;
diff --git a/src/config.c b/src/config.c
index 5bfb0de5c..5ff333fec 100644
--- a/src/config.c
+++ b/src/config.c
@@ -2166,6 +2166,8 @@ standardConfig configs[] = {
createBoolConfig("syslog-enabled", NULL, IMMUTABLE_CONFIG, server.syslog_enabled, 0, NULL, NULL),
createBoolConfig("cluster-enabled", NULL, IMMUTABLE_CONFIG, server.cluster_enabled, 0, NULL, NULL),
createBoolConfig("appendonly", NULL, MODIFIABLE_CONFIG, server.aof_enabled, 0, NULL, updateAppendonly),
+ createBoolConfig("cluster-allow-reads-when-down", NULL, MODIFIABLE_CONFIG, server.cluster_allow_reads_when_down, 0, NULL, NULL},
+
/* String Configs */
createStringConfig("aclfile", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.acl_filename, "", NULL, NULL),
diff --git a/src/server.h b/src/server.h
index f2c93241c..b5e51002b 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1334,6 +1334,8 @@ struct redisServer {
to set in order to suppress certain
native Redis Cluster features. Check the
REDISMODULE_CLUSTER_FLAG_*. */
+ int cluster_allow_reads_when_down; /* Are reads allowed when the cluster
+ is down? */
/* Scripting */
lua_State *lua; /* The Lua interpreter. We use just one for all clients */
client *lua_client; /* The "fake client" to query Redis from Lua */