环境准备

Redis是C语言开发,安装Redis需要先将Redis的源码进行编译,编译依赖gcc环境

  1. yum install gcc-c++
  2. [root@--- redis]# gcc -v
  3. Using built-in specs.
  4. COLLECT_GCC=gcc
  5. COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
  6. Target: x86_64-redhat-linux
  7. Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
  8. Thread model: posix
  9. gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
  10. [root@--- redis]#

master+slave(主从)
sentinel(哨兵)
cluster(集群)

创建redis网卡

  1. [root@--- ~]# docker network create redis --subnet 172.38.0.0/16
  2. 0350d84612bef09bc32b39f15ac6b608dae17cbd75d04b282c0bd37c0283bb7c
  3. [root@iZm5e23n3ueobwkjtfartxZ ~]# docker network ls
  4. NETWORK ID NAME DRIVER SCOPE
  5. feafa30d4051 bridge bridge local
  6. e8bf4fced9e2 host host local
  7. 0096a971fd2c mynet bridge local
  8. 6263db0933b9 none null local
  9. 0350d84612be redis bridge local
  10. 799426d70aa2 test-network bridge local
  11. [root@--- ~]#

创建6个redis服务

脚本创建

  • cluster-enabled:是否启动集群,选值:yes 、no
  • cluster-config-file 配置文件.conf :指定节点信息,自动生成
  • cluster-node-timeout 毫秒值: 配置节点连接超时时间
  • appendonly:是否开启持久化,选值:yes、no
  • daemonize: 守护进程启动(后台启动) ```shell for port in $(seq 1 6); \ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat << EOF >/mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes

    daemonize yes

    EOF done

查看节点

[root@—- redis]# pwd /mydata/redis [root@—- redis]# ls node-1 node-2 node-3 node-4 node-5 node-6

查看redis.conf

[root@—- conf]# cat redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.11 cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes

daemonize yes

[root@—- conf]#

  1. <a name="v1a39"></a>
  2. # 启动redis服务
  3. ```shell
  4. # -v 挂载数据卷
  5. # redis:5.0.9-alpine3.11 redis镜像、
  6. # 6379 是redis端口
  7. # 16379 是redis集群TCP端口
  8. # --net 使用自定义redis网络
  9. # --ip 是本容器绑定的ip
  10. # redis-server /etc/redis/redis.conf 追加命令,通过redis.conf启动
  11. # 方式一、一个一个启动
  12. docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
  13. -v /mydata/redis/node-1/data:/data \
  14. -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
  15. -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  16. docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
  17. -v /mydata/redis/node-2/data:/data \
  18. -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
  19. -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  20. docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
  21. -v /mydata/redis/node-3/data:/data \
  22. -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
  23. -d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  24. docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
  25. -v /mydata/redis/node-4/data:/data \
  26. -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
  27. -d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  28. docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
  29. -v /mydata/redis/node-5/data:/data \
  30. -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
  31. -d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  32. docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
  33. -v /mydata/redis/node-6/data:/data \
  34. -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
  35. -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  36. # 方式二、启动脚本(6个全部启动)
  37. for port in $(seq 1 6); \
  38. do \
  39. echo ${port}
  40. docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
  41. -v /mydata/redis/node-${port}/data:/data \
  42. -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
  43. -d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
  44. done
  45. # 查看
  46. [root@--- conf]# docker ps
  47. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  48. 0d3c18b61098 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 2 seconds ago Up 1 second 0.0.0.0:6376->6379/tcp, 0.0.0.0:16376->16379/tcp redis-6
  49. ee896fb093da redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 13 seconds ago Up 12 seconds 0.0.0.0:6375->6379/tcp, 0.0.0.0:16375->16379/tcp redis-5
  50. a83bb7b16dff redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 48 seconds ago Up 47 seconds 0.0.0.0:6374->6379/tcp, 0.0.0.0:16374->16379/tcp redis-4
  51. ffe4c9619bed redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 58 seconds ago Up 57 seconds 0.0.0.0:6373->6379/tcp, 0.0.0.0:16373->16379/tcp redis-3
  52. a316a31e273f redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:6372->6379/tcp, 0.0.0.0:16372->16379/tcp redis-2
  53. 71c072f57c29 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6371->6379/tcp, 0.0.0.0:16371->16379/tcp redis-1
  54. [root@--- conf]#

创建集群

进入任意一个 Redis 实例

  1. # 进入redis-1容器
  2. docker exec -it redis-1 /bin/sh
  3. # 创建集群主节点
  4. # Redis Cluster最低要求是3个主节点
  5. # redis-cli --cluster create 192.168.163.132:6379 192.168.163.132:6380 192.168.163.132:6381
  6. # 创建集群从节点
  7. --cluster-replicas 参数为数字,1表示每个主节点需要1个从节点。
  8. redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

问题:

  1. # 启动客户端
  2. [root@--- src]# ./redis-cli
  3. Could not connect to Redis at 127.0.0.1:6379: Connection refused
  4. not connected> exit
  5. [root@--- src]#
  6. 连接redis被拒绝

原因:推测是后台redis服务没有起来,后来发现cluster-announce-ip配错ip了🤣
重新创建还是Could not connect to Redis at 172.38.0.11:6379: Connection refused,发现port配成6739了🧐

修改之后终于可以了

  1. >>> Nodes configuration updated
  2. >>> Assign a different config epoch to each node
  3. >>> Sending CLUSTER MEET messages to join the cluster
  4. Waiting for the cluster to join
  5. ...
  6. >>> Performing Cluster Check (using node 172.38.0.11:6379)
  7. M: 70ebdca0264c079bb2c33452e6388d37706da282 172.38.0.11:6379
  8. slots:[0-5460] (5461 slots) master
  9. 1 additional replica(s)
  10. M: b3f737d0d77b823794087011f1501fd43a2ea316 172.38.0.12:6379
  11. slots:[5461-10922] (5462 slots) master
  12. 1 additional replica(s)
  13. M: 506ff2bf1020d468e7d7a81ddbfb616a7e9b7d96 172.38.0.13:6379
  14. slots:[10923-16383] (5461 slots) master
  15. 1 additional replica(s)
  16. S: 7f57f8a01493fa9e46e24ad8a9e46995634f7442 172.38.0.15:6379
  17. slots: (0 slots) slave
  18. replicates 70ebdca0264c079bb2c33452e6388d37706da282
  19. S: f839b6924977e99d3b74324f2ef70b3678e1a257 172.38.0.14:6379
  20. slots: (0 slots) slave
  21. replicates 506ff2bf1020d468e7d7a81ddbfb616a7e9b7d96
  22. S: bbc4dd0639b90e9ddfb5cef278be04a24276cbdb 172.38.0.16:6379
  23. slots: (0 slots) slave
  24. replicates b3f737d0d77b823794087011f1501fd43a2ea316
  25. [OK] All nodes agree about slots configuration.
  26. >>> Check for open slots...
  27. >>> Check slots coverage...
  28. [OK] All 16384 slots covered.
  29. /data #

image.png

测试连接集群

  1. 连接集群
  2. redis-cli -c
  3. 127.0.0.1:6379> cluster info
  4. cluster_state:ok
  5. cluster_slots_assigned:16384
  6. cluster_slots_ok:16384
  7. cluster_slots_pfail:0
  8. cluster_slots_fail:0
  9. cluster_known_nodes:6
  10. cluster_size:3
  11. cluster_current_epoch:6
  12. cluster_my_epoch:1
  13. cluster_stats_messages_ping_sent:292
  14. cluster_stats_messages_pong_sent:307
  15. cluster_stats_messages_sent:599
  16. cluster_stats_messages_ping_received:302
  17. cluster_stats_messages_pong_received:292
  18. cluster_stats_messages_meet_received:5
  19. cluster_stats_messages_received:599
  20. 127.0.0.1:6379> cluster nodes
  21. b3f737d0d77b823794087011f1501fd43a2ea316 172.38.0.12:6379@16379 master - 0 1633332452560 2 connected 5461-10922
  22. 506ff2bf1020d468e7d7a81ddbfb616a7e9b7d96 172.38.0.13:6379@16379 master - 0 1633332453000 3 connected 10923-16383
  23. 7f57f8a01493fa9e46e24ad8a9e46995634f7442 172.38.0.15:6379@16379 slave 70ebdca0264c079bb2c33452e6388d37706da282 0 1633332453000 5 connected
  24. 70ebdca0264c079bb2c33452e6388d37706da282 172.38.0.11:6379@16379 myself,master - 0 1633332452000 1 connected 0-5460
  25. f839b6924977e99d3b74324f2ef70b3678e1a257 172.38.0.14:6379@16379 slave 506ff2bf1020d468e7d7a81ddbfb616a7e9b7d96 0 1633332453762 4 connected
  26. bbc4dd0639b90e9ddfb5cef278be04a24276cbdb 172.38.0.16:6379@16379 slave b3f737d0d77b823794087011f1501fd43a2ea316 0 1633332453000 6 connected
  27. 127.0.0.1:6379>

image.png

测试主从节点替换

set一个值,然后停掉对应的服务,再次get

  1. 127.0.0.1:6379> set a b
  2. -> Redirected to slot [15495] located at 172.38.0.13:6379
  3. OK
  4. # 发现a值设置在了172.38.0.13容器上,然后我们试着去停掉redis-3容器的服务,然后再次get,看一下结果
  5. 172.38.0.13:6379> get a
  6. "b"
  7. 172.38.0.13:6379> get a
  8. Could not connect to Redis at 172.38.0.13:6379: Host is unreachable
  9. (34.04s)
  10. not connected> exit
  11. # 重连集群
  12. /data # redis-cli -c
  13. 127.0.0.1:6379> get a
  14. -> Redirected to slot [15495] located at 172.38.0.14:6379
  15. "b"
  16. 172.38.0.14:6379>
  17. # 发现a值被存储到了172.38.0.14机器上,172.38.0.14是172.38.0.13的从节点,当主节点172.38.0.13
  18. # 发生故障时,自动替换到172.38.0.13
  1. # 查看redis节点服务信息,发现72.38.0.13节点fail, 172.38.0.14变成master
  2. 172.38.0.14:6379> cluster nodes
  3. 506ff2bf1020d468e7d7a81ddbfb616a7e9b7d96 172.38.0.13:6379@16379 master,fail - 1633332679285 1633332678000 3 connected
  4. bbc4dd0639b90e9ddfb5cef278be04a24276cbdb 172.38.0.16:6379@16379 slave b3f737d0d77b823794087011f1501fd43a2ea316 0 1633333102497 6 connected
  5. f839b6924977e99d3b74324f2ef70b3678e1a257 172.38.0.14:6379@16379 myself,master - 0 1633333100000 8 connected 10923-16383
  6. 70ebdca0264c079bb2c33452e6388d37706da282 172.38.0.11:6379@16379 master - 0 1633333101494 1 connected 0-5460
  7. 7f57f8a01493fa9e46e24ad8a9e46995634f7442 172.38.0.15:6379@16379 slave 70ebdca0264c079bb2c33452e6388d37706da282 0 1633333102000 5 connected
  8. b3f737d0d77b823794087011f1501fd43a2ea316 172.38.0.12:6379@16379 master - 0 1633333102596 2 connected 5461-10922
  9. 172.38.0.14:6379>

docker搭建redis集群完成🎈🎈