redis的哨兵(sentinel)配置和python程序应用示例

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:

Sentinel概述:

当用RedisMaster-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。SentinelRedis的高可用性(HA)解决方案,由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进行下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。Redis提供的sentinel(哨兵)机制,通过sentinel模式启动redis后,自动监控master/slave的运行状态,基本原理是:心跳机制+投票裁决

监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

配置信息:哨兵提供了认证和服务发现,客户端连接到哨兵去获取当前redis 主服务器地址,如果发生故障转移,哨兵将会汇报新的服务器地址。每次进行主从切换时,sentinel配置文件自动更新

二、Sentinel支持集群

很显然,只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群,这样有几个好处:

1. 即使有一些sentinel进程宕掉了,依然可以进行redis集群的主备切换;

2. 如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);

3. 如果有多个sentinelredis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息。

三、Sentinel版本选择

Sentinel当前最新的稳定版本称为Sentinel 2(与之前的Sentinel 1区分开来)。随着redis2.8的安装包一起发行。安装完Redis2.8后,可以在redis2.8/src/里面找到Redis-sentinel的启动程序。如果你使用的是redis2.6(sentinel版本为sentinel 1),你最好应该使用redis2.8版本的sentinel 2,因为sentinel 1有很多的Bug,已经被官方弃用,所以强烈建议使用redis2.8以及sentinel 2

四、Redis Sentinel的配置

redisip192.168.221.160

redisip192.168.221.161

Sentinelredis主从的基础上继续配置,主从配置的方式这里不再赘述。详情请参考楼主另一篇文章:redis安装及主从配置 

我这里配置两个哨兵,分别部署在两台机器上采用了典型的配置项,配置文件如下

1
2
3
4
5
6
7
8
9
10
[root@DB ~] # grep -Ev '^#|^$' /etc/sentinel_26379.conf 
port 26379
daemonize  yes  #程序后台执行
logfile  "/var/log/sentinel.log"
dir  "/tmp"
sentinel monitor mymaster 192.168.221.160 6379 2  #第一次设置哨兵时此ip一定要设置为redis集群中的主ip
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 6000
sentinel config-epoch mymaster 7
sentinel parallel-syncs mymaster 1


下面简单解释下这些配置项:

sentinel monitor mymaster 192.168.221.160 6379 表示sentinel监控的master名字是mymaster,地址为192.168.221.160:6379。行尾最后的一个2代表什么意思呢?我们知道,网络是不可靠的,有时候一个sentinel会因为网络堵塞而误以为一个master redis已经死掉了,当sentinel集群式,解决这个问题的方法就变得很简单,只需要多个sentinel互相沟通来确认某个master是否真的死了,这个2代表,当集群中有2sentinel认为master死了时,才能真正认为该master已经不可用了。(sentinel集群中各个sentinel也有互相通信,通gossip协议)

sentinel down-after-milliseconds mymaster 5000  Sentinel会向master发送心跳PING来确认master是否存活,如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了(subjectively down, 也简称为SDOWN)。而这个down-after-milliseconds就是用来指定这个“一定时间范围”的,单位是毫秒

sentinel parallel-syncs mymaster 1 在执行故障转移时,最多可以有多少个从服务器同时从新的主服务器进行同步,数字越小,完成故障转移需要的时间越长

五、运行Sentinel,状态检查

先启动redis主从程序,在启动sentinel

1
redis-server  /etc/sentinel_26379 .conf --sentinel

Master机器查看进程:

1
2
3
4
5
root      84286  57342  0 Oct18 pts /2     00:00:00 redis-cli -h 192.168.221.160 -p 26379
root      84302      1  0 Oct18 ?        00:03:41 redis-server *:26379                            
redis     84328      1  0 Oct18 ?        00:03:01  /usr/sbin/redis-server  192.168.221.160:6379
root      84391  83553  0 Oct18 pts /3     00:00:00 redis-cli -h 192.168.221.160
root      86746  86651  0 09:35 pts /6     00:00:00  grep  redis

Slave机器查看进程:

1
2
3
4
redis     53505      1  0 Oct18 ?        00:02:17  /usr/sbin/redis-server  192.168.221.161:6379
root      53510  52922  0 Oct18 pts /0     00:00:00 redis-cli -h 192.168.221.161
root      53542      1  0 Oct18 ?        00:02:53 redis-server *:26379                            
root      54767  54723  0 09:34 pts /1     00:00:00  grep  redis

查看master状态:

1
2
3
4
5
6
7
8
9
10
11
[root@MidApp ~] # redis-cli -h 192.168.221.160 
192.168.221.160:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.221.161,port=6379,state=online,offset=9243499,lag=0
master_repl_offset:9243644
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:8195069
repl_backlog_histlen:1048576


查看slave状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@DB ~] # redis-cli -h 192.168.221.161 -p 6379
192.168.221.161:6379> info replication
# Replication
role:slave
master_host:192.168.221.160
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:9200304
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0


查看sentinel状态:

1
2
3
4
5
6
7
8
[root@DB ~] # redis-cli -h 192.168.221.160 -p 26379
192.168.221.160:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=192.168.221.160:6379,slaves=1,sentinels=2


六、Redis-Sentinel主从切换测试

首先手动关闭主redis(192.168.221.160),查看sentinel日志,可以看到192.168.221.161已经变成了主redis,自动完成了切换:

1
2
3
4
5
6
7
[84302] 18 Oct 15:22:31.539 * +failover-state-wait-promotion slave 192.168.221.161:6379 192.168.221.161 6379 @ mymaster 192.168.221.160 6379
[84302] 18 Oct 15:22:32.434  # +promoted-slave slave 192.168.221.161:6379 192.168.221.161 6379 @ mymaster 192.168.221.160 6379
[84302] 18 Oct 15:22:32.434  # +failover-state-reconf-slaves master mymaster 192.168.221.160 6379
[84302] 18 Oct 15:22:32.498  # +failover-end master mymaster 192.168.221.160 6379
[84302] 18 Oct 15:22:32.499  # +switch-master mymaster 192.168.221.160 6379 192.168.221.161 6379
[84302] 18 Oct 15:22:32.500 * +slave slave 192.168.221.160:6379 192.168.221.160 6379 @ mymaster 192.168.221.161 6379
[84302] 18 Oct 15:22:37.552  # +sdown slave 192.168.221.160:6379 192.168.221.160 6379 @ mymaster 192.168.221.161 6379


把刚才关闭的redis再次启动之后检查redis主从状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@DB ~] # redis-cli -h 192.168.221.160 -p 6379
192.168.221.160:6379> info replication
# Replication
role:slave
master_host:192.168.221.161
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:9200304
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0


 

1
2
3
4
5
6
7
8
9
10
11
[root@MidApp ~] # redis-cli -h 192.168.221.161 
192.168.221.161:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.221.160,port=6379,state=online,offset=9243499,lag=0
master_repl_offset:9243644
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:8195069
repl_backlog_histlen:1048576


检查sentinel配置文件:

1
2
3
4
5
6
7
8
9
10
11
[root@DB ~] # grep -Ev '^#|^$' /etc/sentinel_26379.conf 
port 26379
daemonize  yes
logfile  "/var/log/sentinel.log"
dir  "/tmp"
sentinel monitor mymaster 192.168.221.161 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 6000
sentinel config-epoch mymaster 7
sentinel known-slave mymaster 192.168.221.160 6379
sentinel known-sentinel mymaster 192.168.221.161 26379 74f54a23bf06b57ce1618ee48f42a09a11522bb9


可以看到配置文件监控的master机器也变成了192.168.221.161:6379

七、python程序访问sentinel集群

由于很好奇连入的程序是如何访问sentinel集群的,自己用python验证了一下。

Python下需要安装redis相关的lib库,我这里使用的是redis-2.10.5版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@DB ~] # python 
Python 2.6.6 (r266:84292, Jan 22 2014, 09:42:36) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type  "help" "copyright" "credits"  or  "license"  for  more  information.
>>> from redis.sentinel  import  Sentinel  #加载redis模块
>>> sentinel = Sentinel([( '192.168.221.160' , 26379),
...                      ( '192.168.221.161' , 26379)],
...                     socket_timeout=0.1)  #连接哨兵服务器
>>> sentinel.discover_master( 'mymaster' #获取主redis服务器地址
( '192.168.221.161' , 6379)
>>> sentinel.discover_slaves( 'mymaster' ) #获取从redis服务区地址
[( '192.168.221.160' , 6379)]
>>> master = sentinel.master_for( 'mymaster' , socket_timeout=0.1) 
>>> master. set ( 'foo' , 'bar' #获取主redis服务器并进行写入
True
>>> slave = sentinel.slave_for( 'mymaster' , socket_timeout=0.1)
>>> slave.get( 'foo' ) #获取从redis服务器进行获取
'bar'
>>>


初步认为程序通过sentinel提供的端口进行访问,获取主redis进行写入操作,读的话如果不指定方式会采取轮询的方式进行读操作

 

参考文档:

 

Redis Sentinel机制与用法(一)


本文转自 青苗飞扬 51CTO博客,原文链接:http://blog.51cto.com/qingmiao/1974146


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
8天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
11天前
|
数据库 Python
Python 应用
Python 应用。
32 4
|
20天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
63 6
|
21天前
|
数据采集 数据安全/隐私保护 开发者
非阻塞 I/O:异步编程提升 Python 应用速度
非阻塞 I/O:异步编程提升 Python 应用速度
|
8天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
1天前
|
人工智能 安全 Java
Java和Python在企业中的应用情况
Java和Python在企业中的应用情况
20 7
|
11天前
|
机器学习/深度学习 数据采集 数据可视化
Python在数据科学中的应用:从入门到实践
本文旨在为读者提供一个Python在数据科学领域应用的全面概览。我们将从Python的基础语法开始,逐步深入到数据处理、分析和可视化的高级技术。文章不仅涵盖了Python中常用的数据科学库,如NumPy、Pandas和Matplotlib,还探讨了机器学习库Scikit-learn的使用。通过实际案例分析,本文将展示如何利用Python进行数据清洗、特征工程、模型训练和结果评估。此外,我们还将探讨Python在大数据处理中的应用,以及如何通过集成学习和深度学习技术来提升数据分析的准确性和效率。
|
10天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
|
13天前
|
机器学习/深度学习 JSON API
Python编程实战:构建一个简单的天气预报应用
Python编程实战:构建一个简单的天气预报应用
32 1
|
21天前
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
69 7
下一篇
无影云桌面