Docker 部署 Redis 集群(主从复制+哨兵模式)

引言

Redis是一种高性能的内存数据库,它可以存储各种类型的数据,如字符串、列表、集合、散列、有序集等,并提供了丰富的操作和功能,如事务、发布订阅、lua脚本、持久化等。Redis的优点有以下几点:

  • 速度快:Redis是基于内存的,读写速度非常快,可以达到每秒数十万次的处理能力。
  • 灵活:Redis支持多种数据结构,可以满足不同的业务需求,如缓存、计数器、排行榜、消息队列等。
  • 可扩展:Redis可以通过集群的方式,提高数据的可用性、安全性和性能。

那么,为什么要部署集群呢?这是因为单个Redis节点可能会遇到以下问题:

  • 容量有限:Redis是基于内存的,如果数据量过大,可能会超出单个节点的内存容量,导致数据丢失或者服务不可用。
  • 性能有限:Redis是单线程的,如果请求量过大,可能会导致响应延迟或者服务拥塞,影响用户体验。
  • 可用性有限:Redis是单点的,如果节点发生故障或者网络中断,可能会导致数据不可访问或者数据丢失,影响业务正常运行。

为了解决这些问题,我们可以使用Redis集群,它是一种分布式的架构,可以将数据分片存储在多个节点上,实现以下好处:

  • 容量扩展:Redis集群可以通过增加节点的数量,来增加总的内存容量,从而存储更多的数据。
  • 性能提升:Redis集群可以通过分散请求的压力,来提高吞吐量和响应速度,从而提高服务质量。
  • 可用性保障:Redis集群可以通过主从复制和故障转移,来保证数据的一致性和可靠性,从而提高服务的稳定性。

综上所述,Redis是一种非常强大和灵活的内存数据库,它可以为我们的业务提供高效和可靠的数据服务。为了充分发挥Redis的优势,我们需要使用Redis集群,来提升数据的容量、性能和可用性。在接下来的文章中,我将向你展示如何使用docker来部署Redis集群。

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

1,部署环境

IP 地址(本地测试环境):192.168.200.128
操作系统:Linux CentOS 7

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

2,Redis 集群目录

3,配置文件

  1) 创建 master 的 redis.conf 文件

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

# 创建目录

mkdir -p /home/docker/redis_cluster/master/conf

cd /home/docker/redis_cluster/master/conf

vim redis.conf

内容如下:

bind 0.0.0.0            
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
dir /data

bind 0.0.0.0        允许从任何地址连接到 Redis 服务器

port 6379           端口

protected-mode no        禁用保护模式,允许来自任何地址的连接

slave-read-only no        从节点可以处理读写操作,设置为yes就表示只读

logfile /var/log/redis.log    日志文件路径为 /var/log/redis.log

dir /data        指定 Redis 持久化数据文件的存储目录

2) 创建 node_1 的 redis.conf 文件

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

# 创建目录

mkdir -p  /home/docker/redis_cluster/node_1/conf

cd /home/docker/redis_cluster/node_1/conf

vim 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 文件,内容如下:

# 创建目录

mkdir -p  /home/docker/redis_cluster/node_2/conf

cd /home/docker/redis_cluster/node_2/conf

vim 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 文件,内容如下:

# 进入该目录

cd /home/docker/redis_cluster

vim common.env

内容如下:

REQUIRE_PASS=123456
MASTER_AUTH=123456

MASTER_HOST=redis_master
MASTER_PORT=6379

common.env 文件是一个环境变量文件

  • REQUIRE_PASS:Redis 服务器的密码。
  • MASTER_AUTH:主节点的身份验证密码。
  • MASTER_HOST:主节点的主机名。
  • MASTER_PORT:主节点的端口号。

5) 创建 run_redis_server.sh 文件

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

mkdir  /home/docker/redis_cluster/scripts

cd  /home/docker/redis_cluster/scripts

vim run_redis_server.sh

内容如下:

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

我大概解释一下这里:

如果命令行参数 $1 的值等于字符串 'master',则执行以下代码块:

  • 启动 Redis 服务器作为主节点(Master)。
  • 使用 redis-server 命令启动 Redis,指定配置文件为 /etc/redis/redis.conf
  • 使用 --requirepass 选项设置 Redis 主节点的密码为环境变量 $REQUIRE_PASS 的值。
  • 使用 --masterauth 选项设置主节点的身份验证密码为环境变量 $MASTER_AUTH 的值。

如果命令行参数 $1 的值等于字符串 'slave',则执行以下代码块:

  • 启动 Redis 服务器作为从节点(Slave)。
  • 使用 redis-server 命令启动 Redis,指定配置文件为 /etc/redis/redis.conf
  • 使用 --slaveof 选项将从节点连接到主节点,主机名为环境变量 $MASTER_HOST 的值,端口号为环境变量 $MASTER_PORT 的值。
  • 使用 --requirepass 选项设置 Redis 从节点的密码为环境变量 $REQUIRE_PASS 的值。
  • 使用 --masterauth 选项设置从节点的身份验证密码为环境变量 $MASTER_AUTH 的值。

主从复制

现在我们开始实现redis的主从复制

  1) 创建 docker-compose.yml

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

mkdir /home/docker/redis_cluster/replication

vim docker-compose.yml
内容如下:

version: "3"
services:
    redis_master:
        image: redis
        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
        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
        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

我解释一下:

image: redis     redis镜像的名字,因为我的redis版本是latest,所以可以简写redis

container_name        设置容器名称
volumes:                数据卷

networks        网络
command        用于定义在容器启动时执行的命令
env_file:        用于指定一个或多个包含环境变量的文件。

 2) 启动

cd /home/docker/redis_cluster/replication

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

注意:你需要安装docker-compose,否则会:找不到命令,下面这行代码就是安装docker-compose

curl -L "https://github.com/docker/compose/releases/download/1.29.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

添加权限

chmod +x /usr/local/bin/docker-compose

现在我们就已经完成redis的主从复制了,接下来自己可以测试一下

哨兵模式

哨兵模式是一种辅助的高可用方案,它可以实现对主从复制或者cluster集群的监控和管理,从而提高数据的可靠性和稳定性。

哨兵模式的原理是:

  • 在主从复制的基础上,增加一个或多个哨兵节点(Sentinel),它们是一些特殊的Redis实例,不存储数据,只负责监控主从节点的运行状态。
  • 哨兵节点会定期向主从节点发送心跳包,检查它们是否存活,是否正常工作,是否满足角色切换的条件等。
  • 当哨兵节点发现主节点出现故障时,它会与其他哨兵节点进行协商,选举出一个领头哨兵,由它来执行故障转移的操作。
  • 故障转移的操作包括:从所有从节点中选出一个最优的从节点,将它升级为新的主节点,通知其他从节点将新的主节点作为复制源,通知客户端和其他哨兵节点更新主节点的信息。
  • 故障转移后,哨兵节点会继续监控新的主从节点,如果原来的主节点恢复了,它会被降级为从节点,重新加入复制。

  1) 创建 Sentinel 配置文件

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


port 26379
dir "/tmp"
sentinel monitor the_master 172.25.0.12 6381 2
sentinel auth-pass the_master 123456

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.12 6381 2
sentinel auth-pass the_master 123456

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.12 6381 2
sentinel auth-pass the_master 123456

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
        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
        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
        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
        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
        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
        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

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

启动起来之后,控制台(Console 1)现在是处于阻塞状态

 4) 模拟 master 节点故障

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

docker pause redis_master

以上命令运行后,控制台(Console 1)新显示内容如下:

故障转移了,说明没有问题,我们的哨兵模式就搭建好了,现在可以恢复redis_master了

docker unpause redis_master

喜欢博主的可以关注一波,你的支持就是我的动力!让我们一起进步!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值