Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 的 NoSQL 数据库,并提供多种语言的 API。

大型网站为了提高站点响应速度,使用缓存工具将热点数据保存在内存中,避免直接从后端数据库读取查询,降低后端压力,其中常见的 Cache 工具有 Memcached 和 Redis。

Memcached 更侧重于⾼性能内存/缓存系统,⽽ Redis 则⽀持持久化,主打数据库功能,兼可作缓存系统(性能也很⾼)。如果业务中更加侧重性能的⾼效性,对持久化要求不⾼,那么应该优先选择 Memcached。如果业务中对持久化有需求或者对数据涉及到存储、排序等一系列复杂的操作,比如业务中有排⾏榜类应⽤、社交关系存储、数据排重、实时配置等功能,那么应该优先选择 Redis。

在大型站点应用中,热点数据几十 ~ 上百 G 很普遍,而无论是物理机、云主机(虚拟机),内存资源往往是有限的,虽然目前硬件成本降低,几十 G 几十核的主机也很常见,但是对于 Redis 这种工作进程为单线程模式的工具来说,一台主机只运行一个实例就有些浪费,且出现单点故障时影响范围很大。同时,Redis 管理大内存时不如管理相对较小的内存高效,据第三方测试,Redis 单进程内存分配达到 20G 后性能急剧下降,因此普遍使用的方式为单进程分配 8G 内存,单主机开启多个 Redis Instance.

Redis 三种集群方式:主从复制、哨兵模式(Sentinel)、Cluster 集群。

主从复制:

    从服务器将向主服务器发送 SYNC 命令,接收到 SYNC 命令后的主服务器会进行一次 BGSAVE 命令,在执行期间,会将所有命令写入缓冲区中,当 BGSAVE 命令执行完毕之后会将生成的 RDB 文件发送给从服务器,从服务器使用这个文件加载数据到内存中,之后主服务器会以 Redis 命令协议的格式将缓冲区的命令发送给从服务器。
    
    此后每次主服务执行命令都会同步给从服务器,即使有多个从服务器向主服务器发送 SYNC 命令,主服务器也只会执行一个 BGSAVE 命令,就可以处理接下来的同步请求。一个主服务器可以拥有多个从服务器,而从服务器也可拥有从服务器,复制功能不会阻塞主服务器,即使有一个或多个同步请求,主服务器依然能处理命令请求。

    当配置了主从复制模式时需要开启主服务器的持久化功能,如果将主服务器的持久化功能关闭,主服务器一旦重启,所有从服务器的数据将会丢失,即使配置了 Sentinel 模式,如果主服务器自动拉起进程比较快,以至于在 Sentinel 模式下还未选举出新的主服务器,主服务的启动也会造成子服务器的数据丢失。

哨兵模式:

    Redis 的 Sentinel 系统用于管理多个 Redis,主要执行以下三件事:

        (1) 监控:Sentinel 会不断的检查主从服务器运行状态;
        (2) 提醒:当某个 Redis 服务器出现故障,可通过 API 或者其他应用程序发送通知;
        (3) 自动故障迁移:当一个主服务器不能正常工作时,Sentinel 会进行一次故障自动迁移,会将失效主服务器的从服务器选举出一个新的主服务器,剩下的从服务器将会自动连接复制选举出来的新服务器的数据;

    Redis 的 Sentinel 系统是一个分布式的系统,可以在系统中配置一个或多个 Sentinel。

    当一个 Sentinel 发现主服务器下线时,称为主观下线,只有多个 Sentinel 都发现主服务下线,并相互之间通过命令进行交流判断主服务器下线时,称为客观下线。只有对主服务器进行客观下线时,会选举出领头 Sentinel,选举出之后,会进行新的主服务器投票选举,选举出一个从服务器升级为主服务器。并向被选中的从服务器发送 SLAVEOF no one 命令,让其变为主服务器,通过发布订阅的功能,将新的配置广播给其他 Sentinel 进行更新,并向下线的主服务器发送 SLAVEOF 命令,让其复制新的主服务器,当所有从服务器都已经开始复制新的主服务器时,领头 Sentinel 终止本次故障迁移。

    当一个 Redis 实例被重新配置是,无论是被设置成主服务器、从服务器、又或者被设置成其他主服务器的从服务器 ,Sentinel 都会向被重新配置的实例发送一个 CONFIG REWRITE 命令, 从而确保这些配置会持久化在硬盘里。

Redis cluster:

    主从复制和哨兵模式都难以在线扩容,而 Redis cluster 集群实现了对 Redis 的水平扩容,即启动 N 个Redis 节点,每个节点又可以有自己的从服务器,将数据均匀分布的存储在这 N 个结点上,每个节点存储数据的 1/N。Redis cluster 集群就是一个可以在多个 Redis 节点之间进行数据共享的设施;Redis cluster 集群采用的是无中心化配置,即节点 A 无法处理,会将请求转发至节点 B 进行处理。

    Redis 集群中的键空间被分割为 16384 个槽位。每个主节点负责 16384 中槽位的一部分,Redis 使用CRC16 算法进行槽位分配。为了保证高可用,cluster 模式也引入了主从复制模式,一个主节点对应一个或多个从节点,当主节点发生宕机时,可进行故障转移,将子节点升级为主节点。

本文部署 3 个 Redis 节点,来演示主从复制和哨兵模式,部署 6 个节点(至少 6 个节点),来演示 Cluster 集群。

1. 部署环境

    IP 地址(本地测试环境):192.168.0.10
    操作系统:Linux CentOS 7.9     
    Docker 版本: 20.10.7
    Docker Compose 版本: 2.6.1

    Redis 集群目录:/home/docker/redis_cluster

2. Redis 集群目录

    在 /home/docker/redis_cluster 目录下,目录结构如下:

        redis_cluster
            |- master
            |   |- conf
            |   |   |- redis.cnf
            |   |
            |   |- data
            |   |- log  
            |
            |- node_1
            |   |- conf
            |   |   |- redis.cnf
            |   |   
            |   |- data
            |   |- log
            |
            |- node_2
            |   |- conf
            |   |   |- redis.cnf
            |   |
            |   |- data
            |   |- log
            |           
            |   ...
            |
            |- scripts
            |   |- run_redis_server.sh  
            |
            |- replication
            |   |- docker-compose.yml
            |
            |- sentinel
            |   |- conf_1
            |   |   |- sentinel.cnf
            |   |- conf_2
            |   |   |- sentinel.cnf  
            |   |- conf_3
            |   |   |- sentinel.cnf
            |   |
            |   |  ...
            |   |                                
            |   |- docker-compose.yml
            |
            |- cluster
            |   |- docker-compose.yml
            |                        
            |- common.env

 

3. 配置文件

    1) 创建 master 的 redis.conf 文件

        在 /home/docker/redis_cluster/master/conf 目录下,创建 redis.conf 文件,内容如下:

            bind 0.0.0.0
            port 6379
            protected-mode no
            slave-read-only no

            logfile /var/log/redis.log
            #dir /data

    2) 创建 node_1 的 redis.conf 文件

        在 /home/docker/redis_cluster/node_1/conf 目录下,创建 redis.conf 文件,内容如下:

            bind 0.0.0.0
            port 6380
            protected-mode no
            slave-read-only no

            logfile /var/log/redis.log
            #dir /data

    3) 创建 node_2 的 redis.conf 文件

        在 /home/docker/redis_cluster/node_2/conf 目录下,创建 redis.conf 文件,内容如下:

            bind 0.0.0.0
            port 6381
            protected-mode no
            slave-read-only no

            logfile /var/log/redis.log
            #dir /data

    4) 创建 common.env 文件

        在 /home/docker/redis_cluster 目录下,创建 common.env 文件,内容如下:

            REQUIRE_PASS=123456
            MASTER_AUTH=123456

            MASTER_HOST=redis_master
            MASTER_PORT=6379

    5) 创建 run_redis_server.sh 文件

         在 /home/docker/redis_cluster/scripts 目录下,创建 run_redis_server.sh 文件,内容如下:       

            #!/bin/bash

            if [[ $1 = 'master' ]]; then

                redis-server /etc/redis/redis.conf --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH

            elif [[ $1 = 'slave' ]]; then

                redis-server /etc/redis/redis.conf --slaveof $MASTER_HOST $MASTER_PORT --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH
                            
            else

                echo "Usage: $0 [master|slave]"
                echo "  master - Redis master"
                echo "  slave - Redis slave"

            fi

4. 主从复制 (Replication)

    1) 创建 docker-compose.yml

        在 /home/docker/redis_cluster/replication 目录下,创建 docker-compose.yml 文件,内容如下:

            version: "3"
            services:
                redis_master:
                    image: redis:6
                    container_name: redis_master
                    volumes:
                        - /home/docker/redis_cluster/master/data:/data
                        - /home/docker/redis_cluster/master/conf:/etc/redis
                        - /home/docker/redis_cluster/master/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.10
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh master
                    env_file:
                        - /home/docker/redis_cluster/common.env                
                redis_node_1:
                    image: redis:6
                    container_name: redis_node_1
                    depends_on:
                        - redis_master
                    volumes:
                        - /home/docker/redis_cluster/node_1/data:/data
                        - /home/docker/redis_cluster/node_1/conf:/etc/redis
                        - /home/docker/redis_cluster/node_1/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.11
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
                    env_file:
                        - /home/docker/redis_cluster/common.env                
                redis_node_2:
                    image: redis:6
                    container_name: redis_node_2
                    depends_on:
                        - redis_master
                    volumes:
                        - /home/docker/redis_cluster/node_2/data:/data
                        - /home/docker/redis_cluster/node_2/conf:/etc/redis
                        - /home/docker/redis_cluster/node_2/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.12
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
                    env_file:
                        - /home/docker/redis_cluster/common.env
            networks:
                my_net:
                    driver: bridge
                    ipam:
                        config:
                            - subnet: 172.25.0.0/16

    2) 启动

        $ cd /home/docker/redis_cluster/replication

        $ docker-compose up -d   # 在后台运行

            [+] Running 4/4
            ⠿ Network redis_cluster_my_net  Created                      0.0s
            ⠿ Container redis_node_1        Started                      0.6s
            ⠿ Container redis_node_2        Started                      0.6s
            ⠿ Container redis_master        Started                      0.6s

            注:本地 docker 没有所需要的镜像时,会自动下载所需的镜像。遇到无法自动下载的情况,可以使用 docker pull 命令下载所需的镜像,再运行 docker-compose up 命令。

        $ docker images     # 查看镜像

            REPOSITORY   TAG              IMAGE ID       CREATED          SIZE
            redis               6                136fbb04568e   7 days ago      113MB

        $ docker ps

            CONTAINER ID   IMAGE     COMMAND                 ...    PORTS      NAMES
            06ea72a37b5f   redis:6   "docker-entrypoint.s…"         6379/tcp   redis_master
            e9db204dfced   redis:6   "docker-entrypoint.s…"         6379/tcp   redis_node_2
            d150fd52bf13   redis:6   "docker-entrypoint.s…"         6379/tcp   redis_node_1

        $ docker exec -it redis_master /bin/bash    # 进入 redis_master 容器

           root@a762d02ea05f:/data# redis-cli -p 6379
            127.0.0.1:6379> auth 123456
            OK
            127.0.0.1:6379> info replication
            # Replication
            role:master
            connected_slaves:2
            slave0:ip=172.25.0.11,port=6380,state=online,offset=4858,lag=1
            slave1:ip=172.25.0.12,port=6381,state=online,offset=4858,lag=1
            master_failover_state:no-failover
            master_replid:d5971ebdc023fdbeff153f84b51c047744db6456
            master_replid2:0000000000000000000000000000000000000000
            master_repl_offset:4858
            second_repl_offset:-1
            repl_backlog_active:1
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:1
            repl_backlog_histlen:4858

 

5. 哨兵模式 (Sentinel)

    1) 创建 Sentinel 配置文件

        在 /home/docker/redis_cluster/sentinel/conf_1 目录下,创建 sentinel.conf 文件,内容如下:

            port 26379
            dir /tmp
            sentinel monitor the_master 172.25.0.10 6379 2
            sentinel auth-pass the_master 123456
            sentinel down-after-milliseconds the_master 30000
            sentinel parallel-syncs the_master 1
            sentinel failover-timeout the_master 10000
            sentinel deny-scripts-reconfig yes

        在 /home/docker/redis_cluster/sentinel/conf_2 目录下,创建 sentinel.conf 文件,内容如下:

            port 26380
            dir /tmp
            sentinel monitor the_master 172.25.0.10 6379 2
            sentinel auth-pass the_master 123456
            sentinel down-after-milliseconds the_master 30000
            sentinel parallel-syncs the_master 1
            sentinel failover-timeout the_master 10000  
            sentinel deny-scripts-reconfig yes

        在 /home/docker/redis_cluster/sentinel/conf_3 目录下,创建 sentinel.conf 文件,内容如下:

            port 26381
            dir /tmp
            sentinel monitor the_master 172.25.0.10 6379 2
            sentinel auth-pass the_master 123456
            sentinel down-after-milliseconds the_master 30000
            sentinel parallel-syncs the_master 1
            sentinel failover-timeout the_master 10000  
            sentinel deny-scripts-reconfig yes

    2) 创建 docker-compose.yml

        在 /home/docker/redis_cluster/sentinel 目录下,创建 docker-compose.yml 文件,内容如下:

            version: "3"
            services:
                redis_master:
                    image: redis:6
                    container_name: redis_master
                    volumes:
                        - /home/docker/redis_cluster/master/data:/data
                        - /home/docker/redis_cluster/master/conf:/etc/redis
                        - /home/docker/redis_cluster/master/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.10
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh master
                    env_file:
                        - /home/docker/redis_cluster/common.env                
                redis_node_1:
                    image: redis:6
                    container_name: redis_node_1
                    depends_on:
                        - redis_master
                    volumes:
                        - /home/docker/redis_cluster/node_1/data:/data
                        - /home/docker/redis_cluster/node_1/conf:/etc/redis
                        - /home/docker/redis_cluster/node_1/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.11
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
                    env_file:
                        - /home/docker/redis_cluster/common.env                
                redis_node_2:
                    image: redis:6
                    container_name: redis_node_2
                    depends_on:
                        - redis_master
                    volumes:
                        - /home/docker/redis_cluster/node_2/data:/data
                        - /home/docker/redis_cluster/node_2/conf:/etc/redis
                        - /home/docker/redis_cluster/node_2/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.12
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
                    env_file:
                        - /home/docker/redis_cluster/common.env
                sentinel_1:
                    image: redis:6
                    container_name: redis_sentinel_1
                    depends_on:
                        - redis_master
                        - redis_node_1
                        - redis_node_2
                    volumes:
                        - /home/docker/redis_cluster/sentinel/conf_1:/usr/local/etc/redis
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.13
                    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
                sentinel_2:
                    image: redis:6
                    container_name: redis_sentinel_2
                    depends_on:
                        - redis_master
                        - redis_node_1
                        - redis_node_2
                    volumes:
                        - /home/docker/redis_cluster/sentinel/conf_2:/usr/local/etc/redis
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.14
                    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
                sentinel_3:
                    image: redis:6
                    container_name: redis_sentinel_3
                    depends_on:
                        - redis_master
                        - redis_node_1
                        - redis_node_2
                    volumes:
                        - /home/docker/redis_cluster/sentinel/conf_3:/usr/local/etc/redis
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.15
                    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
            networks:
                my_net:
                    driver: bridge
                    ipam:
                        config:
                            - subnet: 172.25.0.0/16

    3) 启动

        $ cd /home/docker/redis_cluster/sentinel

        $ docker-compose up

            [+] Running 7/7r sentinel]# docker-compose up
            ⠿ Network sentinel_my_net     Created               0.0s
            ⠿ Container redis_master      Created               0.0s
            ⠿ Container redis_node_2      Created               0.0s
            ⠿ Container redis_node_1      Created               0.0s
            ⠿ Container redis_sentinel_1  Created               0.0s
            ⠿ Container redis_sentinel_2  Created               0.0s
            ⠿ Container redis_sentinel_3  Created               0.0s
            Attaching to redis_master, redis_node_1, redis_node_2, redis_sentinel_1, redis_sentinel_2, redis_sentinel_3

            ...

            redis_sentinel_1  | 1:X 13 Oct 2022 10:12:52.996 # Sentinel ID is 141d777f9984c5aa5f5e6f82fd6d9dc9e865c51d
            redis_sentinel_1  | 1:X 13 Oct 2022 10:12:52.996 # +monitor master the_master 172.25.0.10 6379 quorum 2

            ...

            redis_sentinel_2  | 1:X 13 Oct 2022 10:12:53.146 # Sentinel ID is a1df19e38db034efd18add95b7bbcf6bbc6000d5
            redis_sentinel_2  | 1:X 13 Oct 2022 10:12:53.146 # +monitor master the_master 172.25.0.10 6379 quorum 2

            ...

            redis_sentinel_3  | 1:X 13 Oct 2022 10:12:53.203 # Sentinel ID is 6ba1b24f82a3e53d7fcb1e3ff9f51292c4c24440
            redis_sentinel_3  | 1:X 13 Oct 2022 10:12:53.203 # +monitor master the_master 172.25.0.10 6379 quorum 2

            注:如果之前 /home/docker/redis_cluster/replication 目录下运行的 docker-compose up 还在运行,需要先回到 /home/docker/redis_cluster/replication 目录下运行 docker-compose down。

                控制台(Console 1)处于阻塞状态,redis_sentinel_1、redis_sentinel_2 和 redis_sentinel_3 监控 master 的状态。

    4) 模拟 master 节点故障

        可以暂停 redis_master 的容器,打开一个新的控制台(Console 2):

            $ docker pause redis_master

        以上命令运行后,控制台(Console 1)阻塞状态结束阻塞,新显示内容如下:

            ...
            
            redis_node_1      | 9:S 13 Oct 2022 10:14:34.075 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization.
            redis_sentinel_2  | 1:X 13 Oct 2022 10:14:34.965 * +slave-reconf-inprog slave 172.25.0.11:6380 172.25.0.11 6380 @ the_master 172.25.0.10 6379
            redis_sentinel_2  | 1:X 13 Oct 2022 10:14:34.965 * +slave-reconf-done slave 172.25.0.11:6380 172.25.0.11 6380 @ the_master 172.25.0.10 6379
            redis_sentinel_2  | 1:X 13 Oct 2022 10:14:35.055 # -odown master the_master 172.25.0.10 6379
            redis_sentinel_2  | 1:X 13 Oct 2022 10:14:35.055 # +failover-end master the_master 172.25.0.10 6379
            redis_sentinel_2  | 1:X 13 Oct 2022 10:14:35.055 # +switch-master the_master 172.25.0.10 6379 172.25.0.12 6381
            redis_sentinel_2  | 1:X 13 Oct 2022 10:14:35.055 * +slave slave 172.25.0.11:6380 172.25.0.11 6380 @ the_master 172.25.0.12 6381
            redis_sentinel_2  | 1:X 13 Oct 2022 10:14:35.055 * +slave slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381
            redis_sentinel_1  | 1:X 13 Oct 2022 10:15:04.122 # +sdown slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381
            redis_sentinel_3  | 1:X 13 Oct 2022 10:15:04.122 # +sdown slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381
            redis_sentinel_2  | 1:X 13 Oct 2022 10:15:05.079 # +sdown slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381

6. Cluster 集群

    1) Cluster 配置文件

        Redis Cluster 官方建议最少 6 个节点,准备如下 6 个节点。

        (1) 创建 node_3 的 redis.conf 文件

            在 /home/docker/redis_cluster/node_3/conf 目录下,创建 redis.conf 文件,内容如下:

                bind 0.0.0.0
                port 6379
                protected-mode no
                slave-read-only no

                logfile /var/log/redis.log
                #dir /data

                cluster-enabled yes
                cluster-config-file node-3.conf

                masterauth pass123
                requirepass pass123

        (2) 创建 node_4 的 redis.conf 文件

            在 /home/docker/redis_cluster/node_4/conf 目录下,创建 redis.conf 文件,内容如下:

                bind 0.0.0.0
                port 6379
                protected-mode no
                slave-read-only no

                logfile /var/log/redis.log
                #dir /data

                cluster-enabled yes
                cluster-config-file node-4.conf

                masterauth pass123
                requirepass pass123 

        (3) 创建 node_5 的 redis.conf 文件

            在 /home/docker/redis_cluster/node_5/conf 目录下,创建 redis.conf 文件,内容如下:

                bind 0.0.0.0
                port 6379
                protected-mode no
                slave-read-only no

                logfile /var/log/redis.log
                #dir /data

                cluster-enabled yes
                cluster-config-file node-5.conf

                masterauth pass123
                requirepass pass123

        (4) 创建 node_6 的 redis.conf 文件

            在 /home/docker/redis_cluster/node_6/conf 目录下,创建 redis.conf 文件,内容如下:

                bind 0.0.0.0
                port 6379
                protected-mode no
                slave-read-only no

                logfile /var/log/redis.log
                #dir /data

                cluster-enabled yes
                cluster-config-file node-6.conf

                masterauth pass123
                requirepass pass123

        (5) 创建 node_7 的 redis.conf 文件

            在 /home/docker/redis_cluster/node_7/conf 目录下,创建 redis.conf 文件,内容如下:

                bind 0.0.0.0
                port 6379
                protected-mode no
                slave-read-only no

                logfile /var/log/redis.log
                #dir /data

                cluster-enabled yes
                cluster-config-file node-7.conf

                masterauth pass123
                requirepass pass123

        (6) 创建 node_8 的 redis.conf 文件

            在 /home/docker/redis_cluster/node_8/conf 目录下,创建 redis.conf 文件,内容如下:

               bind 0.0.0.0
                port 6379
                protected-mode no
                slave-read-only no

                logfile /var/log/redis.log
                #dir /data

                cluster-enabled yes
                cluster-config-file node-8.conf

                masterauth pass123      # 主从认证密码
                requirepass pass123     # 本地认证密码

                       
    2) 修改 common.env 文件

        在 /home/docker/redis_cluster 目录下,修改 common.env 文件,内容如下:

            REQUIRE_PASS=123456
            MASTER_AUTH=123456

            MASTER_HOST=redis_master
            MASTER_PORT=6379

            CLUSTER_HOSTS=172.25.0.13:6379 172.25.0.14:6379 172.25.0.15:6379 172.25.0.16:6379 172.25.0.17:6379 172.25.0.18:6379
            CLUSTER_PASS=pass123

    3) 修改 run_redis_server.sh 文件

        在 /home/docker/redis_cluster/scripts 目录下,修改 run_redis_server.sh 文件,内容如下:

            #!/bin/bash

            if [[ $1 = 'master' ]]; then

                redis-server /etc/redis/redis.conf --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH

            elif [[ $1 = 'slave' ]]; then

                redis-server /etc/redis/redis.conf --slaveof $MASTER_HOST $MASTER_PORT --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH

            elif [[ $1 = 'cluster_normal' ]]; then

                redis-server /etc/redis/redis.conf
                
            elif [[ $1 = 'cluster_special' ]]; then

                redis-server /etc/redis/redis.conf
                echo "yes" | redis-cli --cluster create $CLUSTER_HOSTS --cluster-replicas 1 -a $CLUSTER_PASS

            else

                echo "Usage: $0 [master|slave|cluster_normal|cluster_special]"
                echo "  master - Redis master"
                echo "  slave - Redis slave"
                echo "  cluster_normal - Redis cluster normal node"
                echo "  cluster_special - Redis cluster special node"
                echo ""

            fi

    4) 创建 docker-compose.yml

        在 /home/docker/redis_cluster/cluster 目录下,创建 docker-compose.yml 文件,内容如下:

            version: "3"
            services:            
                redis_node_3:
                    image: redis:6
                    container_name: redis_node_3
                    volumes:
                        - /home/docker/redis_cluster/node_3/data:/data
                        - /home/docker/redis_cluster/node_3/conf:/etc/redis
                        - /home/docker/redis_cluster/node_3/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.13       
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
                    env_file:
                        - /home/docker/redis_cluster/common.env
                redis_node_4:
                    image: redis:6
                    container_name: redis_node_4
                    volumes:
                        - /home/docker/redis_cluster/node_4/data:/data
                        - /home/docker/redis_cluster/node_4/conf:/etc/redis
                        - /home/docker/redis_cluster/node_4/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.14
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
                    env_file:
                        - /home/docker/redis_cluster/common.env
                redis_node_5:
                    image: redis:6
                    container_name: redis_node_5
                    volumes:
                        - /home/docker/redis_cluster/node_5/data:/data
                        - /home/docker/redis_cluster/node_5/conf:/etc/redis
                        - /home/docker/redis_cluster/node_5/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.15
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
                    env_file:
                        - /home/docker/redis_cluster/common.env
                redis_node_6:
                    image: redis:6
                    container_name: redis_node_6
                    volumes:
                        - /home/docker/redis_cluster/node_6/data:/data
                        - /home/docker/redis_cluster/node_6/conf:/etc/redis
                        - /home/docker/redis_cluster/node_6/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.16
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
                    env_file:
                        - /home/docker/redis_cluster/common.env             
                redis_node_7:
                    image: redis:6
                    container_name: redis_node_7
                    volumes:
                        - /home/docker/redis_cluster/node_7/data:/data
                        - /home/docker/redis_cluster/node_7/conf:/etc/redis
                        - /home/docker/redis_cluster/node_7/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.17
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
                    env_file:
                        - /home/docker/redis_cluster/common.env
                redis_node_8:
                    image: redis:6
                    container_name: redis_node_8
                    depends_on:
                        - redis_node_3
                        - redis_node_4
                        - redis_node_5
                        - redis_node_6
                        - redis_node_7                        
                    volumes:
                        - /home/docker/redis_cluster/node_8/data:/data
                        - /home/docker/redis_cluster/node_8/conf:/etc/redis
                        - /home/docker/redis_cluster/node_8/log:/var/log
                        - /home/docker/redis_cluster/scripts:/root/redis_scripts
                    networks:
                        my_net:
                            ipv4_address: 172.25.0.18
                    command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_special
                    env_file:
                        - /home/docker/redis_cluster/common.env
            networks:
                my_net:
                    driver: bridge
                    ipam:
                        config:
                            - subnet: 172.25.0.0/16

    5) 启动

        $ cd /home/docker/redis_cluster/cluster

        $ docker-compose up -d

            [+] Running 7/7
            ⠿ Network cluster_my_net  Created                    0.0s
            ⠿ Container redis_node_6  Started                    0.8s
            ⠿ Container redis_node_7  Started                    0.7s
            ⠿ Container redis_node_3  Started                    0.8s
            ⠿ Container redis_node_4  Started                    1.0s
            ⠿ Container redis_node_5  Started                    1.0s
            ⠿ Container redis_node_8  Started                    1.6s

        $ docker exec -it redis_node_8 /bin/bash

            root@754fb446b99f:/data#  redis-cli -c
            127.0.0.1:6379> auth pass123
            OK

            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:2
            cluster_stats_messages_ping_sent:37
            cluster_stats_messages_pong_sent:38
            cluster_stats_messages_sent:75
            cluster_stats_messages_ping_received:38
            cluster_stats_messages_pong_received:37
            cluster_stats_messages_received:75

            127.0.0.1:6379> cluster nodes

            4a93001b49bb2138c0a2c7f67369e47f1762ae7d 172.25.0.18:6379@16379 myself,slave c1095cc3609d0043fb8f7db7d2e728f89c19c5ee 0 1665898497000 2 connected
            c1095cc3609d0043fb8f7db7d2e728f89c19c5ee 172.25.0.14:6379@16379 master - 0 1665898499256 2 connected 5461-10922
            98c22d70fedf2332629df0e065d5fa5dfbaa9964 172.25.0.16:6379@16379 slave d1604ceeb5fa2474e779468bb6f4566c1adee365 0 1665898497000 3 connected
            d1604ceeb5fa2474e779468bb6f4566c1adee365 172.25.0.15:6379@16379 master - 0 1665898498228 3 connected 10923-16383
            c2f940037de7ff3a0b05611a9b70f56f0afa7a09 172.25.0.13:6379@16379 master - 0 1665898496171 1 connected 0-5460
            1c834e5fbe2f61029f55a53e6f517ec8dcf87833 172.25.0.17:6379@16379 slave c2f940037de7ff3a0b05611a9b70f56f0afa7a09 0 1665898497193 1 connected    

        可以看到 redis_node_3、redis_node_4、redis_node_5 是 master,redis_node_6、redis_node_7、redis_node_8 是 slave。进入任意从节点,执行 info replicaiton 来再次验证。

        $ docker exec -it redis_node_6 /bin/bash

            root@15ccf6f9c9b8:/data# redis-cli -c
            127.0.0.1:6379> auth pass123
            OK
            127.0.0.1:6379> info replication
            # Replication
            role:slave
            master_host:172.25.0.15
            master_port:6379
            master_link_status:up
            master_last_io_seconds_ago:9
            master_sync_in_progress:0
            slave_read_repl_offset:924
            slave_repl_offset:924
            slave_priority:100
            slave_read_only:0
            replica_announced:1
            connected_slaves:0
            master_failover_state:no-failover
            master_replid:f64ceb5694da9afbd96ec4fe96eb07f17d2f7922
            master_replid2:0000000000000000000000000000000000000000
            master_repl_offset:924
            second_repl_offset:-1
            repl_backlog_active:1
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:1
            repl_backlog_histlen:924            

 

原文地址:http://www.cnblogs.com/tkuang/p/16797494.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性