目标、需求:

为上层应用提供高可靠、低延迟、低(无限接近0)数据损失的Redis缓存服务

方案概述:

采用同一网络内的三台主机(可以是物理主机、虚拟机或docker容器),要求三台主机之间都能相互访问,每一台主机上都安装redis-server、redis-sentinel和keepalived。

redis-server负责提供Redis缓存服务,三台主机间的关系是master-slave-slave

redis-sentinel负责提供Redis高可用,三台主机间的关系与redis-server相同

keepalived负责提供VIP地址供上层应用使用,三台主机的关系是master-backup-backup,VIP始终在redis-server master上,保证对上层应用可写可读。

三台主机的冗余度是1,也就是说当有一台主机宕机时另外两台中至少有一台主机可以提供Redis缓存服务

方案原理:

redis-server提供单实例的Redis缓存服务,redis-sentinel能在一台主机挂掉时自动的将某一台可用主机上的redis-server由slave状态切换成master状态。

keepalived通过vrrp_script检测当前主机上的redis-server是否以master状态运行,如果当前主机上的redis-server正在以master状态运行,则将vrrp_instance标记为存活状态,并分配VIP;如果当前主机上的redis-server正在以slave状态运行,则将vrrp_instance标记为错误状态。当某台主机宕机后,其他两台主机上的keepalived会将VIP切换到新的master(当前主机上的redis-server正在以master状态运行)上。

由于keepalived的VIP切换有延迟(大约40ms),因此上层应用不能过分依赖Redis,例如大规模并发性的短时间内向Redis插入大量数据。

连接图

如图所示,有三台主机,分别标识为Redis1、Redis2、Redis3,它们的角色和配置等信息如下:

主机标识 Redis1 Redis2 Redis3
IP地址 192.168.1.241 192.168.1.242 192.168.1.243
预设配置 redis-server master          
keepalived master
redis-server slave          
keepalived backup
redis-server slave          
keepalived backup
  VIP    

配置步骤:

步骤概述

  1. 安装:安装redis-server、redis-sentinel、keepalived

  2. 配置:配置Redis1、Redis2、Redis3,主要是编辑各个服务的配置文件

  3. 启动:先启动redis-server、再启动redis-sentinel、最后自动keepalived

  4. 验证:模拟一台主机宕机,主机网络中断,redis-server、redis-sentinel、keepalived三个服务任何一个发生故障的情况。

(1)设定主机名(建议设定为fqdn格式)、同步时间、更改文件描述符最大打开数量、更改内核参数、配置编译环境、配置防火墙在此就不赘述了。

(2)安装redis-server和redis-sentinel

Redis的安装由于只是bin二进制可执行文件和data目录比较重要,因此简化安装如下

# http://download.redis.io/redis-stable.tar.gz
wget -c http://download.redis.io/releases/redis-3.0.7.tar.gz
tar zxf redis-3.0.7.tar.gz
cd redis-3.0.7
make
cd
\cp redis-3.0.7/src/redis-benchmark /usr/local/sbin/
\cp redis-3.0.7/src/redis-check-aof /usr/local/sbin/
\cp redis-3.0.7/src/redis-check-dump /usr/local/sbin/
\cp redis-3.0.7/src/redis-cli /usr/local/sbin/
\cp redis-3.0.7/src/redis-sentinel /usr/local/sbin/
\cp redis-3.0.7/src/redis-server /usr/local/sbin/
mkdir /etc/redis
mkdir -p /data/redis-6379/

(3)安装keepalived

# http://www.keepalived.org/documentation.html
wget -c http://www.keepalived.org/software/keepalived-1.2.19.tar.gz
tar zxf keepalived-1.2.19.tar.gz
cd keepalived-1.2.19
./configure --prefix=/usr/local/keepalived
make
make install
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
mkdir /etc/keepalived

keepalived的配置文件在后面添加

(4)Redis1上的redis-sentinel配置文件

cat >/etc/redis/sentinel.conf<<eof
port 26379
dir /tmp
sentinel monitor mymaster 192.168.1.241 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
eof

Redis2和Redis3上的redis-sentinel配置文件与Redis1上的redis-sentinel配置文件内容相同。

(5)Redis1上的redis-server的配置文件

cat > /etc/redis/redis-6379.conf <<eof
# maxmemory 268435456
maxmemory 256mb
daemonize yes
pidfile /data/redis-6379/redis-6379.pid
port 6379
bind 0.0.0.0
tcp-backlog 511
timeout 0     tcp-keepalive 0
loglevel notice
logfile /data/redis-6379/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dumpredis-6379.rdb
dir /data/redis-6379
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
# repl-ping-slave-period 10
# repl-timeout 60
repl-disable-tcp-nodelay no
# repl-backlog-size 1mb
# repl-backlog-ttl 3600
slave-priority 100
# min-slaves-to-write 3
# min-slaves-max-lag 10     appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
eof

(6)Redis2与Redis3上的redis-server配置文件

cat > /etc/redis/redis-6379.conf <<eof
slaveof 192.168.1.241 6379
# maxmemory 268435456
maxmemory 256mb
daemonize yes
pidfile /data/redis-6379/redis-6379.pid
port 6379
bind 0.0.0.0
tcp-backlog 511
timeout 0
tcp-keepalive 0
loglevel notice
logfile /data/redis-6379/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dumpredis-6379.rdb
dir /data/redis-6379
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5 # repl-ping-slave-period 10
# repl-timeout 60
repl-disable-tcp-nodelay no
# repl-backlog-size 1mb
# repl-backlog-ttl 3600
slave-priority 100
# min-slaves-to-write 3
# min-slaves-max-lag 10
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
eof

(7)Redis1上的keepalived配置文件(vim /etc/keepalived/keepalived.conf)

关于keepalived的配置文件

keepalived的配置文件默认是没有的,当然sample&example文件还是有的,通常在PREFIX/etc/sample目录下。

keepalived master和backup(backups)之间不同的是:

1.优先级的不同,master的优先级priority的数字要高一些

2.global_defs段的router_id都不一样,实际中可以用任意名字区分也可以用主机名区分

3.backup的配置文件中还有一个nopreempt字段,意思是设置为非抢占模式,作用是让master优先获取到VIP,并保证VIP是在原先的master上。

! Configuration File for keepalived
global_defs {     notification_email {     root@localhost     }     notification_email_from keepalived@localhost     smtp_server 127.0.0.1     smtp_connect_timeout 10     router_id keepalivedha_1
}
vrrp_script chk_http_port {     script "redis-cli info | grep role:master >/dev/null 2>&1"     interval 1     timeout 2     fall 2     rise 1
}
vrrp_sync_group VG_1 {     group {     VI_1     }
}
vrrp_instance VI_1 {     state BACKUP     interface eth1     #use_vmac keepalived     #vmac_xmit_base     mcast_src_ip 192.168.1.241     smtp_alert     virtual_router_id 20    priority 100     advert_int 1     authentication {     auth_type PASS     auth_pass password     }     virtual_ipaddress {     192.168.1.245     }     track_script {     chk_http_port     }
}

(8)Redis2上的keepalived配置文件

! Configuration File for keepalived
global_defs {     notification_email {     root@localhost     }     notification_email_from keepalived@localhost    smtp_server 127.0.0.1     smtp_connect_timeout 10     router_id keepalivedha_2
}
vrrp_script chk_http_port {     script "redis-cli info | grep role:master >/dev/null 2>&1"     interval 1     timeout 2     fall 2     rise 1
}
vrrp_sync_group VG_1 {     group {     VI_1     }
}
vrrp_instance VI_1 {     state BACKUP     interface eth2     #use_vmac keepalived     #vmac_xmit_base     mcast_src_ip 192.168.1.242     smtp_alert     virtual_router_id 20    priority 99     advert_int 1     authentication {     auth_type PASS     auth_pass password     }     virtual_ipaddress {     192.168.1.245     }     track_script {     chk_http_port     }     nopreempt
}

(9)Redis3上的keepalived配置文件

! Configuration File for keepalived
global_defs {     notification_email {     root@localhost     }     notification_email_from keepalived@localhost     smtp_server 127.0.0.1     smtp_connect_timeout 10     router_id keepalivedha_3
}
vrrp_script chk_http_port {     script "redis-cli info | grep role:master >/dev/null 2>&1"     interval 1     timeout 2     fall 2     rise 1
}
vrrp_sync_group VG_1 {     group {     VI_1     }
}
vrrp_instance VI_1 {     state BACKUP     interface eth1     #use_vmac keepalived     #vmac_xmit_base     mcast_src_ip 192.168.1.243     smtp_alert     virtual_router_id 20    priority 98     advert_int 1     authentication {     auth_type PASS     auth_pass password     }     virtual_ipaddress {     192.168.1.245     }     track_script {     chk_http_port     }     nopreempt
}

(10)启动redis-server

redis-server /etc/redis/redis-6379.conf
tail /data/redis-6379/redis.log

(11)启动redis-sentinel

redis-sentinel /etc/redis/redis-sentinel.conf
tail /data/redis-6379/redis-sentinel.log

(12)启动keepalived

service keepalived start
tail /var/log/messages

如果keepalived启动后日志如下图显示则表示启动成功。

测试

测试分两块内容,一是测试键值对的set与get,二是测试自增唯一id的是否可用。

(1)测试Redis键值对的set与get

先不模拟故障,先测试一下redis的set、get和复制情况

再测试一下模拟故障出现时redis的set、get和复制情况

停掉Redis1上的redis-server

Redis1上的VIP已经被移除

查看Redis2上的Redis状态和VIP状态

通过上图的***文字可以看出,VIP已经漂移到新的redis-server master了。

注意:VIP的漂移过程是需要时间的,时间大概需要10*4ms左右,如下图所示:

此时再次测试一下Redis的复制情况

由上图可见,Redis复制情况正常,上层应用依然可以使用Redis缓存服务。

(2)测试自增唯一id(autoincrementing unique identifier)

概念参考:http://redis-cookbook.readthedocs.org/en/latest/z.html

自增唯一id最常见的应用就是作为关系型数据库的主键,因为主键必须确保每个数据项都有唯一id。

它也可以在不支持自增唯一id的数据库中(比如MongoDB)用来替代唯一id(uniqueidentifier,通常是一个哈希值)

它也可以为用户提供更好的URL:比如将/topic/4e491e229f328b0cd900010d修改为/topic/10086。

一个自增唯一id对象最重要的是保证值的唯一性,要做到这一点,自增id的自增incr操作必须是一个原子操作,它应该能在一个原子时间内完成以下两件事:

增加id值,返回当前id值,并且它也没有减法decr和清零reset等操作,因为这些操作破坏了唯一性。

get操作一般只用于内部检查,比如观察值是否溢出,但在一般情况下,自增唯一id对象应该只有一个incr操作。

先测试一下主机健康状态下的自增唯一id

发现各个redis-server中的自增唯一id是好用的。再测试一下某台主机故障状态下的自增唯一id。先根据ip addr找到VIP的主机位置,或者通过redis-cli info查看role找到redis-server master的主机,然后kill redis-server pid,再进行测试。

由此发现redis-server中的自增唯一id仍然是好用的。

故障切换的步骤

如果一台主机宕机,则主机启动后,先启动redis-server、再启动redis-sentinel、最后自动keepalived。

如果多台主机宕机,则按照一台主机宕机的步骤做同样处理。

如果一台主机的中的某台服务停止,则直接启动该服务即可。

参考

Redis Documention http://redis.io/documentation

Redis High Availability http://redis.io/topics/sentinel

Redis Replication http://redis.io/topics/replication

后续

由于keepalived的应用场景有限,比如它的核心协议VRRP只能工作在局域网内,不能工作在局域网外(网间、广域网),而且在网络不受自己控制时基本不能用,除非设定好的VIP是供局域网使用。因此特别是在云计算环境中,使用云主机(例如阿里云ECS等)就不能用keepalived,因此只能寻找一个可替代keepalived的解决方案来替代它。Consul作为服务注册、服务发现的最佳选择,无疑可以很好的替代keepalived。第二种方案可以参考这篇文章《利用redis-sentinel+consul实现redis高可用》。

tag:Redis集群,Redis高可用,redis-sentinel,keepalived配置,Redis主从复制

--end--

转载于:https://blog.51cto.com/dgd2010/1742766

利用redis-sentinel+keepalived实现redis高可用相关推荐

  1. redis集群方式及高可用架构

    Redis集群模式 1.主从模式,单台服务器即可,无高可用,为1主2从方式 主节点可读写,从节点只读,数据会从主节点同步至从节点 2.cluster模式 3.0以上版本支持 Redis Cluster ...

  2. Redis M/S + Keepalived 主从备份高可用

    目录 文章目录 目录 高可用 Redis 的高可用 Redis 主从复制配置 Redis 主从切换(手动方式) SLAVEOF 指令 Redis M/S + Keepalived 故障的 3 种情况 ...

  3. Redis 备份,容灾及高可用实战

    一.Redis简单介绍 Redis是一个高性能的key-value非关系型数据库,由于其具有高性能的特性,支持高可用.持久化.多种数据结构.集群等,使其脱颖而出,成为常用的非关系型数据库.此外,Red ...

  4. Redis实践(二)高可用的集群+哨兵部署

    项目中通常会需要若干台Redis服务器来协同担当起内存数据库的工作,在redis的部署方案上要考虑下面几点: 结构上,单个 Redis 服务器会发生单点故障,而且一台服务器需要承受所有的请求负载. 这 ...

  5. 【带你重拾Redis】Redis 哨兵集群实现高可用

    Redis 哨兵集群实现高可用 哨兵的介绍 sentinel,中文名是哨兵.哨兵是 Redis 集群架构中非常重要的一个组件,主要有以下功能: 集群监控:负责监控 Redis master 和 sla ...

  6. asp.net core 实战之 redis 负载均衡和quot;高可用quot;实现

    1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的"高可用"实现, 呵呵双引号的"高可用"并不是 ...

  7. redis主从复制,复制功能是高可用Redis的基础,为满足故障恢复和负载均衡等需求把Redis数据复制多个副本部署到其他机器;如何实现redis的主从复制模式以及主从复制模式下常见的运维问题;

    目录 一.如何使用redis主从复制模式 1.建立复制 2.断开复制 3.安全性 4.只读模式 5.传输延迟 二.Redis的复制拓扑结构 1.一主一从结构 2.一主多从结构 3.树状主从结构 三.主 ...

  8. MySQL共享存储主备模式利用Keepalived实现双机高可用

    简单介绍 先简单说下MySQL主从复制与keepalived模式和MySQL共享存储与Keepalived模式 MySQL共享存储主备模式不同于MySQL主主复制模式,MySQL主主是利用MySQL自 ...

  9. 【7W字长文】使用LVS+Keepalived实现Nginx高可用,一文搞懂Nginx

    往期文章一览 分布式会话与单点登录SSO系统CAS,包含完整示例代码实现 [15W字长文]主从复制高可用Redis集群,完整包含Redis所有知识点 使用LVS+Keepalived实现Nginx高可 ...

  10. 【Keepalived】开源高可用的Keepalived

    Keepalived 一.What is Keepalived? 二.什么是高可用? 三.keepalived故障转移实现高可用 四.keepalived运行环境 1.下载安装 2.启动keepali ...

最新文章

  1. 思科基本配置脚本命令
  2. 第二次做HDOJ 1051
  3. 屏蔽朋友圈的第一天的感悟
  4. python为什么没有点击就触发_Ai中没有触发的触发器
  5. Service Broker实现发布-订阅(Publish-Subscribe)框架(3)
  6. [ShapeInferenceError] Mismatch between number of source and target dimensions. Source=1 Target=0
  7. java中使用es精准查询_使用ES简单查询语句须知
  8. IBM研究院计画5年改变人类生活创新预测
  9. loadrunner 参数化
  10. HP5200打印机从控制面板手动配置TCP/IP 参数
  11. Could not find a version that satisfies the requirement PyQt5
  12. 汇编语言与微机接口——交通灯设计
  13. 详解 box-shadow
  14. ssl2334 铲雪车
  15. 服务器 sn 作用,命令查看服务器SN号
  16. 适合穷人挣钱最快的方法
  17. 注册企业邮箱,怎么给国外的人发邮件?
  18. 维克森林大学计算机科学专业好不好,维克森林大学计算机科学系
  19. 一个mysql安装问题的解决
  20. 高可用网站架构设计与实现

热门文章

  1. http 升级 https 影响原来的链接吗_360站长平台自动收录JS切换为https
  2. vscode新建文件的快捷键_Mac怎么创建txt文件?如何设置新建txt的快捷键?
  3. java光标_java怎么设置光标位置 java设置光标位置方法
  4. b区计算机复试国家线,2020研究生考试国家线A区B区有什么区别
  5. update怎么同时改两个字段_[NewLife.XCode]高级增删改
  6. 我最喜欢的科目是计算机课英语,初一英语作:my favorite subject(我最喜欢的科目)要求写美术课(art),80词以上,拜托啦!...
  7. 加载类_JVM类加载
  8. Java学习笔记2.2.1 常量与变量 - 变量
  9. 安卓学习笔记03:安卓应用目录结构
  10. 【BZOJ1003】【codevs1655】物流运输,最短路+DP