Redis 是我们当下比较流行使用的非关系数据库, 可支持多样化的数据类型, 多线程高并发支持, redis 运行在内存拥有更快的读写因为 redis 的表现如此出色, 如何能保障 redis 在运行中能够应对宕机故障,
Redis 特点
Redis 是完全开源免费的, 遵守 BSD 协议, 是一个高性能的 key-value 数据库
Redis 与其他 key - value 缓存产品有以下三个特点:
Redis 支持数据的持久化, 可以将内存中的数据保持在磁盘中, 重启的时候可以再次加载进行使用
Redis 不仅仅支持简单的 key-value 类型的数据, 同时还提供如: 字符串 (String), 哈希(Map), 列表(list), 集合(sets) 和有序集合(sorted sets) 等数据结构的存储
Redis 支持数据的备份, 即 master-slave 模式的数据备份
Redis 优势
性能极高 Redis 能读的速度是 100K + 次 / s, 写的速度是 80K + 次 / s
丰富的数据类型 Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作
原子 Redis 的所有操作都是原子性的, 同时 Redis 还支持对几个操作全并后的原子性执行
丰富的特性 Redis 还支持 publish/subscribe, 通知, key 过期等等特性
准备环境
CentOS7 --> 172.16.81.140 -->主 Redis -->主 Keepalived
CentOS7 --> 172.16.81.141 -->从 Redis -->备 Keepalived
- VIP --> 172.16.81.139
- redis(一般 3.0 版本以上都行)
- KeepAlived(直接在线安装的)
Redis 编译安装
1 提前准备好的 redis 软件放在 / opt 目录下: redis-4.0.6.tar.gz
- cd /opt
- tar -zxvf redis-4.0.6.tar.gz
- mv redis-4.0.6 redis
- cd redis
- makeMALLOC=libc
- make PREFIX=/usr/local/redis install
2 配置 redis 启动脚本
- vim /etc/init.d/redis
- #!/bin/sh
- #chkconfig:2345 80 90
- # Simple Redisinit.d script conceived to work on Linux systems
- # as it doeSUSE of the /proc filesystem.
- # 配置 redis 端口号
- REDISPORT=6379
- # 配置 redis 启动命令路径
- EXE=/usr/local/redis/bin/redis-server
- # 配置 redis 连接命令路径
- CLIEXE=/usr/local/redis/bin/redis-cli
- # 配置 redis 运行 PID 路径
- PIDFILE=/var/run/redis_6379.pid
- # 配置 redis 的配置文件路径
- CONF="/etc/redis/redis.conf"
- # 配置 redis 的连接认证密码
- REDISPASSWORD=123456
- function start () {
- if [ -f $PIDFILE ]
- then
- echo "$PIDFILE exists,process is already running or crashed"
- else
- echo "Starting Redisserver..."
- $EXE $CONF &
- fi
- }
- function stop () {
- if [ ! -f $PIDFILE ]
- then
- echo "$PIDFILE does not exist, process is not running"
- else
- PID=$(cat $PIDFILE)
- echo "Stopping ..."
- $CLIEXE -p $REDISPORT -a $REDISPASSWORD shutdown
- while [ -x /proc/${PID} ]
- do
- echo "Waiting forRedis to shutdown ..."
- sleep 1
- done
- echo "Redis stopped"
- fi
- }
- function restart () {
- stop
- sleep 3
- start
- }
- case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- *)
- echo -e "\e[31m Please use $0 [start|stop|restart] asfirst argument \e[0m"
- ;;
- esac
授予执行权限:
chmod +x /etc/init.d/redis
添加开机启动:
- chkconfig --add redis
- chkconfig redis on
查看: chkconfig --list | grep redis
此次试验事先关闭了防火墙和 selinux, 生产环境建议开启防火墙
3 添加 redis 命令环境变量
- #vi /etc/profile
- # 添加下一行参数
- exportPATH="$PATH:/usr/local/redis/bin"
- # 环境变量生效
- source /etc/profile
4 启动 redis 服务
- service redis start
- # 检查启动情况
- ps -ef | grep redis
注: 在我们两台服务器上先执行同样的操作安装完成 redis, 接下来安装完成后, 就直接进入配置主从环境
Redis 主从配置
引申回到前面的设计模式, 我们的思路是以 140 作为主, 141 作为从, 139 作为 VIP 飘逸地址, 应用通过 139 的 6379 端口访问 redis 数据库
正常运行下, 当主节点 140 宕机后, VIP 飘逸到 141 上, 这时 141 就会接管 140 成为主节点, 140 就会成为从节点, 继续提供读写操作
当 140 恢复正常后, 这时 140 会与 141 进行一次数据同步, 140 原有的数据不会丢失, 还会同步宕机之间已经写入到 141 的数据, 数据同步完成之后,
VIP 会因为权重的原因重新回到 140 节点上并成为主节点, 141 会因为失去 VIP 会重新成为从节点, 恢复到初始状态继续提供不间断的读写服务
1 配置 redis 的配置文件
Master-140 配置文件
- vim /etc/redis/redis.conf
- bind 0.0.0.0
- port 6379
- daemonize yes
- requirepass 123456
- slave-serve-stale-data yes
- slave-read-only no
Slave-141 配置文件
- vim /etc/redis/redis.conf
- bind 0.0.0.0
- port 6379
- daemonize yes
- slaveof 172.16.81.140 6379
- masterauth 123456
- slave-serve-stale-data yes
- slave-read-only no
2 配置完成后重启 redis 服务! 验证主从是否正常
主节点 140 终端登录测试:
- [root@localhost ~]# redis-cli -a 123456
- 127.0.0.1:6379> INFO
- .
- .
- .
- # Replication
- role:master
- connected_slaves:1
- slave0:ip=172.16.81.141,port=6379,state=online,offset=105768,lag=1
- master_replid:f83fcc3c98614d770f2205831fef1e877fa3f482
- master_replid2:1f25604997a4ad3eb8344e8155990e78acd93312
- master_repl_offset:105768
- second_repl_offset:447
- repl_backlog_active:1
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:447
- repl_backlog_histlen:105322
从节点 141 终端登录测试:
- [root@localhost ~]# redis-cli -a 123456
- 127.0.0.1:6379> info
- .
- .
- .
- # Replication
- role:slave
- master_host:172.16.81.140
- master_port:6379
- master_link_status:up
- master_last_io_seconds_ago:5
- master_sync_in_progress:0
- slave_repl_offset:105992
- slave_priority:100
- slave_read_only:0
- connected_slaves:0
- master_replid:f83fcc3c98614d770f2205831fef1e877fa3f482
- master_replid2:1f25604997a4ad3eb8344e8155990e78acd93312
- master_repl_offset:105992
- second_repl_offset:447
- repl_backlog_active:1
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:239
- repl_backlog_histlen:105754
3 同步测试
主节点 140
从节点 141
到此 redis 的主从已经完成!
KeepAlived 配置实现双机热备
使用 Keepalived 实现 VIP, 并且通过 notify_masternotify_backupnotify_faultnotify_stop 来实现容灾
1 配置 Keepalived 配置文件
主 Keepalived 配置文件
- vim /etc/keepalived/keepalived.conf
- ! Configuration File for keepalived
- global_defs {
- notification_email {
- acassen@firewall.loc
- failover@firewall.loc
- sysadmin@firewall.loc
- }
- notification_email_from Alexandre.Cassen@firewall.loc
- smtp_server 192.168.200.1
- smtp_connect_timeout 30
- router_id redis01
- }
- vrrp_script chk_redis {
- script "/etc/keepalived/script/redis_check.sh"
- interval 2
- }
- vrrp_instance VI_1 {
- state MASTER
- interface eno16777984
- virtual_router_id 51
- priority 100
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 1111
- }
- track_script {
- chk_redis
- }
- virtual_ipaddress {
- 172.16.81.139
- }
- notify_master /etc/keepalived/script/redis_master.sh
- notify_backup /etc/keepalived/script/redis_backup.sh
- notify_fault /etc/keepalived/script/redis_fault.sh
- notify_stop /etc/keepalived/script/redis_stop.sh
- }
备用 Keepalived 配置文件
- vim /etc/keepalived/keepalived.conf
- ! Configuration File for keepalived
- global_defs {
- notification_email {
- acassen@firewall.loc
- failover@firewall.loc
- sysadmin@firewall.loc
- }
- notification_email_from Alexandre.Cassen@firewall.loc
- smtp_server 192.168.200.1
- smtp_connect_timeout 30
- router_id redis02
- }
- vrrp_script chk_redis {
- script "/etc/keepalived/script/redis_check.sh"
- interval 2
- }
- vrrp_instance VI_1 {
- state BACKUP
- interface eno16777984
- virtual_router_id 51
- priority 99
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 1111
- }
- track_script {
- chk_redis
- }
- virtual_ipaddress {
- 172.16.81.139
- }
- notify_master /etc/keepalived/script/redis_master.sh
- notify_backup /etc/keepalived/script/redis_backup.sh
- notify_fault /etc/keepalived/script/redis_fault.sh
- notify_stop /etc/keepalived/script/redis_stop.sh
- }
2 配置脚本
Master KeepAlived -- 140
创建存放脚本目录: mkdir -p /etc/keepalived/script/
- cd /etc/keepalived/script/
- [root@localhost script]# cat redis_check.sh
- #!/bin/bash
- ALIVE=`/usr/local/redis/bin/redis-cli -a 123456 PING`
- if [ "$ALIVE" == "PONG" ];then
- echo $ALIVE
- exit 0
- else
- echo $ALIVE
- exit 1
- fi
- [root@localhost script]# cat redis_master.sh
- #!/bin/bash
- REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
- LOGFILE="/var/log/keepalived-redis-state.log"
- sleep 15
- echo "[master]">> $LOGFILE
- date>> $LOGFILE
- echo "Being master....">>$LOGFILE 2>&1
- echo "Run SLAVEOF cmd ...">> $LOGFILE
- $REDISCLI SLAVEOF 172.16.81.141 6379>>$LOGFILE 2>&1
- if [ $? -ne 0 ];then
- echo "data rsync fail.">>$LOGFILE 2>&1
- else
- echo "data rsync OK.">> $LOGFILE 2>&1
- fi
- sleep 10 #延迟 10 秒以后待数据同步完成后再取消同步状态
- echo "Run SLAVEOF NO ONE cmd ...">> $LOGFILE
- $REDISCLI SLAVEOF NO ONE>> $LOGFILE 2>&1
- if [ $? -ne 0 ];then
- echo "Run SLAVEOF NO ONE cmd fail.">>$LOGFILE 2>&1
- else
- echo "Run SLAVEOF NO ONE cmd OK.">> $LOGFILE 2>&1
- fi
- [root@localhost script]# cat redis_backup.sh
- #!/bin/bash
- REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
- LOGFILE="/var/log/keepalived-redis-state.log"
- echo "[backup]">> $LOGFILE
- date>> $LOGFILE
- echo "Being slave....">>$LOGFILE 2>&1
- sleep 15 #延迟 15 秒待数据被对方同步完成之后再切换主从角色
- echo "Run SLAVEOF cmd ...">> $LOGFILE
- $REDISCLI SLAVEOF 172.16.81.141 6379>>$LOGFILE 2>&1
- [root@localhost script]# cat redis_fault.sh
- #!/bin/bash
- LOGFILE=/var/log/keepalived-redis-state.log
- echo "[fault]">> $LOGFILE
- date>> $LOGFILE
- [root@localhost script]# cat redis_stop.sh
- #!/bin/bash
- LOGFILE=/var/log/keepalived-redis-state.log
- echo "[stop]">> $LOGFILE
- date>> $LOGFILE
- Slave KeepAlived -- 141
创建存放脚本目录: mkdir -p /etc/keepalived/script/
- cd /etc/keepalived/script/
- [root@localhost script]# cat redis_check.sh
- #!/bin/bash
- ALIVE=`/usr/local/redis/bin/redis-cli -a 123456 PING`
- if [ "$ALIVE" == "PONG" ]; then
- echo $ALIVE
- exit 0
- else
- echo $ALIVE
- exit 1
- fi
- [root@localhost script]# cat redis_master.sh
- #!/bin/bash
- REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
- LOGFILE="/var/log/keepalived-redis-state.log"
- echo "[master]">> $LOGFILE
- date>> $LOGFILE
- echo "Being master....">>$LOGFILE 2>&1
- echo "Run SLAVEOF cmd ...">> $LOGFILE
- $REDISCLI SLAVEOF 172.16.81.140 6379>>$LOGFILE 2>&1
- sleep 10 #延迟 10 秒以后待数据同步完成后再取消同步状态
- echo "Run SLAVEOF NO ONE cmd ...">> $LOGFILE
- $REDISCLI SLAVEOF NO ONE>> $LOGFILE 2>&1
- [root@localhost script]# cat redis_backup.sh
- #!/bin/bash
- REDISCLI="/usr/local/redis/bin/redis-cli -a 123456"
- LOGFILE="/var/log/keepalived-redis-state.log"
- echo "[backup]">> $LOGFILE
- date>> $LOGFILE
- echo "Being slave....">>$LOGFILE 2>&1
- sleep 15 #延迟 15 秒待数据被对方同步完成之后再切换主从角色
- echo "Run SLAVEOF cmd ...">> $LOGFILE
- $REDISCLI SLAVEOF 172.16.81.140 6379>>$LOGFILE 2>&1
- [root@localhost script]# cat redis_fault.sh
- #!/bin/bash
- LOGFILE=/var/log/keepalived-redis-state.log
- echo "[fault]">> $LOGFILE
- date>> $LOGFILE
- [root@localhost script]# cat redis_stop.sh
- #!/bin/bash
- LOGFILE=/var/log/keepalived-redis-state.log
- echo "[stop]">> $LOGFILE
- date>> $LOGFILE
3 启动服务
- systemctl start keepalived
- systemctl enable keepalived
4 测试服务是否正常
ps -ef | grep keepalived
ping 172.16.81.139
查看 VIP 地址
测试连接 redis 是否正常
redis-cli -h 172.16.81.139 -p 6379 -a 123456
Keepalived 测试完成!!
测试故障转移情况
关闭主 redis 服务, 查看从 redis 是否会接管 VIP 变成主? 然后再新的主 redis141 上插入数据, 测试当 140 恢复, 数据是否存在? 141 的是否会变成从节点?
1 主 140 关闭 redis
service redis stop
2 查看 141 状态
测试 VIP 连接远程连接
通过 INFO 可以查看状态信息
可以看到从节点的 141 已经变成 master 节点了
3 插入数据
4 开启 140 主节点
service redis start
5 查看 140 和 141 的主从状态
141 的状态, 变回了从
140 的状态, 变回了主
我们在 140 上查看刚刚在 141 上插入的新数据
数据存在, 证明主从切换是正常的!!!
上面是本人亲测过的, 如有问题请留言!!!
来源: http://www.linuxidc.com/Linux/2018-03/151377.htm