Redis中主从、哨兵和集群区别及搭建

  • Redis实现高可用
    • AOF/RDB持久化机制
    • 主从架构(主服务器挂了,手动由从服务器顶上)
    • 引入哨兵机制自动故障转义
  • 主从复制原理
    • PSYNC命令两种模式:完全重同步、部分重同步
    • 完全重同步:主从服务器建立连接、主服务器生成RDB文件发给从服务器、主服务器不阻塞(相关修改命令记录至buffer)、将修改命令发给从服务器
    • 部分重同步:从服务器断线重连,发送RunId和offset给主服务器,主服务器判断offset和runId,将还未同步给从服务器的offset相关指令进行发送
  • 哨兵机制
    • 哨兵可以理解为特殊的Redis服务器,一般会组成哨兵集群
    • 哨兵主要工作是监控、告警、配置以及选主
    • 当主服务器发生故障时,会「选出」一台从服务器来顶上「客观下线」的服务器,由「领头哨兵」进行切换
  • 数据丢失
    • Redis的主从复制和故障转移阶段都有可能发生数据丢失问题(通过配置尽可能避免)

一、Redis主从架构实现(本文是采用docker搭建redis主从架构)

1. 环境准备

准备三台服务器 或者 docker

2.docker 拉取redis镜像

  1. docker pull redis

image.png

3.准备好redis配置文件(这里实现一主两从)

  • redis-6380/redis.conf(master节点配置文件)
  • redis-6381/redis.conf(slave1节点配置文件)
  • redis-6382/redis.conf(slave2节点配置文件)

这里的配置文件是存到本地的,redis配置文件可以从网上下载master配置文件如下

  1. #指定redis接受来自该ip的请求,如果设置为0.0.0.0则默认接受所有来源的请求
  2. bind 0.0.0.0
  3. #是否开启保护模式,要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,
  4. #拒绝外部访问。要是开启了密码和bind,可以开启。否则最好关闭,设置为no
  5. protected-mode no
  6. #redis监听的端口号
  7. port 6380
  8. #参数全设置为0为不限制
  9. client-output-buffer-limit normal 0 0 0
  10. client-output-buffer-limit replica 0 0 0
  11. client-output-buffer-limit pubsub 0 0 0

slave1节点在master的基础上额外加上如下的配置:

  1. #指定redis接受来自该ip的请求,如果设置为0.0.0.0则默认接受所有来源的请求
  2. bind 0.0.0.0
  3. #是否开启保护模式,要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,
  4. #拒绝外部访问。要是开启了密码和bind,可以开启。否则最好关闭,设置为no
  5. protected-mode no
  6. #redis监听的端口号
  7. port 6381
  8. #绑定主节点的ip和端口号 这里的ip地址一定是redis主服务器的docker给分配的ip
  9. replicaof 172.17.0.2 6380
  10. #从节点是否具有只读的功能,如果为yes,从节点只可以读取,不可以写入
  11. replica-read-only yes

slave2节点在master的基础上额外加上如下的配置:

  1. #指定redis接受来自该ip的请求,如果设置为0.0.0.0则默认接受所有来源的请求
  2. bind 0.0.0.0
  3. #是否开启保护模式,要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,
  4. #拒绝外部访问。要是开启了密码和bind,可以开启。否则最好关闭,设置为no
  5. protected-mode no
  6. #redis监听的端口号
  7. port 6382
  8. #绑定主节点的ip和端口号 这里的ip地址一定是redis主服务器的docker给分配的ip
  9. replicaof 172.17.0.2 6380
  10. #从节点是否具有只读的功能,如果为yes,从节点只可以读取,不可以写入
  11. replica-read-only yes

4.启动容器

  1. #启动redis
  2. docker run -p 6380:6380 -d --name redis-6380 -v /Users/lishuo/Code/docker/redis/conf/redis-6380/redis.conf:/redis.conf --restart=always redis redis-server /redis.conf
  3. docker run -p 6381:6381 -d --name redis-6381 -v /Users/lishuo/Code/docker/redis/conf/redis-6381/redis.conf:/redis.conf --restart=always redis redis-server /redis.conf
  4. docker run -p 6382:6382 -d --name redis-6382 -v /Users/lishuo/Code/docker/redis/conf/redis-6382/redis.conf:/redis.conf --restart=always redis redis-server /redis.conf
  • 参数解释
    • run 启动容器
    • -p 端口映射 宿主机端口:docker内redis端口
    • -d 守护进程
    • —name redis进程名称
    • -v 数据卷绑定,宿主机redis配置文件路径与docker内redis文件路径的绑定

启动成功截图: image.png

5. 进入到容器内部,查看redis信息

  1. docker exec -it redis-6380 /bin/bash
  2. redis-cli -h 127.0.0.1 -p 6380
  3. info replication
  • 进入redis 6380 主服务器查看配置信息

image.png

  • 进入redis 6381 从1服务器查看配置信息

image.png

  • 进入redis 6382 从2服务器查看配置信息

image.png

  • 参数解释
    • info replication 命令可以打印出redis的节点相关信息
    • role后面会显示该节点是master或者slave,如果该节点为slave节点,那么还会显示主节点的ip和端口号
    • master_link_status的值为up表示从节点和主节点的关系已经连接上,为down则表示关系未连接。

6. 验证主从复制功能

  • 在master节点上 设置一个name的key

image.png

  • 去从库1何从库2节点上获取name的key

image.png

  • 去从库1何从库2节点上是不允许写入的

image.png

至此我们Redis的主从复制就已经搭建好了

二、Redis哨兵搭建

1.准备好redis哨兵配置文件(这里实现三台哨兵集群)

redis-26380-sentinel/conf/sentinel.conf\ redis-26381-sentinel/conf/sentinel.conf\ redis-26382-sentinel/conf/sentinel.conf

26380-sentinel 哨兵配置文件如下

  1. #哨兵端口号 一定要和启动命令映射第二个端口号一致
  2. port 26380
  3. # 让sentinel服务后台运行
  4. daemonize yes
  5. # 修改监控的主redis服务器
  6. # 最后一个1表示,两台机器判定主被动下线后,就进行failover(故障转移)
  7. sentinel monitor mymaster 172.17.0.2 6380 1
  • 这是哨兵配置文件中定义一个要监视的Redis主服务器的指令。解释如下:
    • sentinel: 告诉哨兵模式下的Redis服务器,后面的指令是用于哨兵的配置。
    • monitor: 指令用于添加要监视的Redis主服务器。
    • mymaster: 这是给要监视的Redis主服务器起的一个名称,你可以自己指定,后续的操作都会使用这个名称来引用该主服务器。
    • 172.17.0.2: 这是要监视的Redis主服务器的IP地址或主机名。6380: 这是要监视的Redis主服务器的端口号。
    • 1: 这是一个表示“主服务器至少需要多少个哨兵同意才能进行故障转移”的数字。在这里,设置为1意味着只需要一个哨兵同意故障转移就可以开始。

26381-sentinel 哨兵配置文件如下

  1. #哨兵端口号 一定要和启动命令映射第二个端口号一致
  2. port 26381
  3. # 让sentinel服务后台运行
  4. daemonize yes
  5. # 修改监控的主redis服务器
  6. # 最后一个1表示,两台机器判定主被动下线后,就进行failover(故障转移)
  7. sentinel monitor mymaster 172.17.0.2 6380 1

26382-sentinel 哨兵配置文件如下

  1. #哨兵端口号 一定要和启动命令映射第二个端口号一致
  2. port 26382
  3. # 让sentinel服务后台运行
  4. daemonize yes
  5. # 修改监控的主redis服务器
  6. # 最后一个1表示,两台机器判定主被动下线后,就进行failover(故障转移)
  7. sentinel monitor mymaster 172.17.0.2 6380 1

2.创建三台哨兵容器

  1. docker run -p 26380:26380 -d --name redis-sentinel-26380 -v /Users/lishuo/Code/docker/redis/conf/redis-26380-sentinel:/data/sentinel.conf --restart=always redis
  2. docker run -p 26381:26381 -d --name redis-sentinel-26381 -v /Users/lishuo/Code/docker/redis/conf/redis-26381-sentinel:/data/sentinel.conf --restart=always redis
  3. docker run -p 26382:26382 -d --name redis-sentinel-26382 -v /Users/lishuo/Code/docker/redis/conf/redis-26382-sentinel:/data/sentinel.conf --restart=always redis

image.png

3.然后切到容器内部启动服务

  1. lishuo@李硕的MacBook Pro:~/Code/docker/redis/redis-26380-sentinel/conf
  2. [130] $ docker exec -it 14ba726b5d34 bash
  3. root@14ba726b5d34:/data# redis-sentinel /data/sentinel.conf/sentinel.conf

4.判断哨兵是否配置成功

切到配置文件,查看刚才的哨兵配置文件是否新增以下信息

  1. #哨兵端口号 一定要和启动命令映射第二个端口号一致
  2. port 26380
  3. #后台启动
  4. daemonize yes
  5. sentinel monitor mymaster 172.17.0.2 6380 1
  6. # Generated by CONFIG REWRITE
  7. pidfile "/var/run/redis.pid"
  8. user default on nopass ~* &* +@all
  9. dir "/data"
  10. sentinel myid 1adb3bb3916726edbd3a88a7c4ed4f84e293dc44
  11. sentinel config-epoch mymaster 1
  12. sentinel leader-epoch mymaster 1
  13. sentinel current-epoch 1
  14. sentinel known-replica mymaster 172.17.0.4 6381
  15. sentinel known-replica mymaster 172.17.0.2 6382
  16. sentinel known-sentinel mymaster 172.17.0.7 26380 d017bdf8ec22411dd19146833e92682c0b0dcd50
  17. sentinel known-sentinel mymaster 172.17.0.5 26380 000bc04811e6ceb5418df6fe8aacbce763b2d679

如果出现以下配置文件说明配置成功

5.关闭redis主服务器,看是否会自动选举新的主服务器,如果推选则配置无误

  1. #哨兵端口号 一定要和启动命令映射第二个端口号一致
  2. port 26380
  3. # 让sentinel服务后台运行
  4. daemonize yes
  5. # 修改监控的主redis服务器
  6. # 最后一个1表示,两台机器判定主被动下线后,就进行failover(故障转移)
  7. sentinel monitor mymaster 172.17.0.3 6382 1
  8. # Generated by CONFIG REWRITE
  9. pidfile "/var/run/redis.pid"
  10. user default on nopass ~* &* +@all
  11. dir "/data"
  12. sentinel myid 000bc04811e6ceb5418df6fe8aacbce763b2d679
  13. sentinel config-epoch mymaster 1
  14. sentinel leader-epoch mymaster 1
  15. sentinel current-epoch 1
  16. sentinel known-replica mymaster 172.17.0.2 6380
  17. sentinel known-replica mymaster 172.17.0.4 6381
  18. sentinel known-sentinel mymaster 172.17.0.7 26382 d017bdf8ec22411dd19146833e92682c0b0dcd50
  19. sentinel known-sentinel mymaster 172.17.0.6 26381 1adb3bb3916726edbd3a88a7c4ed4f84e293dc44