From c58fa5a4fd33ce11e84623ffaa2393ac6b1a937f Mon Sep 17 00:00:00 2001 From: Binbin Date: Tue, 13 Feb 2024 16:49:01 +0800 Subject: [PATCH 1/2] Remove the restriction that redis-cli --cluster create requires at least 3 master nodes There is no limitation in Redis to create a cluster with 1 or 2 masters, only that it cannot do automatic failover. Remove this restriction and add `are you sure` prompt to prompt the user. This was suggested in #12892. --- src/redis-cli.c | 14 +++++--------- tests/unit/cluster/cli.tcl | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index 13275a826..c6b207f0f 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -6935,17 +6935,13 @@ static int clusterManagerCommandCreate(int argc, char **argv) { int replicas = config.cluster_manager_command.replicas; int masters_count = CLUSTER_MANAGER_MASTERS_COUNT(node_len, replicas); if (masters_count < 3) { - clusterManagerLogErr( - "*** ERROR: Invalid configuration for cluster creation.\n" - "*** Redis Cluster requires at least 3 master nodes.\n" - "*** This is not possible with %d nodes and %d replicas per node.", - node_len, replicas); - clusterManagerLogErr("\n*** At least %d nodes are required.\n", - 3 * (replicas + 1)); - return 0; + int ignore_force = 0; + if (!confirmWithYes("Redis Cluster requires at least 3 master nodes for " + "automatic failover, are you sure?", ignore_force)) + return 0; } clusterManagerLogInfo(">>> Performing hash slots allocation " - "on %d nodes...\n", node_len); + "on %d node(s)...\n", node_len); int interleaved_len = 0, ip_count = 0; clusterManagerNode **interleaved = zcalloc(node_len*sizeof(**interleaved)); char **ips = zcalloc(node_len * sizeof(char*)); diff --git a/tests/unit/cluster/cli.tcl b/tests/unit/cluster/cli.tcl index ce4629ec9..713bb3d01 100644 --- a/tests/unit/cluster/cli.tcl +++ b/tests/unit/cluster/cli.tcl @@ -9,8 +9,35 @@ set ::singledb 1 # cluster creation is complicated with TLS, and the current tests don't really need that coverage tags {tls:skip external:skip cluster} { -# start three servers set base_conf [list cluster-enabled yes cluster-node-timeout 1000] + +start_multiple_servers 3 [list overrides $base_conf] { + test {Create 1 node cluster} { + exec src/redis-cli --cluster-yes --cluster create \ + 127.0.0.1:[srv 0 port] + + wait_for_condition 1000 50 { + [CI 0 cluster_state] eq {ok} + } else { + fail "Cluster doesn't stabilize" + } + } + + test {Create 2 node cluster} { + exec src/redis-cli --cluster-yes --cluster create \ + 127.0.0.1:[srv -1 port] \ + 127.0.0.1:[srv -2 port] + + wait_for_condition 1000 50 { + [CI 1 cluster_state] eq {ok} && + [CI 2 cluster_state] eq {ok} + } else { + fail "Cluster doesn't stabilize" + } + } +} + +# start three servers start_multiple_servers 3 [list overrides $base_conf] { set node1 [srv 0 client] From 72417dc58c5b967cee65550d309eae4ab0881ece Mon Sep 17 00:00:00 2001 From: Binbin Date: Tue, 13 Feb 2024 19:30:18 +0800 Subject: [PATCH 2/2] code review --- src/redis-cli.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index c6b207f0f..1358e16ae 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -6936,8 +6936,10 @@ static int clusterManagerCommandCreate(int argc, char **argv) { int masters_count = CLUSTER_MANAGER_MASTERS_COUNT(node_len, replicas); if (masters_count < 3) { int ignore_force = 0; + clusterManagerLogInfo("Requested to create a cluster with %d masters and " + "%d replicas per master.\n", masters_count, replicas); if (!confirmWithYes("Redis Cluster requires at least 3 master nodes for " - "automatic failover, are you sure?", ignore_force)) + "automatic failover. Are you sure?", ignore_force)) return 0; } clusterManagerLogInfo(">>> Performing hash slots allocation "