Docker quickly builds redis cluster

Time:2020-12-3

What is redis cluster

Redis cluster is a distributed database solution provided by redis. The cluster shares data through sharding, and provides replication and fail over functions.

node

A redis cluster is usually composed of multiple nodes. At the beginning, each node is independent of each other, and they are in a cluster that only contains itself. To build a truly working cluster, we must connect the independent nodes to form a cluster containing multiple nodes.

Redis cluster communication protocol

Gossip [ˈ s ᠬ P] protocol

Gossip protocol uses a random way to spread information to the whole network, and makes the data of all nodes in the system consistent in a certain period of time. In fact, gossip is a decentralized distributed protocol, which can solve two problems: the propagation of state in the cluster and the guarantee of state consistency.

Common distributed consistency algorithms

  • Zab
  • Paxos
  • Raft

Cluster configuration

configuration file

Download configuration file:https://raw.githubusercontent.com/antirez/redis/5.0/redis.conf

Adjust cluster node configuration

#Open cluster
cluster-enabled yes

#Cluster profile
cluster-config-file nodes-6379.conf

#Cluster node timeout
cluster-node-timeout 15000

Docker quickly builds redis cluster

Skip installing redis

preparation

├── conf
│   ├── redis.conf
│   └── sentinel.conf
├── redis
│   ├── data_6379
│   ├── data_6380
│   ├── data_6381
│   ├── data_6382
│   ├── data_6383
│   └── data_6384
└── scripts
    ├── cluster.sh
    ├── run.sh
    └── sentinel.sh

run.sh Script file

#!/usr/bin/env bash
set -e

#Script current directory
cPath=$(cd $(dirname "$0") || exit; pwd)

#Root directory
dirPath=$(dirname "$cPath")

#Get port
port="$1"
if [[ ! "$port" ]]; then
  port=6379
fi

#Create data directory
mkdir -p "$dirPath"/redis/data_"$port"

#Delete started service
containerId=$(docker ps -a | grep "redis_$port" | awk -F' ' '{print $1}')
if [[ "$containerId" ]]; then
    docker rm -f ${containerId} > /dev/null
fi

#Start service
containerName=redis_"$port"
docker run -itd --privileged=true -p "$port":6379 --name ${containerName} \
-v="$dirPath"/conf/redis.conf:/etc/redis/redis.conf \
-v="$dirPath"/redis/data_"$port":/data \
redis \
redis-server /etc/redis/redis.conf > /dev/null

#Get container IP address
dockerIp=$(docker inspect -f "{{.NetworkSettings.IPAddress}}" "$containerName")

#Gets the container startup status
isRunning=$(docker inspect -f "{{.State.Running}}" "$containerName")
if [[ "$isRunning" == "true" ]]; then
    Echo "container: $containername - IP: $dockerip - started successfully"
fi

cluster.sh Script file

#!/usr/bin/env bash
set -e

#Script current directory
cPath=$(cd $(dirname "$0") || exit; pwd)

#Number of clusters started
num="$1"
if [[ ! "$num" ]]; then
  num=6
fi

sPort=6378
for((i=1;i<=$num;i++)); do
    sh ${cPath}/run.sh  $(($sPort+$i))
done

Start service

Execute the script file and create 6 nodes by default

sh scripts/cluster.sh

Script returns results

Container: redis_ 6379 - IP: 172.17.0.2 - boot successful
Container: redis_ 6380 - IP: 172.17.0.3 - boot successful
Container: redis_ 6381 - IP: 172.17.0.4 - boot successful
Container: redis_ 6382 - IP: 172.17.0.5 - boot successful
Container: redis_ 6383 - IP: 172.17.0.6 - boot successful
Container: redis_ 6384 - IP: 172.17.0.7 - boot successful

implementdocker psIs the startup successful

[email protected]:~/docker-config/redis# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
c0601df1a456        redis               "docker-entrypoint.s…"   27 seconds ago      Up 26 seconds       0.0.0.0:6384->6379/tcp   redis_6384
6fecf70465b8        redis               "docker-entrypoint.s…"   27 seconds ago      Up 26 seconds       0.0.0.0:6383->6379/tcp   redis_6383
1af15e90b7a0        redis               "docker-entrypoint.s…"   28 seconds ago      Up 27 seconds       0.0.0.0:6382->6379/tcp   redis_6382
6c495f31a5df        redis               "docker-entrypoint.s…"   28 seconds ago      Up 28 seconds       0.0.0.0:6381->6379/tcp   redis_6381
e54fd9fd0550        redis               "docker-entrypoint.s…"   29 seconds ago      Up 28 seconds       0.0.0.0:6380->6379/tcp   redis_6380
be92ad2f7046        redis               "docker-entrypoint.s…"   29 seconds ago      Up 29 seconds       0.0.0.0:6379->6379/tcp   redis_6379

So far, six independent cluster nodes have been created, and they can not work normally at present.

Create a cluster

You can skip here. I want to save time

Get container asredis_Start all container IP addresses

docker inspect -f "{{.NetworkSettings.IPAddress}}:6379" `docker ps | grep redis_ | awk -F' ' '{print $1}'` | sort |xargs |  sed 's/ /, /g'

#Return results
# 172.17.0.2:6379, 172.17.0.3:6379, 172.17.0.4:6379, 172.17.0.5:6379, 172.17.0.6:6379, 172.17.0.7:6379

Create cluster for the first time

./redis-cli --cluster create 172.17.0.2:6379, 172.17.0.3:6379, 172.17.0.4:6379, 172.17.0.5:6379, 172.17.0.6:6379, 172.17.0.7:6379 --cluster-replicas 1

Output results

licas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.17.0.6:6379 to 172.17.0.2:6379
Adding replica 172.17.0.7:6379 to 172.17.0.3:6379
Adding replica 172.17.0.5:6379 to 172.17.0.4:6379
M: e8da1fef656984de3ec2a677edc8d9c48d01cd95 172.17.0.2:6379
   slots:[0-5460] (5461 slots) master
M: 68b925ab0fbbc1a632c1754587fb6dad3fa14c91 172.17.0.3:6379
   slots:[5461-10922] (5462 slots) master
M: 0a46ab2f6d176738b55fe699c2df1c34f8200d06 172.17.0.4:6379
   slots:[10923-16383] (5461 slots) master
S: bd3064ad5297dfc258e9236943455c589be8b2a3 172.17.0.5:6379
   replicates 0a46ab2f6d176738b55fe699c2df1c34f8200d06
S: f1d8c897882d29e6538b1158525493b3b782289a 172.17.0.6:6379
   replicates e8da1fef656984de3ec2a677edc8d9c48d01cd95
S: 619e1cb52f39e07b321719b77fc3631fa6293cef 172.17.0.7:6379
   replicates 68b925ab0fbbc1a632c1754587fb6dad3fa14c91
Can I set the above configuration? (type 'yes' to accept):

Enter: Yes to allocate slots equally

>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.....
>>> Performing Cluster Check (using node 172.17.0.2:6379)
M: e8da1fef656984de3ec2a677edc8d9c48d01cd95 172.17.0.2:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: f1d8c897882d29e6538b1158525493b3b782289a 172.17.0.6:6379
   slots: (0 slots) slave
   replicates e8da1fef656984de3ec2a677edc8d9c48d01cd95
S: bd3064ad5297dfc258e9236943455c589be8b2a3 172.17.0.5:6379
   slots: (0 slots) slave
   replicates 0a46ab2f6d176738b55fe699c2df1c34f8200d06
M: 0a46ab2f6d176738b55fe699c2df1c34f8200d06 172.17.0.4:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 619e1cb52f39e07b321719b77fc3631fa6293cef 172.17.0.7:6379
   slots: (0 slots) slave
   replicates 68b925ab0fbbc1a632c1754587fb6dad3fa14c91
M: 68b925ab0fbbc1a632c1754587fb6dad3fa14c91 172.17.0.3:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Connect cluster

Connect via client

Redis-cli - C < port >

Execute command:cluster info

127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:104
cluster_stats_messages_pong_sent:120
cluster_stats_messages_sent:224
cluster_stats_messages_ping_received:115
cluster_stats_messages_pong_received:104
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:224

See:cluster_state:okIt indicates that the cluster can work normally

Code example

PHP code example

Stand alone connection

$redis = new \Redis();
$redis->connect("172.28.168.204", 26379);
$servers = $redis->rawCommand('sentinel', 'masters');

Cluster connection

$redis_list = array('172.17.0.2:6379', '172.17.0.3:6379', '172.17.0.4:6379');
$redisCluster = new \RedisCluster(null, $redis_list, 1.5, 1.5);
$redisCluster->set("data_80300_0_", "aaa");

var_dump($redisCluster->get("data_80300_0_"));

Related help

Client console

cluster help

Redis cli cluster help

redis-cli --cluster help

Recommended Today

PHP 12th week function learning record

sha1() effect sha1()Function to evaluate the value of a stringSHA-1Hash. usage sha1(string,raw) case <?php $str = “Hello”; echo sha1($str); ?> result f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0 sha1_file() effect sha1_file()Function calculation fileSHA-1Hash. usage sha1_file(file,raw) case <?php $filename = “test.txt”; $sha1file = sha1_file($filename); echo $sha1file; ?> result aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d similar_text() effect similar_text()Function to calculate the similarity between two strings. usage similar_text(string1,string2,percent) case […]