关于哨兵模式的讲解,强烈推荐 【深入学习redis(4):哨兵】
解压
tar -zxvf redis-7.0.4.tar.gz -C /usr/local/
#重命名
mv /usr/local/redis-7.0.4 /usr/local/redis
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。
启动
/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
shell
/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379
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
配置文件 /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为数值。 |
修改配置文件:
/usr/local/redis/bin/redis-cli -h ip -p 6379 -a redis123
#查看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
执行 /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
分别修改配置
- 此处省略 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"
```
启动
注意,首次安装redis实例后,就自动运行了,改完配置文件后需重启。
service redis_6379 start service redis_6380 start service redis_6381 start
验证是否成功,看到从节点状态 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
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
哨兵节点的启动有两种方式,二者作用是完全相同的:
#第一种启动方式
/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
验证是否成功,看到最后 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
故障转移
关闭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
从 https://github.com/tporadowski/redis/releases 下载windows版的redis,自行下载解压。
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
redis-server.exe redis-6379.windows.conf
redis-server.exe redis-6380.windows.conf
redis-server.exe redis-6381.windows.conf
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
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
redis-server.exe sentinel-26379.windows.conf --sentinel
redis-server sentinel-26380.windows.conf --sentinel
redis-server sentinel-26381.windows.conf --sentinel
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
关掉主节点 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配置文件会自动更新为该密码。