利用redis-sentinel+consul实现redis高可用

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

在前文《利用redis-sentinel+keepalived实现redis高可用》详细描述了利用redis-sentinel+keepalived实现redis高可用的方案。本文中redis-sentinel的应用场景也是一样的,也是提供Redis单实例服务,当某Redis(master)服务意外停掉或该服务所在的主机发生宕机故障或网络故障时,另一台Redis服务会由slave自动成为master,提供Redis读写服务。redis-sentinel的配置可以参考前文,本文略去,只讨论consul代替keepalived。

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

前文是用的keepalived提供一个VIP为上层应用提供访问入口,本文是将keepalived替换成consul,利用consul的DNS Interface为上层应用提供Redis(master)的IP。

image

前提条件:需要一个可用的consul集群,可以利用consul集群本身和配置文件注册服务,也可以用一台单独的主机注册,还可以用HTTP API向Consul注册。

为了获取Redis(master)的IP而不是Redis(Slave)的IP,可以用脚本检查实现,与keepalived脚本中相似,只是返回值将1设定成2,因为consul中返回值0是没问题(passed),1是警告(warning),2是严重(critical)。

下面是用一台单独的主机注册的例子。

json配置文件如下:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
   "services" : [
     {
       "id" "redisnode1" ,
       "name" "redis" ,
       "tags" : [
         "master"
       ],
       "address" "192.168.1.241" ,
       "port" : 6379,
       "checks" : [
         {
           "script" "/usr/local/sbin/redis-cli -h 192.168.1.241 -p 6379 info | grep role:master || exit 2" ,
           "interval" "5s"
         }
       ]
     },
     {
       "id" "redisnode2" ,
       "name" "redis" ,
       "tags" : [
         "master"
       ],
       "address" "192.168.1.242" ,
       "port" : 6379,
       "checks" : [
         {
           "script" "/usr/local/sbin/redis-cli -h 192.168.1.242 -p 6379 info | grep role:master || exit 2" ,
           "interval" "5s"
         }
       ]
     },
     {
       "id" "redisnode3" ,
       "name" "redis" ,
       "tags" : [
         "master"
       ],
       "address" "192.168.1.243" ,
       "port" : 6379,
       "checks" : [
         {
           "script" "/usr/local/sbin/redis-cli -h 192.168.1.243 -p 6379 info | grep role:master || exit 2" ,
           "interval" "5s"
         }
       ]
     }
   ]
}

注册是利用consul agent作为Client运行注册的,假设consul集群中某台Server的地址是192.168.1.245。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
mkdir  -p  /usr/local/consul/data  /usr/local/consul/config   
cat  > /usr/local/consul/config/rediscluster .json<<eof
{
   "services" : [
     {
       "id" "redisnode1" ,
       "name" "redis" ,
       "tags" : [
         "master"
       ],
       "address" "192.168.1.241" ,
       "port" : 6379,
       "checks" : [
         {
           "script" "/usr/local/sbin/redis-cli -h 192.168.1.241 -p 6379 info | grep role:master || exit 2" ,
           "interval" "5s"
         }
       ]
     },
     {
       "id" "redisnode2" ,
       "name" "redis" ,
       "tags" : [
         "master"
       ],
       "address" "192.168.1.242" ,
       "port" : 6379,
       "checks" : [
         {
           "script" "/usr/local/sbin/redis-cli -h 192.168.1.242 -p 6379 info | grep role:master || exit 2" ,
           "interval" "5s"
         }
       ]
     },
     {
       "id" "redisnode3" ,
       "name" "redis" ,
       "tags" : [
         "master"
       ],
       "address" "192.168.1.243" ,
       "port" : 6379,
       "checks" : [
         {
           "script" "/usr/local/sbin/redis-cli -h 192.168.1.243 -p 6379 info | grep role:master || exit 2" ,
           "interval" "5s"
         }
       ]
     }
   ]
}
eof
/bin/consul  agent -advertise=$( ifconfig  $(route -n |  awk  '/^0.0.0.0/ && /UG/ {print $NF}' ) |  grep  inet |  egrep  - v  "(inet6|127.0.0.1)"  cut  -d  ":"  -f2 |  cut  -d  " "  -f1) -bind=$( ifconfig  $(route -n |  awk  '/^0.0.0.0/ && /UG/ {print $NF}' ) |  grep  inet |  egrep  - v  "(inet6|127.0.0.1)"  cut  -d  ":"  -f2 |  cut  -d  " "  -f1) -data- dir = /usr/local/consul/data  -config- dir = /usr/local/consul/config  - join  192.168.1.245

需要后台运行时可以添加nohup thiscommandline >/path/to/logfile 2>&1 &

注意:在consul json配置文件中,每个consul agent的service id都不能重复,name是强制要求的,必须要有,如果id省略,则跟name相同,其他的都是可选的,可有可无。但为了能够使用某条服务信息,就必须要有IP和port,当然port可以在应用中指定。check最好要有,否则当出现问题时不能从consul中取消注册。

注意:上述命令行中使用的是与默认网关同网段IP(公网IP地址),要求此地址与consul集群地址之间能互相访问。在启动consul agent之前可以下面两行命令中的一行确定是否满足此条件:

1
2
consul info -rpc-addr=192.168.1.245:8400   
consul members -rpc-addr=192.168.1.245:8400

在consul agent启动后,此时Redis的信息就会在consul中展示出来,包括UI、DNS Interface和HTTP API中都能查询到。使用Redis的应用应该将DNS指向consul集群的DNS地址,这样才能查询到Redis服务对应的IP。

通过consul HTTP API中提供的“curl http://192.168.1.245:8500/v1/catalog/service/redis”方法只能列举出当前service:redis中有哪些节点,但无法区分这些节点中哪些是正常工作的节点,哪些是有问题的节点,但DNS Interface方法“dig @192.168.1.245 -p 53 redis.service.dc1.consul. ANY”可以准确的将可用的节点的IP找到,如下图所示。

image

image

例如用redis-cli测试一下Redis集群。

image

文中只是利用consul的DNS Interface获取到了Redis集群的master的IP,并没有获取到port,尽管可以通过“dig @192.168.1.245 -p 53 redis.service.consul SRV”可以获取到port,但对于上层应用来说并不是很好做,毕竟大部分应用的域名解析是不会查询SRV记录的。本文的consul是Consul v0.6.0,目前有更新的版本0.6.3可以使用,https://www.consul.io/downloads.html ,consul可能还有其他比较好用的方法更好的获取服务的IP和Port,以后使用的过程中也会再补充。更多关于consul的信息可以参考consul的官方网站:https://www.consul.io/

注意:可能存在的问题。如果Redis master发生故障,原先的slave会变成新的master,DNS缓存可能不会刷新,这个在发生故障处理时需要注意清空上层应用的DNS缓存。

tag:Redis集群,Redis高可用,redis-sentinel,consul API,Redis主从复制

--end--





本文转自 urey_pp 51CTO博客,原文链接:http://blog.51cto.com/dgd2010/1745314,如需转载请自行联系原作者


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
存储 监控 NoSQL
|
1天前
|
存储 监控 NoSQL
Redis是如何保证高可用的?
通过这些机制,Redis可以在主节点故障或其他异常情况下保持高可用性,确保数据的可靠性和可用性。不过,为了实现高可用性,需要仔细规划和配置Redis集群,并确保监控和故障恢复机制的可靠性。
15 6
|
10天前
|
存储 负载均衡 监控
Redis分区指南:如何实现高可用与扩展性
本文由技术小伙伴小米讲解Redis分区容错中的数据分区。内容涉及Hash、一致性Hash、Codis的Hash槽和RedisCluster四种方法。Hash简单但不稳定,数据迁移和分区不均衡是其主要问题;一致性Hash通过最小化数据迁移实现负载均衡,但仍有局限;Codis的Hash槽提供灵活的负载均衡和在线迁移;RedisCluster是官方高可用、可扩展的解决方案。每种方案有优缺点,需根据实际需求选择。
34 0
Redis分区指南:如何实现高可用与扩展性
|
2月前
|
缓存 NoSQL Java
Redis缓存高可用集群
Redis缓存高可用集群
|
3月前
|
存储 NoSQL Java
面试官:Redis如何保证高可用?
面试官:Redis如何保证高可用?
82 2
面试官:Redis如何保证高可用?
|
4月前
|
监控 NoSQL 程序员
Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
78 5
|
4月前
|
存储 负载均衡 NoSQL
Redis 高可用篇:你管这叫主从架构数据同步原理?
Redis 高可用篇:你管这叫主从架构数据同步原理?
242 5
|
28天前
|
存储 NoSQL 算法
09- Redis分片集群中数据是怎么存储和读取的 ?
Redis分片集群使用哈希槽分区算法,包含16384个槽(0-16383)。数据存储时,通过CRC16算法对key计算并模16383,确定槽位,进而分配至对应节点。读取时,根据槽位找到相应节点直接操作。
59 12
|
28天前
|
NoSQL Linux Redis
06- 你们使用Redis是单点还是集群 ? 哪种集群 ?
**Redis配置:** 使用哨兵集群,结构为1主2从,加上3个哨兵节点,总计分布在3台Linux服务器上,提供高可用性。
355 0
|
5天前
|
NoSQL Redis
透视Redis集群:心跳检测如何维护高可用性
Redis心跳检测保障集群可靠性,通过PING命令检测主从连接状态,预防数据丢失。当连接异常时,自动触发主从切换。此外,心跳检测辅助实现`min-slaves-to-write`和`min-slaves-max-lag`策略,避免不安全写操作。还有重传机制,确保命令无丢失,维持数据一致性。合理配置心跳检测,能有效防止数据问题,提升Redis集群的高可用性。关注“软件求生”获取更多Redis知识!
44 10
透视Redis集群:心跳检测如何维护高可用性