单机版

  1. 宿主机创建目录/app/redis
  2. /app/redis下创建文件redis.conf,主要修改以下几项配置
# 开启密码验证(可选)
requirepass 123

# 允许redis外地连接,需要注释掉绑定的IP
# bind 127.0.0.1

# 关闭保护模式(可选)
protected-mode no

# 注释掉daemonize yes,或者配置成 daemonize no。因为该配置和 docker run中的 -d 参数冲突,会导致容器一直启动失败
daemonize no

# 开启redis数据持久化, (可选)
appendonly yes
  1. 启动docker容器:(因为要使用自定义的配置文件,所以需要指定容器运行的命令为redis-server 容器内配置文件路径
docker run -d  -p 6379:6379 --restart=always --name redis --privileged=true \
           -v /app/redis/redis.conf:/etc/redis/redis.conf \
           -v /app/redis/data:/data \
           redis:6.0.8 \
           redis-server /etc/redis/redis.conf  --appendonly yes --requirepass "root123456"

集群版(3主3从)

使用docker搭建3主3从的Redis集群,每台主机都对应一台从机。
启动6台redis容器

# 启动第1台节点
# --net host 使用宿主机的IP和端口,默认
# --cluster-enabled yes 开启redis集群
# --appendonly yes 开启redis持久化
# --port 6381 配置redis端口号
docker run -d --name redis-node-1 --net host --privileged=true -v /app/redis-cluster/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381

# 启动第2台节点
docker run -d --name redis-node-2 --net host --privileged=true -v /app/redis-cluster/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382

# 启动第3台节点
docker run -d --name redis-node-3 --net host --privileged=true -v /app/redis-cluster/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383

# 启动第4台节点
docker run -d --name redis-node-4 --net host --privileged=true -v /app/redis-cluster/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384

# 启动第5台节点
docker run -d --name redis-node-5 --net host --privileged=true -v /app/redis-cluster/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385

# 启动第6台节点
docker run -d --name redis-node-6 --net host --privileged=true -v /app/redis-cluster/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386

构建主从关系:

  1. 进入节点1(或其中任意一个节点):
docker exec -it redis-node-1 /bin/bash
  1. 构建主从关系
# 宿主机IP:端口
redis-cli --cluster create 192.168.xxx.xxx:6381 192.168.xxx.xxx:6382 192.168.xxx.xxx:6383 192.168.xxx.xxx:6384 192.168.xxx.xxx:6385 192.168.xxx.xxx:6386 --cluster-replicas 1
  1.  redis尝试自动进行主从节点分配
  2. 因为我们的docker容器IP相同,所以会出现警告,可以直接忽略该警告 
[WARNING] Some slaves are in the same host as their master
M: f451eb48bbc0a7c31c7da022ffe80cc1696e0f37 192.168.xxx.xxx:6381
   slots:[0-5460] (5461 slots) master
M: 05984211b8c38222a73abeff1d4e459c0fe1efbc 192.168.xxx.xxx:6382
   slots:[5461-10922] (5462 slots) master
M: 1fc935c12b1d34a7df50aed643c195eb29bb3435 192.168.xxx.xxx:6383
   slots:[10923-16383] (5461 slots) master
S: f8d0de47114bf33438747acd713cce4e412ae721 192.168.xxx.xxx:6384
   replicates 1fc935c12b1d34a7df50aed643c195eb29bb3435
S: de0b393c17e452d856f6de2b348e9ca4e5aa4002 192.168.xxx.xxx:6385
   replicates f451eb48bbc0a7c31c7da022ffe80cc1696e0f37
S: 0c0767e13a09ee48541738d4163592cd9842c143 192.168.xxx.xxx:6386
   replicates 05984211b8c38222a73abeff1d4e459c0fe1efbc
Can I set the above configuration? (type 'yes' to accept):
  1. 输入Yes确认后,redis会向其他节点发送信息加入集群,并分配哈希槽:
>>> 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 192.168.xxx.xxx:6381)
M: f451eb48bbc0a7c31c7da022ffe80cc1696e0f37 192.168.xxx.xxx:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 1fc935c12b1d34a7df50aed643c195eb29bb3435 192.168.xxx.xxx:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 05984211b8c38222a73abeff1d4e459c0fe1efbc 192.168.xxx.xxx:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 0c0767e13a09ee48541738d4163592cd9842c143 192.168.xxx.xxx:6386
   slots: (0 slots) slave
   replicates 05984211b8c38222a73abeff1d4e459c0fe1efbc
S: f8d0de47114bf33438747acd713cce4e412ae721 192.168.xxx.xxx:6384
   slots: (0 slots) slave
   replicates 1fc935c12b1d34a7df50aed643c195eb29bb3435
S: de0b393c17e452d856f6de2b348e9ca4e5aa4002 192.168.xxx.xxx:6385
   slots: (0 slots) slave
   replicates f451eb48bbc0a7c31c7da022ffe80cc1696e0f37
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

查看集群状态

1. 进入容器节点1(或集群中其他节点):

docker exec -it redis-node-1 /bin/bash

2. 使用redis-cli连接到6381节点: 

redis-cli -p 6381

3. 使用redis的相关命令查看集群状态:

cluster info

其中,分配的哈希槽数量 cluster_slots_assigned为16384,集群节点数量cluster_known_nodes为6 

4. 查看集群节点信息 

cluster nodes

Redis集群读写出错

当使用 redis-cli连接redis集群时,需要添加 -c参数,否则可能会出现读写出错

示例:

1.进入容器节点

docker exec -it redis-node-1 /bin/bash

2.使用redis-cli连接,不加-c参数时 

redis-cli -p 6381 

3.此时向redis中添加键值对,可能会成功,也可能会失败 

set k1 v1

报错:k1经过计算得到的哈希槽为12706,但是当前连接的redis-server为6381(即节点1),它的哈希槽为:[0,5460](在创建构建主从关系时redis有提示,也可以通过 cluster nodes查看),所以会因为存不进去而报错。 
执行 set k2 v2可以成功,因为k2计算出的哈希槽在[0-5460]区间中。


4. 使用-c参数的redis-cli命令连接即可 

redis-cli -p 6381 -c

5.此时可以正常的插入所有数据

set k1 v1


 集群信息检查

检查查看集群信息:

  1. 进入容器节点1
docker exec -it redis-node-1 /bin/bash
  1. 进行集群信息检查
# 输入任意一台主节点地址都可以进行集群检查
redis-cli --cluster check 192.168.xxx.xxx:6381

返回的检查结果

当前集群中各个节点存储的key的数量
192.168.xxx.xxx:6381 (f451eb48...) -> 0 keys | 5461 slots | 1 slaves.
192.168.xxx.xxx:6383 (1fc935c1...) -> 1 keys | 5461 slots | 1 slaves.
192.168.xxx.xxx:6382 (05984211...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 1 keys in 3 masters.  
0.00 keys per slot on average.

主从机器信息
>>> Performing Cluster Check (using node 192.168.xxx.xxx:6381)
M: f451eb48bbc0a7c31c7da022ffe80cc1696e0f37 192.168.xxx.xxx:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 1fc935c12b1d34a7df50aed643c195eb29bb3435 192.168.xxx.xxx:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 05984211b8c38222a73abeff1d4e459c0fe1efbc 192.168.xxx.xxx:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 0c0767e13a09ee48541738d4163592cd9842c143 192.168.xxx.xxx:6386
   slots: (0 slots) slave
   replicates 05984211b8c38222a73abeff1d4e459c0fe1efbc
S: f8d0de47114bf33438747acd713cce4e412ae721 192.168.xxx.xxx:6384
   slots: (0 slots) slave
   replicates 1fc935c12b1d34a7df50aed643c195eb29bb3435
S: de0b393c17e452d856f6de2b348e9ca4e5aa4002 192.168.xxx.xxx:6385
   slots: (0 slots) slave
   replicates f451eb48bbc0a7c31c7da022ffe80cc1696e0f37
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

主从扩容缩容 


主从扩容

1.启动两台新的节点

# 启动第7台节点 docker run -d --name redis-node-7 --net host --privileged=true -v /app/redis-cluster/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387 # 启动第8台节点 docker run -d --name redis-node-8 --net host --privileged=true -v /app/redis-cluster/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388

2.进入6387(节点7)容器内部 

docker exec -it redis-node-7 /bin/bash

3.将6387作为master加入集群

# redis-cli --cluster add-node 本节点地址 要加入的集群中的其中一个节点地址 redis-cli --cluster add-node 192.168.xxx.xxx:6387 192.168.xxx.xxx:6381

4.检查当前集群状态

redis-cli --cluster check 192.168.xxx.xxx:6381

可以发现,6371节点已经作为master加入了集群,但是该节点没有被分配槽位。

5.重新分配集群的槽位

redis-cli --cluster reshard 192.168.xxx.xxx:6381

redis经过槽位检查后,会提示需要分配的槽位数量:
例如,我们现在是4台master,我们想要给node7分配4096个槽位,这样每个节点都是4096个槽位。
输入4096后,会让输入要接收这些哈希槽的节点ID,填入node7的节点ID即可。(就是节点信息中很长的一串十六进制串)。
然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node7。一般选择 all,即将之前的3个主节点的槽位都均一些给Node7,这样可以使得每个节点的槽位数相等均衡。
输入all之后,redis会列出一个计划,内容是自动从前面的3台master中拨出一部分槽位分给Node7的槽位,需要确认一下分配的计划。
输入yes确认后,redis便会自动重新洗牌,给Node7分配槽位。


重新分配完成后,可以进行集群信息检查,查看分配结果:

redis-cli --cluster check 192.168.xxx.xxx:6381

可以发现重新洗牌后的槽位分配为:

节点1:[1365-5460](供4096个槽位),,,分配前为[0-5460](共5461个槽位) 节点2:[6827-10922](共4096个槽位),,,分配前为[5461-10922](共5461个槽位) 节点3:[12288-16383](共4096个槽位),,,分配前为[10923-16383](共5462个槽位) 节点7:[0-1364],[5461-6826],[10923-12287](共4096个槽位),从每个节点中匀出来了一部分给了节点7

因为可能有些槽位中已经存储了key,完全的重新洗牌重新分配的成本过高,所以redis选择从前3个节点中匀出来一部分给节点7


为主节点6387分配从节点6388:

redis-cli --cluster add-node 192.168.xxx.xxx:6388 192.168.xxx.xxx:6381 --cluster-slave --cluster-master-id node7节点的十六进制编号字符串

redis便会向6388发送消息,使其加入集群并成为6387的从节点。

检查集群当前状态

redis-cli --cluster check 192.168.xxx.xxx:6381

主从缩容

首先删除从节点6388:

1.进入容器节点1

docker exec -it redis-node-1 /bin/bash

2.检查容器状态,获取6388的节点编号 

redis-cli --cluster check 192.168.xxx.xxx:6381

3.将6388从集群中移除

redis-cli --cluster del-node 192.168.xxx.xxx:6388 6388节点编号

对node7重新分配哈希槽:

 1.对集群重新分配哈希槽

redis-cli --cluster reshard 192.168.xxx.xxx:6381

2.redis经过槽位检查后,会提示需要分配的槽位数量

How many slots do you want to move (from 1 to 16384)?


如果我们想直接把node7的4096个哈希槽全部分给某个节点,可以直接输入4096。 输入4096后,会让输入要接收这些哈希槽的节点ID。假如我们想把这4096个槽都分给Node1,直接输入node1节点的编号即可。 然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node1。这里我们输入node7的节点编号,回车后输入done。

node7上面没有了哈希槽,此时便可以将node7从集群中移除。(如果node7上面有哈希槽,直接从集群中移除会报错)

 

redis-cli --cluster del-node 192.168.xxx.xxx:6387 node7节点编号