Based on spec, I understand that we need minimum of three Redis nodes(instances) to be able to use Redis Cluster. However due to some constraints, I need to be able to run Redis Cluster on a single node and then scale to three later at which point each instance runs on each single node.

Is there a configuration in Redis to be able to accomplish that. If not which places in the source code can be modified to accomplish this. So that we can modify and use it for our purposes.

One thing that I thought of is Running in none cluster mode initially and changing to cluster mode during scale out operation. However I noticed that once cluster mode is disabled, we need a re-start to enable cluster mode.

Comment From: madolson

You need a minimum of 3 nodes to get high availability in Redis cluster, running a single node is OK, you just won't get automatic failover. I presume it doesn't matter much in your case, since you have no extra nodes anyway, so there is no one to failover to.

I would suggest going ahead with the single node and doing the transition ASAP, so you can get the high availability functionality.

Comment From: vineelyalamarthy

@madolson But the problem is it has zero slots when we start with single node and cluster status is always fail. Is there a way I can change in the source this small part for our use case?

Comment From: uvletter

try cluster addslots or cluster addslotsrange to assign slots to the node before the first use, if i memorize the commands correctly

Comment From: vineelyalamarthy

@uvletter @madolson @antirez Right, but is there a way to change it in source only and use that binary. Can some point out relevant code, so I can try to modify and build a binary.

Comment From: uvletter

Perhaps I don't grasp your point,do you intend that the node primitively owns all slots as a default behavior? But what if you want to let a new node join a existed cluster, the node with all slots would conflict with cluster as any slot can only be hold by exactly only one node. Maybe you just want to use Redis cluster out of box or with some simple configurations, but afaik the only way to claim or change slot is by cluster series commands.

Comment From: vineelyalamarthy

@uvletter I meant that single instance of pod with cluster-enabled=true should have all 16384 slots by default and when I scale out, I can migrate the slots.
Can I please get some insights on source code that deals with this. So that I can change it and try.

Comment From: madolson

@vineelyalamarthy I would recommend you just have some setup script that calls CLUSTER ADDSLOTSRANGE 0 16383 on startup.

Comment From: madolson

Otherwise, please consider calling this function https://github.com/redis/redis/blob/b414605285244c453f3fadbbe7a157cd83ed5f59/src/cluster.c#L61 for all of the slots.

Comment From: vineelyalamarthy

@madolson where in the code are they checking for minimum three nodes and then only we distribute the slots. Where is that enforced.

Comment From: madolson

@vineelyalamarthy It's not enforced.

Comment From: douddle

I will be interested by this feature for test purposes. it would be great to group 'CLUSTER ADDSLOTSRANGE 0 16383' command and options '--cluster-enabled yes', '--cluster-require-full-coverage no' in one single option in docker images.

Comment From: douddle

Like '--single-node-cluster'

Comment From: rafajunio

Well, for those that uses docker. Its easy to solve this issue. - redis.conf:

port 6000
cluster-enabled yes
cluster-config-file nodes-6000.conf
cluster-node-timeout 5000
logfile redis-log-6000
protected-mode no
pidfile /var/run/redis-6000.pid
dbfilename dump-6000.rdb
  • cluster_conf.sh
#!env /bin/sh

# Remove old config (dump-600*, redis-log-600*, nodes-600*)
rm -rf /data/*

# check if redis node in port $1 is up
ping_node() {
  result=$(redis-cli -p $1 ping | grep 'PONG')
  echo "$result"
}

# wait redis node to be live in port $1
wait_node() {
  live='NOT_LIVE'
  while [[ ${live} != 'PONG' ]]; do live=$(ping_node $1); done
}

# setup cluster with three node
setup_cluster() {
  echo 'Setup cluster...'
  wait_node 6002
  wait_node 6001
  wait_node 6000
  MY_IP=$(ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
  echo "My ip: $MY_IP"
  redis-cli -p 6000 --cluster create \
    $MY_IP:6000 $MY_IP:6001 $MY_IP:6002 \
    --cluster-replicas 0 --cluster-yes
  sleep 3
  touch /redis/healthcheck.txt
}

# create node 1
echo 'Setup node 1'
cp /redis/redis.conf /redis/redis-6000.conf
redis-server /redis/redis-6000.conf &

# create node 2
echo 'Setup node 2'
cp /redis/redis.conf /redis/redis-6001.conf
sed -i 's/6000/6001/g' /redis/redis-6001.conf
redis-server /redis/redis-6001.conf &

# create node 3
echo 'Setup node 3'
cp /redis/redis.conf /redis/redis-6002.conf
sed -i 's/6000/6002/g' /redis/redis-6002.conf
redis-server /redis/redis-6002.conf
  • docker-compose.yml
version '3.8'

services:
  redis_cluster:
    image: redis:7.0-alpine
    ports:
      - 6000:6000
    volumes:
      - redis_vol:/data
      - ./redis.conf:/redis/redis.conf
      - ./cluster_conf.sh:/redis/cluster_conf.sh
    command: sh /redis/cluster_conf.sh
    healthcheck:
      test: test -f /redis/healthcheck.txt
      interval: 2s
      timeout: 3s
      retries: 50
    restart: always
    mem_limit: '2g'
    mem_reservation: '512m'
    cpus: '3'

volumes:
  redis_vol:
    name: redis_cluster

To use: $ docker compose up