Redis哨兵模式搭建.md 18 KB

关于哨兵模式的讲解,强烈推荐 【深入学习redis(4):哨兵】

Linux哨兵模式

安装Redis

  1. 下载tar安装包

  2. 解压

    tar -zxvf redis-7.0.4.tar.gz -C /usr/local/
    #重命名
    mv /usr/local/redis-7.0.4 /usr/local/redis
    
    1. 安装 shell #切换到解压目录 cd /usr/local/redis/ #编译 make #安装 make install PREFIX=/usr/local/redis

make:根据makefile文件将源代码编译成可执行文件

make install:将可执行文件及其依赖库复制到安装目录

make install PREFIX=/usr/local/redis :这里多了一个关键字 PREFIX= 用于指定程序存放的路径,可执行文件默认存放在/usr/local/bin目录,库文件默认存放在/usr/local/lib目录,配置文件默认存放在/usr/local/etc目录,这里指定好目录也方便后续的卸载,后续直接rm -rf /usr/local/redis 即可删除redis。

  1. 启动

    /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
    
    1. 登录客户端 shell /usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379

redis实例

install_server.sh 可以执行一次或多次,一个物理机可以有多个redis实例,通过port区分,可执行程序就一份在目录,但是内存中多个实例要有多个配置文件

   #执行redis自带的脚本安装实例
   /usr/local/redis/utils/install_server.sh

遇到第1个问题:

   This systems seems to use systemd.
   Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!

解决:编辑脚本,注释掉部分代码

   vim /usr/local/redis/utils/install_server.sh
   # 如下
    #bail if this system is managed by systemd/usr/local/redis/utils/install_server.sh
    #_pid_1_exe="$(readlink -f /proc/1/exe)"
    #if [ "${_pid_1_exe##*/}" = systemd ]
    #then
    #       echo "This systems seems to use systemd."
    #       echo "Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
    #       exit 1
    #fi
    #unset _pid_1_exe

执行步骤如下:

[root@VM-24-15-centos redis]#  /usr/local/redis/utils/install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] /usr/local/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] /usr/local/redis/data/6379
Please select the redis executable path [] /usr/local/redis/bin/redis-server
Selected config:
Port           : 6379
Config file    : /usr/local/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /usr/local/redis/data/6379
Executable     : /usr/local/redis/bin/redis-server
Cli Executable : /usr/local/redis/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
/var/run/redis_6379.pid exists, process is already running or crashed
Installation successful!

常用操作:

此处的service name来自上面的 Copied /tmp/6379.conf => /etc/init.d/redis_6379 ,末尾的 redis-6379 就是service name

#启动
service redis_6379 start
#关闭
service redis_6379 stop
#重启
service redis_6379 restart
#查看状态
service redis_6379 status

配置文件redis.conf

配置文件 /usr/local/redis/redis.conf ,也可以通过 redis-cli 登录成功之后,执行 config get * 查看配置项

这里列出了比较重要的配置 | 配置项名称 | 配置项值范围 | 说明 | | -------------- | ------------------------------- | ------------------------------------------------------------ | | daemonize | yes、no | yes表示启用守护进程,默认是no即不以守护进程方式运行。其中Windows系统下不支持启用守护进程方式运行 | | port | | 指定 Redis 监听端口,默认端口为 6379 | | bind | | 绑定的主机地址,如果需要设置远程访问则直接将这个属性注释掉或者改为bind * 即可,这个属性和下面的protected-mode控制了是否可以远程访问 | | protected-mode | yes 、no | 保护模式,该模式控制外部网是否可以连接redis服务,默认是yes,所以默认我们外网是无法访问的,如需外网连接rendis服务则需要将此属性改为no。 | | timeout | 300 | 当客户端闲置多长时间后关闭连接,如果指定为 0,表示关闭该功能 | | loglevel | debug、verbose、notice、warning | 日志级别,默认为 notice | | databases | 16 | 设置数据库的数量,默认的数据库是0。整个通过客户端工具可以看得到 | | rdbcompression | yes、no | 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大。 | | dbfilename | dump.rdb | 指定本地数据库文件名,默认值为 dump.rdb | | dir | | 指定本地数据库存放目录 | | requirepass | | 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH <password> 命令提供密码,默认关闭 | | maxclients | 0 | 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息。 | | maxmemory | XXX <bytes> | 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区。配置项值范围列里XXX为数值。 |

修改配置文件:

  • 将daemonize改为yes,这样启动后redis就自动后台运行了
  • 将bind 行注释掉,且将protected-mode设置为no,这样启动后就可以在外网访问了
  • 设置 requirepass redis123,这样登录时就需要密码了
  /usr/local/redis/bin/redis-cli -h ip -p 6379 -a redis123

查看redis运行状态

#查看redis进程
ps -ef | grep redis

#根据端口查看
netstat -tunlp | grep 6379

#关闭redis
#(注意,配置了 requirepass 时,使用 service redis_6379 stop 会无法关闭redis)
#登录redis客户端后,执行 shutodwn
/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a redis123

一主两从

  1. 执行 /usr/local/redis/utils/install_server.sh 安装 6379、6380、6381 三个redis实例,配置如下

    Selected config:
    Port           : 6379
    Config file    : /usr/local/redis/6379.conf
    Log file       : /var/log/redis_6379.log
    Data dir       : /usr/local/redis/data/6379
    Executable     : /usr/local/redis/bin/redis-server
    Cli Executable : /usr/local/redis/bin/redis-cli
        
        
    Selected config:
    Port           : 6380
    Config file    : /usr/local/redis/6380.conf
    Log file       : /var/log/redis_6380.log
    Data dir       : /usr/local/redis/data/6380
    Executable     : /usr/local/redis/bin/redis-server
    Cli Executable : /usr/local/redis/bin/redis-cli
        
        
    Selected config:
    Port           : 6381
    Config file    : /usr/local/redis/6381.conf
    Log file       : /var/log/redis_6381.log
    Data dir       : /usr/local/redis/data/6381
    Executable     : /usr/local/redis/bin/redis-server
    Cli Executable : /usr/local/redis/bin/redis-cli
    
  2. 分别修改配置

    • 此处省略 install_server.sh 安装redis实例时设定好了配置,比如 port、log file、data dir。
    • replicaof 是新版本的命令,旧版本是 slaveof 命令

    6379.conf

    #允许后台运行
    daemonize yes
        
    #注释掉bind
    #bind 127.0.0.1 -::1
        
    #关闭保护模式,允许行外网连接
    protected-mode no
        
    #访问密码
    requirepass redis123
    

    6380.conf

    #允许后台运行
    daemonize yes
        
    #注释掉bind
    #bind 127.0.0.1 -::1
        
    #关闭保护模式,允许行外网连接
    protected-mode no
        
    #访问密码
    requirepass redis123
        
    #主节点ip和端口
    replicaof 81.70.105.158 6379
        
    #连接主节点所使用的密码
    masterauth "redis123"
    

6381.conf

```conf
#允许后台运行
daemonize yes

#注释掉bind
#bind 127.0.0.1 -::1

#关闭保护模式,允许行外网连接
protected-mode no

#访问密码
requirepass redis123

#主节点ip和端口
replicaof 81.70.105.158 6379

#连接主节点所使用的密码
masterauth "redis123"
```
  1. 启动

    注意,首次安装redis实例后,就自动运行了,改完配置文件后需重启。

    service redis_6379 start
    service redis_6380 start
    service redis_6381 start
    
    1. 验证是否成功,看到从节点状态 online 说明主从环境搭建成功了

      [root@VM-24-15-centos redis]# /usr/local/redis/bin/redis-cli -h 81.70.105.158 -p 6379 -a redis123
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      127.0.0.1:6379> info replication
      # Replication
      role:master
      connected_slaves:2
      slave0:ip=127.0.0.1,port=6381,state=online,offset=252,lag=0
      slave1:ip=127.0.0.1,port=6380,state=online,offset=252,lag=0
      master_failover_state:no-failover
      master_replid:be99f9284866de72ad2c7e4c70c4d44cdffad263
      master_replid2:0000000000000000000000000000000000000000
      master_repl_offset:252
      second_repl_offset:-1
      repl_backlog_active:1
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:1
      repl_backlog_histlen:252
      

三个哨兵

  1. 配置三个sentinel.conf

sentinel-26379.conf

   port 26379
   daemonize yes
   logfile "/var/log/redis-sentinel-26379.log"
   sentinel monitor mymaster 81.70.105.158 6379 2
   sentinel auth-pass mymaster redis123

sentinel-26380.conf

   port 26380
   daemonize yes
   logfile "/var/log/redis-sentinel-26380.log"
   sentinel monitor mymaster 81.70.105.158 6379 2
   sentinel auth-pass mymaster redis123

sentinel-26381.conf

   port 26381
   daemonize yes
   logfile "/var/log/redis-sentinel-26381.log"
   sentinel monitor mymaster 81.70.105.158 6379 2
   sentinel auth-pass mymaster redis123
  1. 启动

哨兵节点的启动有两种方式,二者作用是完全相同的:

   #第一种启动方式
   /usr/local/redis/bin/redis-sentinel sentinel-26379.conf
   #第二种启动方式
   /usr/local/redis/bin/redis-server sentinel-26379.conf --sentinel
   
   /usr/local/redis/bin/redis-sentinel sentinel-26379.conf
   /usr/local/redis/bin/redis-sentinel sentinel-26380.conf
   /usr/local/redis/bin/redis-sentinel sentinel-26381.conf
  1. 验证是否成功,看到最后 status=ok 说明成功了

    [root@centos ~]# /usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 26379
    127.0.0.1:26379> info sentinel
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_tilt_since_seconds:-1
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=81.70.105.158:6379,slaves=2,sentinels=3
    
  2. 故障转移

关闭redis-6379节点,然后观察哨兵选出来的新master节点

   [root@centos ~]# /usr/local/redis/bin/redis-cli -h 81.70.105.158 -p 6379 -a redis123
   81.70.105.158:6379>shutdown
   
   [root@centos ~]# /usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 26379
   127.0.0.1:26379> info sentinel
   # Sentinel
   sentinel_masters:1
   sentinel_tilt:0
   sentinel_tilt_since_seconds:-1
   sentinel_running_scripts:0
   sentinel_scripts_queue_length:0
   sentinel_simulate_failure_flags:0
   master0:name=mymaster,status=ok,address=81.70.105.158:6380,slaves=2,sentinels=3

image-20220906180431684

Windows哨兵模式

https://github.com/tporadowski/redis/releases 下载windows版的redis,自行下载解压。

一主两从

  1. 复制三份 redis.windows.conf,分别如下配置

redis-6379.windows.conf

   bind 127.0.0.1
   port 6379

redis-6380.windows.conf

   bind 127.0.1
   port 6380
   slaveof 127.0.0.1 6379

redis-6381.windows.conf

   bind 127.0.1
   port 6381
   slaveof 127.0.0.1 6379
  1. 启动
   redis-server.exe redis-6379.windows.conf
   redis-server.exe redis-6380.windows.conf
   redis-server.exe redis-6381.windows.conf
  1. 验证是否成功,看到从节点状态 online 说明主从环境搭建成功了
   redis-cli.exe -h 127.0.0.1 -p 6379
   
   127.0.0.1:6379> info replication
   # Replication
   role:master
   connected_slaves:2
   slave0:ip=127.0.0.1,port=6380,state=online,offset=98,lag=0
   slave1:ip=127.0.0.1,port=6381,state=online,offset=98,lag=0
   master_replid:677245c1292f2244597f22a12c85730f236fa707
   master_replid2:0000000000000000000000000000000000000000
   master_repl_offset:98
   second_repl_offset:-1
   repl_backlog_active:1
   repl_backlog_size:1048576
   repl_backlog_first_byte_offset:1
   repl_backlog_histlen:98

三个哨兵

  1. 创建三个配置文件

sentinel-26379.windows.conf

   bind 127.0.0.1
   port 26379
   sentinel monitor mymaster 127.0.0.1 6379 2

sentinel-26380.windows.conf

   bind 127.0.0.1
   port 26380
   sentinel monitor mymaster 127.0.0.1 6379 2

sentinel-26381.windows.conf

   bind 127.0.0.1
   port 26381
   sentinel monitor mymaster 127.0.0.1 6379 2
  1. 启动哨兵
   redis-server.exe sentinel-26379.windows.conf --sentinel
   redis-server sentinel-26380.windows.conf --sentinel
   redis-server sentinel-26381.windows.conf --sentinel
  1. 验证是否成功,看到最后 status=ok 说明成功了
    127.0.0.1:26379> info sentinel
   # Sentinel
   sentinel_masters:1
   sentinel_tilt:0
   sentinel_running_scripts:0
   sentinel_scripts_queue_length:0
   sentinel_simulate_failure_flags:0
   master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
  1. 演示故障自动切换

关掉主节点 6379,等一会,就会发现哨兵切换了主节点,重新启动 6379 节点,它就变成了从节点了

   redis-cli.exe -h 127.0.0.1 -p 6379
   
   127.0.0.1:6379> info replication
   # Replication
   role:slave
   master_host:127.0.0.1
   master_port:6380
   master_link_status:up
   master_last_io_seconds_ago:1
   master_sync_in_progress:0
   slave_repl_offset:56440
   slave_priority:100
   slave_read_only:1
   connected_slaves:0
   master_replid:8f282577c2e4ddeb9794f88757e5dad7870e5e6d
   master_replid2:0000000000000000000000000000000000000000
   master_repl_offset:56440
   second_repl_offset:-1
   repl_backlog_active:1
   repl_backlog_size:1048576
   repl_backlog_first_byte_offset:55487
   repl_backlog_histlen:954

遇到的问题

代码客户端连接redis,报错 All sentinels down, cannot determine where is mymaster master is running... 或者 Could not get a resource from the pool

参考这篇博客:https://www.jianshu.com/p/098494958892

好了,认真读过 【深入学习redis(4):哨兵】 ,所以这个问题已经不再是问题了

通过客户端原理的介绍,可以加深对哨兵功能的理解:

(1)配置提供者:客户端可以通过哨兵节点+masterName获取主节点信息,在这里哨兵起到的作用就是配置提供者。

需要注意的是,哨兵只是配置提供者,而不是代理。二者的区别在于:如果是配置提供者,客户端在通过哨兵获得主节点信息后,会直接建立到主节点的连接,后续的请求(如set/get)会直接发向主节点;如果是代理,客户端的每一次请求都会发向哨兵,哨兵再通过主节点处理请求。

举一个例子可以很好的理解哨兵的作用是配置提供者,而不是代理。在前面部署的哨兵系统中,将哨兵节点的配置文件进行如下修改:

> sentinel monitor mymaster 192.168.92.128 6379 2
> 改为
> sentinel monitor mymaster 127.0.0.1 6379 2
> ```
>
> 然后,将前述客户端代码在局域网的另外一台机器上运行,会发现客户端无法连接主节点;这是因为哨兵作为配置提供者,客户端通过它查询到主节点的地址为127.0.0.1:6379,客户端会向127.0.0.1:6379建立redis连接,自然无法连接。如果哨兵是代理,这个问题就不会出现了。

注意一点:哨兵程序监控端口和 redis 服务端口都要开放给客户端,否则就访问不通。

我本地开发环境就是这种情况,可以访问通监控端口,但是无法访问redis服务端口。这也再次说明了哨兵只是配置提供者,而不是代理。

# 不停机修改密码
昨天网络安全部反馈redis服务器有弱口令漏洞隐患,要求三个工作日修复

哨兵模式

```shell
config set masterauth 新密码
config set requirepass 新密码
auth 新密码
config rewrite

# 主从节点依次执行上面的修改,修改之后redis和sentinel配置文件会自动更新为该密码。