redis默认开启了保护模式,只允许本地回环地址登录并访问数据库 修改redis的配置文件,并重启redis的服务 vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf # 绑定主机地址 bind 10.0.0.51 # 开启验证 requirepass 123456 重启redis服务 pkill redis ps -ef|grep redis redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf ps -ef|grep redis
没认证的情况
认证之后的情况
1 从10.0.0.51拷贝redis到10.0.0.52上 10.0.0.51 [root@db01 ~]# tar -czvf redis.tar.gz /opt/redis_cluster/ [root@db01 ~]# scp redis.tar.gz 10.0.0.52:/opt 2 解压压缩包 10.0.0.52 [root@db02 opt]# cd /opt/ [root@db02 opt]# tar -xf redis.tar.gz [root@db02 opt]# mv opt/* ./ [root@db02 opt]# ls opt redis_cluster redis.tar.gz [root@db02 opt]# rm -rf opt/ [root@db02 opt]# ls redis_cluster/ redis redis-3.2.9 redis_6379 [root@db02 opt]# ll redis_cluster/ lrwxrwxrwx 1 root root 31 Jan 10 11:48 redis -> /opt/redis_cluster/redis-3.2.9/ drwxrwxr-x 6 root root 309 May 17 2017 redis-3.2.9 drwxr-xr-x 5 root root 85 Jan 10 14:24 redis_6379 3 执行 make install 命令,把redis相关的命令添加的环境变量中 [root@db02 opt]# cd /opt/redis_cluster/redis-3.2.9 [root@db02 redis]# make install 4 创建数据存放目录 [root@db02 redis]# mkdir /data/redis_cluster/redis_6379 -p 5 修改配置文件 [root@db02 redis]# vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf # 绑定主机地址 bind 10.0.0.52 6 启动redis [root@db02 redis]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf [root@db02 redis]# redis-cli -h 10.0.0.52 10.0.0.52:6379> set k1 v1 OK 10.0.0.52:6379> get k1 "v1" 10.0.0.52:6379>
从库默认只有只读权限,建立主从关系后,从库默认会被清空 1 建立主从方式1 不推荐使用这种方式,因为重启主从关系失效 [root@db02 redis]# redis-cli -h 10.0.0.52 10.0.0.52:6379> SLAVEOF 10.0.0.51 6379 2 建立主从方式2: 写入从库配置文件中 [root@db02 redis]# vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf # 开启主从关系 slaveof 10.0.0.51 6379 重启redis [root@db02 redis]# pkill redis [root@db02 redis]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf [root@db02 redis]# ps -ef|grep redis 验证 [root@db02 redis]# redis-cli -h 10.0.0.52 10.0.0.52:6379> set k5 v5 (error) READONLY You can't write against a read only slave. 10.0.0.52:6379> 10.0.0.52:6379> keys * 1) "k3" 2) "k2" 3) "k1" 10.0.0.52:6379>
流程 1)从服务器连接主服务器,发送SYNC命令; 2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令; 3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
1. 执行主从复制前,将现有的数据备份一份到其他目录 2. 建议将主从复制写入到配置文件中 3. 在业务低峰时期做主从复制 4. 拷贝数据会占用服务器资源 5. 不能自动完成主从切换,需要人工介入
[root@db02 redis_6379]# redis-cli -h 10.0.0.52 10.0.0.52:6379> SLAVEOF no one
哨兵模式也要基于主从复制模式 redis的主从模式下,主节点一旦发送故障不能提供服务,需要人工干预,将从节点升为主节点,同时,还需要修改客户端配置,对于很多的应用场景这种方式无法接受 Sentinel(哨兵)架构解决了 redis 主从需要人工干预的问题 哨兵模式是redis的高可用实现方案,实际生产环境中,对提高整个系统可用性非常有帮助的 特点 1. 监控:哨兵会不断的定期检查你的主服务器和从服务器是否都运作正常 2. 提醒:当监控到某个redis服务器出现问题时, 哨兵可以通过 api 向管理员或者其他应用程序发送通知 3. 自动故障迁移 :当主服务器不能正常工作时,哨兵会开始一次自动故障迁移
需要三台服务器 10.0.0.51 主 10.0.0.52 从 10.0.0.53 从 注意这里也要部署一下redis基础环境,和10.0.0.52部署的时候一样 | 角色 | IP | 端口 | | ----------- | --------- | ----- | | Master | 10.0.0.51 | 6379 | | Sentinel-01 | 10.0.0.51 | 26379 | | slave | 10.0.0.52 | 6379 | | Sentinel-02 | 10.0.0.52 | 26379 | | slave | 10.0.0.53 | 6379 | | Sentinel-03 | 10.0.0.53 | 26379 |
1 10.0.0.51 主服务器
[root@db01 ~]# mkdir -p /data/redis_cluster/redis_26379/ [root@db01 ~]# mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs} [root@db01 ~]# vim /opt/redis_cluster/redis_26379/conf/redis_26379.conf bind 10.0.0.51 port 26379 daemonize yes logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log dir /data/redis_cluster/redis_26379/ # master 主节点别名 主节点IP 端口,需要2个 sentinel 节点同意 sentinel monitor mymaster 10.0.0.51 6379 2 # 选项指定了 sentinel 意味服务器已经断线所需的毫秒数 sentinel down-after-milliseconds mymaster 3000 # 向新的主节点发起复制操作的从服务器个数,1: 轮询发起复制 # 轮询发起复制的好处,降低主节点的开销 sentinel parallel-syncs mymaster 1 # 故障转移超时时间 sentinel failover-timeout mymaster 18000 启动 [root@db01 ~]# redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf [root@db01 ~]# ps -ef|grep redis root 7622 1 0 10:01 ? 00:00:05 redis-server 10.0.0.51:6379 root 7816 1 0 10:58 ? 00:00:01 redis-sentinel 10.0.0.51:26379 [sentinel]
2 10.0.0.52 从服务器
[root@db02 ~]# mkdir -p /data/redis_cluster/redis_26379/ [root@db02 ~]# mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs} [root@db02 ~]# vim /opt/redis_cluster/redis_26379/conf/redis_26379.conf bind 10.0.0.52 port 26379 daemonize yes logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log dir /data/redis_cluster/redis_26379/ # master 主节点别名 主节点IP 端口,需要2个 sentinel 节点同意 sentinel monitor mymaster 10.0.0.51 6379 2 # 选项指定了 sentinel 惹味服务器已经断线所需的毫秒数 sentinel down-after-milliseconds mymaster 3000 # 向新的主节点发起复制操作的丛及诶单个数,1 轮询发起复制 sentinel parallel-syncs mymaster 1 # 故障转移超时时间 sentinel failover-timeout mymaster 18000 启动 [root@db02 ~]# redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf [root@db02 ~]# ps -ef|grep redis root 12415 1 0 10:01 ? 00:00:05 redis-server 10.0.0.52:6379 root 12616 1 0 11:04 ? 00:00:00 redis-sentinel 10.0.0.52:26379 [sentinel]
3 10.0.0.53 从服务器
[root@db02 ~]# mkdir -p /data/redis_cluster/redis_26379/ [root@db02 ~]# mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs} [root@db02 ~]# vim /opt/redis_cluster/redis_26379/conf/redis_26379.conf bind 10.0.0.53 port 26379 daemonize yes logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log dir /data/redis_cluster/redis_26379/ # master 主节点别名 主节点IP 端口,需要2个 sentinel 节点同意 sentinel monitor mymaster 10.0.0.51 6379 2 # 选项指定了 sentinel 惹味服务器已经断线所需的毫秒数 sentinel down-after-milliseconds mymaster 3000 # 向新的主节点发起复制操作的丛及诶单个数,1 轮询发起复制 sentinel parallel-syncs mymaster 1 # 故障转移超时时间 sentinel failover-timeout mymaster 18000 启动 [root@db03 ~]# redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf [root@db03 ~]# ps -ef |grep redis root 7565 1 0 10:46 ? 00:00:01 redis-server 10.0.0.53:6379 root 7618 1 0 11:04 ? 00:00:00 redis-sentinel 10.0.0.53:26379 [sentinel]
当所有的节点都启动后,配置文件发生了变化,体现在三个方面 1. sentinel 节点自动发现了从节点 2. 去掉了默认的配置,例如 sentinel parallel-syncs mymaster 1 参数 3. 添加了配置记录相关参数
[root@db01 ~]# redis-cli -h 10.0.0.51 -p 26379 10.0.0.51: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=10.0.0.51:6379,slaves=2,sentinels=3 [root@db02 ~]# redis-cli -h 10.0.0.52 -p 26379 10.0.0.52: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=10.0.0.51:6379,slaves=2,sentinels=3 10.0.0.52:26379>
在 10.0.0.51 主服务器上 [root@db01 ~]# pkill redis [root@db01 ~]# ps -ef|grep reids root 7903 7262 0 11:17 pts/0 00:00:00 grep --color=auto reids 在 10.0.0.52 服务器上查看(从这里可以看出 10.0.0.53 成为了主服务器) [root@db02 ~]# redis-cli -h 10.0.0.52 -p 26379 10.0.0.52: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=10.0.0.53:6379,slaves=2,sentinels=3 10.0.0.52:26379>
10.0.0.51 上启动redis和sentinel服务 [root@db01 ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf [root@db01 ~]# redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf [root@db01 ~]# ps -ef|grep redis root 7930 1 0 11:25 ? 00:00:00 redis-server 10.0.0.51:6379 root 7947 1 0 11:25 ? 00:00:00 redis-sentinel 10.0.0.51:26379 [sentinel] [root@db01 ~]# redis-cli -h 10.0.0.51 -p 26379 10.0.0.51: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=10.0.0.53:6379,slaves=2,sentinels=3 10.0.0.51:26379> 从上可以看出主节点还在 10.0.0.53 上,我们手动切回10.0.0.51 redis sentinel 存在多个从节点时,如果想将指定的从节点升为主节点,可以将其他节点的 slavepriority 配置为0,但是需要注意 failover后,将 slave-priority 调回原来值 查看 slave-priority 值 [root@db02 ~]# redis-cli -h 10.0.0.52 10.0.0.52:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "100" 设置 slave-priority 值(10.0.0.52 10.0.0.53 都要设置) [root@db02 ~]# redis-cli -h 10.0.0.52 10.0.0.52:6379> CONFIG GET slave-priority 10.0.0.52:6379> CONFIG SET slave-priority 0 OK 10.0.0.52:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "0" [root@db03 ~]# redis-cli -h 10.0.0.53 10.0.0.53:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "100" 10.0.0.53:6379> CONFIG SET slave-priority 0 OK 10.0.0.53:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "0" [root@db03 ~]# redis-cli -h 10.0.0.53 -p 26379 10.0.0.53:26379> sentinel failover mymaster OK 10.0.0.53: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=10.0.0.51:6379,slaves=2,sentinels=3 可以看到已经把 主服务器切回到 10.0.0.51 上了 恢复 10.0.0.52 10.0.0.53 上的 slave-priority 值 [root@db02 ~]# redis-cli -h 10.0.0.52 10.0.0.52:6379> CONFIG SET slave-priority 100 OK 10.0.0.52:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "100" [root@db03 ~]# redis-cli -h 10.0.0.53 -p 6379 10.0.0.53:6379> CONFIG SET slave-priority 100 OK 10.0.0.53:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "100"
https://www.cnblogs.com/kevingrace/p/9004460.html 客户端配置连接的是sentinel信息,比如连接sentinel.conf文件中定义的master名称。在sentinel监听时,当master节点挂了,它会在slave节点中自动选举出新 的master节点,而当挂了的老master节点重新恢复后就会成为新的slave节点。对于客户端来说,redis主从切换后它不需要修改连接配置。 python连接redis sentinel集群(需要安装python redis客户端,即执行"pip install redis") #!/usr/bin/env python # -*- coding:utf-8 -*- import redis from redis.sentinel import Sentinel # 连接哨兵服务器(主机名也可以用域名) sentinel = Sentinel([('192.168.10.202', 26379), ('192.168.10.203', 26379), ('192.168.10.205', 26379)], socket_timeout=0.5) # 获取主服务器地址 master = sentinel.discover_master('mymaster') print(master) # 输出:('192.168.10.202', 26379) # 获取从服务器地址 slave = sentinel.discover_slaves('mymaster') print(slave) # 输出:[('192.168.10.203', 26379), ('192.168.10.205', 26379), ('172.31.0.5', 26379)] # 获取主服务器进行写入 master = sentinel.master_for('mymaster', socket_timeout=0.5, password='redis_auth_pass', db=15) w_ret = master.set('foo', 'bar') # 输出:True # # 获取从服务器进行读取(默认是round-roubin) slave = sentinel.slave_for('mymaster', socket_timeout=0.5, password='redis_auth_pass', db=15) r_ret = slave.get('foo') print(r_ret) # # 输出:bar