高并发大型电商详情页系统的高性能与高可用缓存架构
一、redis安装
redis安装有yum和编译两种方式,本文以编译方式安装,参考文档为官网安装文档
1.gcc安装
1 | [ ~] # yum -y install gcc |
2.下载安装包
1 | [ ~] # wget http://download.redis.io/redis-stable.tar.gz |
3.解压编译
1 2 3 4 | [ ~] # tar xvzf redis-stable.tar.gz [ ~] # cd redis-stable [ redis-stable] # make [ redis-stable] # make install |
4.修改配置文件
1 2 3 4 5 | [ redis-stable] # mkdir /etc/redis[ redis-stable]# mkdir -p /var/redis/6379 [ redis-stable] # cp redis.conf /etc/redis/6379.conf [ redis-stable] # cd /etc/redis/ [ redis] # cp 6379.conf 6379.conf.bak [ redis] # grep -Ev ‘^$|#‘ 6379.conf.bak > 6379.conf |
主要配置修改如下:
1 2 3 4 5 6 | #bind 127.0.0.1 protected-mode no daemonize yes pidfile /var/run/redis_6379 .pid logfile /var/log/redis_6379 .log dir /var/redis/6379 |
5.制作启动服务
1 | [ redis-stable] # cp utils/redis_init_script /etc/init.d/redis_6379 |
6.启动服务并加入开机启动
1 2 | [ redis] # service redis_6379 start [ redis] # chkconfig redis_6379 on |
7.RedisDesktopManager管理工具
该工具为redis图形化管理工具
软件下载:https://pan.baidu.com/s/1no0IWcIEBapfehNi8dfCfw 密码:7dvc
连接设置:
连接后效果
二、redis主从复制及持久化
1.从服务器设置
redis主从复制很简单,只需要在从服务器配置文件新增一条配置即可
1 | [ redis] # sed -i ‘$a slaveof 172.27.9.30 6379‘ /etc/redis/6379.conf |
2.主从测试
2.1主机上写入值
1 2 | [ ~] # redis-cli set test-key abc OK |
查看从机redis键值:
2.2从机写入值
1 2 | [ redis] # redis-cli set test-key 123 (error) READONLY You can‘t write against a read only slave. |
发现报错,处于slave状态redis无法写入。
3.持久化
redis持久化有RDB和AOF两种方式,默认持久化为RDB方式,关闭默认持久化只需要把默认配置注释就行:
1 2 3 | #save 900 1 #save 300 10 #save 60 10000 |
三、keepalived安装配置
1.keepalived安装
1 | [ ~] # yum -y install keepalived |
2.keepalived配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | [ ~] # more /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id master #router_id 机器标识,通常为hostname,但不一定非得是hostname。故障发生时,邮件通知会用到。 } vrrp_script chk_redis { script "/etc/keepalived/redis-check.sh" interval 2 #健康检查周期 weight 30 #优先级变化幅度 fall 2 #尝试两次都成功才成功 rise 2 #尝试两次都失败才失败 } vrrp_instance VI_1 { #vrrp实例定义部分 state MASTER #设置lvs的状态,MASTER和BACKUP两种,必须大写 interface ens33 #设置对外服务的接口 virtual_router_id 100 #设置虚拟路由标示,这个标示是一个数字,同一个vrrp实例使用唯一标示 priority 100 #定义优先级,数字越大优先级越高,在一个vrrp——instance下,master的优先级必须大于backup advert_int 1 #设定master与backup负载均衡器之间同步检查的时间间隔,单位是秒 authentication { #设置验证类型和密码 auth_type PASS #主要有PASS和AH两种 auth_pass 1111 #验证密码,同一个vrrp_instance下MASTER和BACKUP密码必须相同 } virtual_ipaddress { #设置虚拟ip地址,可以设置多个,每行一个 172.27.9.100 } track_script { #执行脚本chk_redis chk_redis } notify_master "/etc/keepalived/redis-master.sh" #指定当切换为master时,执行的脚本 } |
相比master,slave配置有3点不同:
1 2 3 | <code class= "language-bash hljs" >router_id slave state BACKUP priority 90< /code > |
为了避免主从间的来回切换,也可以设置nopreemt参数,开启非抢占式模式;不过当redis或者keepalived发生异常时都会触发各种告警,运维人员会及时介入处理。
3.启动并设置开机启动
1 2 | [ ~] # systemctl start keepalived [ ~] # systemctl enable keepalived |
四、expect安装
1 | [ ~] # yum -y install expect |
expect是一个提供自动交互的工具,本文notify_master中的脚本会使用到。
五、高可用脚本
1.redis-check.sh脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [ keepalived] # more redis-check.sh #!/bin/sh rediscli= "/usr/local/bin/redis-cli" logfile= "/var/log/redis_6379.log" result=$($rediscli ping ) echo $result echo "-------------------redis-check-------------------" >> $logfile date >> $logfile if [ $result == "PONG" ]; then : echo "Success: the result is $result" >> $logfile 2>&1 exit 0 else echo "Failed:the result is $result " >> $logfile 2>&1 exit 1 fi |
该脚本为对redis状态检查
2.redis-master.sh脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [ keepalived] # more redis-master.sh #!/bin/bash rediscli= "/usr/local/bin/redis-cli" logfile= "/var/log/redis_6379.log" sync =`$rediscli info replication| grep master_sync_in_progress| awk -F: ‘{print $2}‘ | sed ‘s/\r//‘ ` #sync=`/usr/local/bin/redis-cli info replication|grep master_sync_in_progress|awk -F: ‘{print $2}‘` echo $ sync echo "-------------------change to master-------------------" >> $logfile 2>&1 date >> $logfile if [ $ sync == 0 ]; then : echo "the master_sync_in_progress is 0 and excute slaveof no one" >>$logfile 2>&1 $rediscli slaveof no one elif [ $ sync == 1 ]; then : sleep 10 $rediscli slaveof no one else echo "the host is master,do nothing" >>$logfile 2>&1 fi /etc/keepalived/exp .sh 172.27.9.31 monitor >>$logfile 2>&1 |
该脚本为本文高可用切换的关键。
monitor为31的root密码;slave脚本的ip应改为172.27.9.30;该脚本为服务器切换为master时执行的脚本,首先会检查切换前与master的主从同步是否完成,然后利用expect工具跳到另一台服务器将其redis状态更改为slave。
3.exp.sh脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [ keepalived] # more exp.sh #!/usr/bin/expect -f set ip [lindex $argv 0 ] set password [lindex $argv 1 ] set timeout 30 spawn ssh $ip expect { "*yes/no" { send "yes\r" ; exp_continue} "*password:" { send "$password\r" ;exp_continue } } expect "#*" send "/usr/local/bin/redis-cli slaveof 172.27.9.30 6379\r" send "exit\r" expect eof |
slave脚本中的ip为172.27.9.31;该脚本作用是跳到另一台服务执行slaveof命令。
六、测试
1.模拟redis服务异常
操作:停掉master的redis服务
预期:vip漂移,slave主机的redis状态切换为master
测试过程:
1.1停止master的redis服务
1 | [ keepalived] # service redis_6379 stop |
1.2查看虚ip
发现vip由30漂移至31
1.3查看redis状态
1 | [ keepalived] # redis-cli info replication |
31的redis状态切换为master
1.4回切
启动30的redis服务
1 | [ keepalived] # service redis_6379 start |
查看vip和redis状态
30:
31:
结论:redis服务异常时会发生切换,从机会切换为master状态对外提供服务。
2.模拟keepalived服务异常
操作:停掉master的keepalived服务
预期:vip漂移,master的redis状态切换为slave,slave的redis状态切换为master
测试过程:
2.1停止master的keepalived服务
1 | [ keepalived] # systemctl stop keepalived |
2.2查看vip和redis状态
30:
31:
vip由30漂移至31且主从发生反转;开启keepalived服务会触发回切。
结论:keepalived服务异常时会发生切换,主从会反转。
3.模拟master宕机
操作:master关机
预期:vip漂移,slave的redis状态切换为master
测试过程:
3.1master服务器关机
1 | [ ~] # init 0 |
3.2查看vip和redis状态
vip漂移至31且状态切换为master;30开机会触发回切。
结论:master宕机时会发生切换,从机切换为master状态对外提供服务。