@zhangsiming65965
2019-02-14T03:22:38.000000Z
字数 15308
阅读 215
云计算
如果有梦想,就放开的去追;
因为只有奋斗,才能改变命运。
主机名 | IP | 用途 |
---|---|---|
Redis01 | 192.168.17.250 | Redis-Master |
Redis02 | 192.168.17.251 | Redis-Slave1 |
Redis03 | 192.168.17.252 | Redis-Slave2 |
[root@ZhangSiming ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@ZhangSiming ~]# uname -r
3.10.0-862.el7.x86_64
[root@ZhangSiming ~]# systemctl stop firewalld
[root@ZhangSiming ~]# systemctl disable firewalld
[root@ZhangSiming ~]# getenforce 0
Disabled
[root@Zhangsiming zhangsiming]# cat redis.yaml
---
- hosts: Nginx
remote_user: root
gather_facts: True
roles:
- redis
[root@Zhangsiming zhangsiming]# cat roles/redis/tasks/main.yaml
---
- name: transfer
copy: src=redis-4.0.11.tar.gz dest=/tmp/
- name: install
script: redis.sh
- name: config
copy: src=redis.conf dest=/usr/local/redis/conf/redis.conf
- name: data dir
file: path=/data/redis/ state=directory owner=root group=root
- name: youhua
copy: src=limits.conf dest=/etc/security/limits.conf
- name: youhua1
shell: echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf
- name: youhua2
shell: echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
- name: youhua3
shell: echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local ; echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local ; echo never > /sys/kernel/mm/transparent_hugepage/enabled ; echo never > /sys/kernel/mm/transparent_hugepage/defrag
.
├── redis.yaml
└── roles
└── redis
├── files
│ ├── limits.conf
│ ├── redis-4.0.11.tar.gz
│ ├── redis.conf
│ └── redis.sh
└── tasks
└── main.yaml
4 directories, 6 files
[root@Zhangsiming zhangsiming]# ansible-playbook redis.yaml
PLAY [Nginx] ***********************************************************************
TASK [Gathering Facts] *************************************************************
ok: [web01]
ok: [web02]
ok: [web03]
TASK [redis : transfer] ************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : install] *************************************************************
changed: [web02]
changed: [web01]
changed: [web03]
TASK [redis : config] **************************************************************
changed: [web03]
changed: [web01]
changed: [web02]
TASK [redis : data dir] ************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : youhua] **************************************************************
changed: [web01]
changed: [web02]
changed: [web03]
TASK [redis : youhua1] *************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : youhua2] *************************************************************
changed: [web01]
changed: [web02]
changed: [web03]
TASK [redis : youhua3] *************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : youhua4] *************************************************************
changed: [web01]
changed: [web02]
changed: [web03]
TASK [redis : youhua5] *************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
PLAY RECAP *************************************************************************
web01 : ok=11 changed=10 unreachable=0 failed=0
web02 : ok=11 changed=10 unreachable=0 failed=0
web03 : ok=11 changed=10 unreachable=0 failed=0
#成功部署
注意:由于sysctl -p ,exit等命令不能在剧本中执行,所以需要到每个节点手动执行
[root@ZhangSiming ~]# sysctl -p
net.core.somaxconn = 10240
vm.overcommit_memory = 1
[root@ZhangSiming ~]# exit
logout
#执行完毕启动redis-server,查看日志文件
[root@ZhangSiming ~]# redis-server /usr/local/redis/conf/redis.conf
[root@ZhangSiming ~]# netstat -antup | grep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 15888/redis-server
[root@ZhangSiming ~]# cat /data/redis/redis.log
15887:C 10 Feb 13:01:32.314 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
15887:C 10 Feb 13:01:32.314 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=15887, just started
15887:C 10 Feb 13:01:32.314 # Configuration loaded
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.11 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 15888
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
15888:M 10 Feb 13:01:32.317 # Server initialized
15888:M 10 Feb 13:01:32.318 * Ready to accept connections
#启动成功,日志没有警告(已经优化完毕)
开启方法很简单,只需在从库指定主库的IP和端口即可。
[root@ZhangSiming ~]# tail -1 /usr/local/redis/conf/redis.conf
SLAVEOF 192.168.17.250 6379
#指定完主库IP端口,重启Redis
[root@ZhangSiming ~]# redis-cli shutdown
[root@ZhangSiming ~]# redis-server /usr/local/redis/conf/redis.conf
[root@ZhangSiming ~]# redis-cli slaveof 192.168.17.134 6379
OK
#开启主从复制
[root@ZhangSiming ~]# cat /data/redis/redis.log
...省略...
16103:S 10 Feb 14:57:40.045 * Full resync from master: 196da898afbb5c81683dcb7b8e6bc29a1dbcb570:1069
16103:S 10 Feb 14:57:40.045 * Discarding previously cached master state.
16103:S 10 Feb 14:57:40.076 * MASTER <-> SLAVE sync: receiving 197 bytes from master
16103:S 10 Feb 14:57:40.076 * MASTER <-> SLAVE sync: Flushing old data
16103:S 10 Feb 14:57:40.077 * MASTER <-> SLAVE sync: Loading DB in memory
16103:S 10 Feb 14:57:40.077 * MASTER <-> SLAVE sync: Finished with success
#开启主从复制且为全部模式
如果从来没有同步过数据,会完整地把主库的所有数据同步过来,这种方式叫主从全部同步;
如果曾经同步过一些数据,就会有一些主库数据的缓存,就可以增量同步新增加的部分过来到从库,这种方式叫主从部分同步。
[root@ZhangSiming ~]# cat /data/redis/redis.log
...省略...
16088:S 10 Feb 14:44:15.127 * Connecting to MASTER 192.168.17.250:6379
16088:S 10 Feb 14:44:15.127 * MASTER <-> SLAVE sync started
16088:S 10 Feb 14:44:15.128 * Non blocking connect for SYNC fired the event.
16088:S 10 Feb 14:44:15.128 * Master replied to PING, replication can continue...
16088:S 10 Feb 14:44:15.129 * Partial resynchronization not possible (no cached master)
16088:S 10 Feb 14:44:15.129 * Full resync from master: 196da898afbb5c81683dcb7b8e6bc29a1dbcb570:644
...省略...
#这种日志显示表示是一个主从全部同步,即从库没有缓存
[root@ZhangSiming ~]# cat /data/redis/redis.log
...省略...
16103:S 10 Feb 14:45:13.859 * Trying a partial resynchronization (request 196da898afbb5c81683dcb7b8e6bc29a1dbcb570:776).
16103:S 10 Feb 14:45:13.860 * Successful partial resynchronization with master.
16103:S 10 Feb 14:45:13.860 * MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.
...省略...
#这种日志显示表示是一个主从部分同步,即从库有缓存
关闭主从复制只需要交互界面输入:redis-cli slaveof no one。
[root@ZhangSiming ~]# redis-cli slaveof no one
OK
#关闭主从复制
[root@ZhangSiming ~]# cat /data/redis/redis.log
...省略...
16103:M 10 Feb 14:56:36.385 * MASTER MODE enabled (user request from 'id=4 addr=127.0.0.1:35242 fd=8 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
#启动了主动模式
MySQL主从复制从库找主库连接都需要验证账户,Redis同样可以设置。
[root@ZhangSiming ~]# redis-cli config set requirepass 666666
OK
[root@ZhangSiming ~]# redis-cli -a 666666 config rewrite
Warning: Using a password with '-a' option on the command line interface may not be safe.
OK
#设置密码为666666
[root@ZhangSiming ~]# redis-cli config set masterauth "666666"
OK
[root@ZhangSiming ~]# redis-cli config rewrite
OK
#添加验证成功
#看一下从库日志
[root@ZhangSiming ~]# cat /data/redis/redis.log
...省略...
16028:S 10 Feb 15:07:33.540 # Error condition on socket for SYNC: No route to host
16028:S 10 Feb 15:07:33.642 * Connecting to MASTER 192.168.17.250:6379
16028:S 10 Feb 15:07:33.642 * MASTER <-> SLAVE sync started
16028:S 10 Feb 15:07:36.546 # Error condition on socket for SYNC: No route to host
16028:S 10 Feb 15:07:36.660 * Connecting to MASTER 192.168.17.250:6379
16028:S 10 Feb 15:07:36.660 * MASTER <-> SLAVE sync started
#之前因为没有auth验证找主库一直返回"No route to host",验证之后才开始主从同步
当系统中只有一台redis运行时,一旦该redis挂了,会导致整个系统无法运行;
于是我们架构Redis主从复制架构,进行数据备份,保证了安全性。
主从复制的Redis虽然有备份冗余,但是一旦主Redis宕机的话,就会使整个主从复制体系因为没有主Redis而崩溃;
Redis-Sentinel就是当主Redis挂了,让从Redis升级成为主Redis的一种高可用方案
#利用ansible-playbook一键部署
[root@Zhangsiming zhangsiming]# ansible-playbook redis.yaml
PLAY [Nginx] ***********************************************************************
TASK [Gathering Facts] *************************************************************
ok: [web01]
ok: [web02]
ok: [web03]
TASK [redis : transfer] ************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : install] *************************************************************
changed: [web02]
changed: [web01]
changed: [web03]
TASK [redis : config] **************************************************************
changed: [web03]
changed: [web01]
changed: [web02]
TASK [redis : data dir] ************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : youhua] **************************************************************
changed: [web01]
changed: [web02]
changed: [web03]
TASK [redis : youhua1] *************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : youhua2] *************************************************************
changed: [web01]
changed: [web02]
changed: [web03]
TASK [redis : youhua3] *************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
TASK [redis : youhua4] *************************************************************
changed: [web01]
changed: [web02]
changed: [web03]
TASK [redis : youhua5] *************************************************************
changed: [web02]
changed: [web03]
changed: [web01]
PLAY RECAP *************************************************************************
web01 : ok=11 changed=10 unreachable=0 failed=0
web02 : ok=11 changed=10 unreachable=0 failed=0
web03 : ok=11 changed=10 unreachable=0 failed=0
#成功部署
[root@ZhangSiming ~]# redis-cli slaveof 192.168.17.134 6379
OK Already connected to specified master
[root@ZhangSiming ~]# redis-cli config set masterauth "666666"
OK
[root@ZhangSiming ~]# redis-cli config rewrite
OK
#从库添加验证密码,开启主从复制
#主库查看主从复制信息
[root@ZhangSiming ~]# redis-cli -a 666666 info replication
Warning: Using a password with '-a' option on the command line interface may not be safe.
# Replication
role:master
#自身是master
connected_slaves:2
#连接到两个从库
slave0:ip=192.168.17.253,port=6379,state=online,offset=1895,lag=0
slave1:ip=192.168.17.148,port=6379,state=online,offset=1895,lag=0
#这两条是从库的IP端口
master_replid:196da898afbb5c81683dcb7b8e6bc29a1dbcb570
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1895
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1895
[root@ZhangSiming ~]# cd /usr/local/redis/conf/
[root@ZhangSiming conf]# ls
redis.conf sentinel.conf
[root@ZhangSiming conf]# vim sentinel.conf
[root@ZhangSiming conf]# sed -n "21p;69p;98p;106p;131p;206p;207p;208p;209p" sentinel.conf
port 6800
#sentinel监听6800端口
sentinel monitor mymaster 192.168.17.134 6379 2
#监听主从复制master为192.168.17.134机器,6379端口,2表示同时两台sentinel发现问题就进行故障转移
sentinel down-after-milliseconds mymaster 5000
#master节点宕机多少时间后检查
sentinel parallel-syncs mymaster 1
#减轻master压力
sentinel failover-timeout mymaster 15000
#故障转移超时时间
daemonize yes
#守护进程模式
logfile "/var/log/redis/sentinel.log"
#Sentinel日志文件,记得提前创建/var/log/redis/目录
pidfile "/var/run/sentinel.pid"
#SentinelPID文件
protected-mode no
#禁止保护模式
[root@ZhangSiming conf]# redis-sentinel /usr/local/redis/conf/sentinel.conf
[root@ZhangSiming conf]# redis-cli -p 6800 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=192.168.17.134:6379,slaves=2,sentinels=3
#master下有两个从库,三个哨兵监控master节点存活
#注意,主从复制必须开
[root@ZhangSiming conf]# redis-cli -p 6379 shutdown
#停掉redis主从复制master节点
[root@ZhangSiming conf]# cat /var/log/redis/sentinel.log
23233:X 10 Feb 16:29:13.113 # +sdown master mymaster 192.168.17.134 6379
23233:X 10 Feb 16:29:13.187 # +new-epoch 1
23233:X 10 Feb 16:29:13.187 # +vote-for-leader c2f28b2bfbfdf33253e0731bdef987fcd0af077d 1
23233:X 10 Feb 16:29:13.980 # +config-update-from sentinel c2f28b2bfbfdf33253e0731bdef987fcd0af077d 192.168.17.253 6800 @ mymaster 192.168.17.134 6379
23233:X 10 Feb 16:29:13.980 # +switch-master mymaster 192.168.17.134 6379 192.168.17.148 6379
#观察sentinel日志,发现自动转移master为192.168.17.148
23233:X 10 Feb 16:29:13.981 * +slave slave 192.168.17.253:6379 192.168.17.253 6379 @ mymaster 192.168.17.148 6379
23233:X 10 Feb 16:29:13.981 * +slave slave 192.168.17.134:6379 192.168.17.134 6379 @ mymaster 192.168.17.148 6379
[root@ZhangSiming conf]# redis-cli -p 6800 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=192.168.17.148:6379,slaves=2,sentinels=3
#info sentinel中查看果然192.168.17.148变为了新的主从复制master,被继续监控
[root@ZhangSiming conf]# redis-server /usr/local/redis/conf/redis.conf
[root@ZhangSiming ~]# redis-cli -p 6379 shutdown
#启动原来的主机,把新的master宕掉
[root@ZhangSiming conf]# redis-cli -p 6800 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=192.168.17.134:6379,slaves=2,sentinels=3
#Redis主从复制master又变回来了
上述方式已经实现了Redis主从复制master节点的高可用,可以在master节点宕机的时候自动提升一个从节点为master主节点;
但是这总方法会改变开发连接的IP地址,事实上Redis虽然高可用了,但是IP地址来回变,这也是麻烦的;
所以可以写一个VIP漂移脚本,使得即使Redismaster宕机了,用户或者开发访问的VIP始终不变。
[root@ZhangSiming conf]# tail -1 /usr/local/redis/conf/sentinel.conf
sentinel client-reconfig-script mymaster /usr/local/redis/mymaster.sh
#指定漂移VIP脚本的路径
[root@ZhangSiming conf]# cat /usr/local/redis/mymaster.sh
#!/bin/bash
MASTER_IP=$6
#$6为Sentinel检测到需要切换master时候传入的参数,为新的masterIP地址
LOCAL_IP="192.168.17.134"
#服务器自身的IP,每个Sentinel服务器不同
VIP="192.168.17.177"
#自己设置的VIP
NETMASK="24"
INTERFACE="ens32"
if [ "${MASTER_IP}" == "${LOCAL_IP}" ];then
/usr/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
#上VIP
/usr/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
#使网卡配置立即生效
exit 0
else
/usr/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
#下VIP
exit 0
fi
exit1
[root@ZhangSiming conf]# redis-cli -p 6800 shutdown
[root@ZhangSiming conf]# redis-sentinel /usr/local/redis/conf/sentinel.conf
#重启Redis-Sentinel
[root@ZhangSiming conf]# redis-cli -p 6800 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=192.168.17.134:6379,slaves=2,sentinels=3
#查看info sentinel
[root@ZhangSiming conf]# ip addr add 192.168.17.177/24 dev ens32
[root@ZhangSiming conf]# arping -q -c 3 -A 192.168.17.177 -I ens32
#第一次先在master上添加VIP,并立即生效
[root@ZhangSiming conf]# ip addr show ens32 | grep 192.168.17
inet 192.168.17.134/24 brd 192.168.17.255 scope global noprefixroute dynamic ens32
inet 192.168.17.177/24 scope global secondary ens32
#停止Redis-server的服务
[root@ZhangSiming ~]# redis-cli -p 6379 shutdown
[root@ZhangSiming ~]# redis-cli -p 6800 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=192.168.17.253:6379,slaves=2,sentinels=3
[root@ZhangSiming ~]# ip addr show ens32 | grep 192.168
inet 192.168.17.134/24 brd 192.168.17.255 scope global noprefixroute dynamic ens32
#master切换为192.168.17.253,VIP也在这里消失了
#切换为192.168.17.253查看
[root@ZhangSiming ~]# ip addr show ens32 | grep 192.168
inet 192.168.17.253/24 brd 192.168.17.255 scope global noprefixroute dynamic ens32
inet 192.168.17.177/24 scope global secondary ens32
#出现VIP,VIP漂移成功
最后的最后,一定要注意每个Sentinel哨兵的ID不能相同,否则info Sentinel检测不出来,也不能实现Redis高可用故障转移!!!