「每天一道面试题」 Redis哨兵模式
mhr18 2024-11-12 11:23 13 浏览 0 评论
Redis哨兵模式
什么是Redis哨兵模式
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。
虽然 Redis Sentinel 释出为一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动 Redis Sentinel 。
哨兵模式简介
Sentinel(哨兵)是用于监控 redis 集群中 Master 状态的工具,是 Redis 的高可用性解决方案,sentinel 哨兵模式已经被集成在 redis2.4 之后的版本中。sentinel 是 redis 高可用的解决方案,sentinel 系统可以监视一个或者多个 redis master 服务,以及这些 master 服务的所有从服务;当某个 master 服务下线时,自动将该 master 下的某个从服务升级为 master 服务替代已下线的 master 服务继续处理请求。
sentinel 可以让 redis 实现主从复制,当一个集群中的 master 失效之后,sentinel 可以选举出一个新的 master 用于自动接替 master 的工作,集群中的其他 redis 服务器自动指向新的 master 同步数据。一般建议 sentinel 采取奇数台,防止某一台 sentinel 无法连接到 master 导致误切换。
Redis Sentinel作用
Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
- 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
- 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时,Sentinel 会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
Sentinel的工作方式
- 每个 Sentinel 以每秒钟一次的频率向它所知的 Master,Slave 以及其他 Sentinel 实例发送一个 PING 命令。
- 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值,则这个实例会被 Sentinel 标记为主观下线。
- 如果一个 Master 被标记为主观下线,则正在监视这个 Master 的所有 Sentinel 要以每秒一次的频率确认 Master 的确进入了主观下线状态。
- 当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认 Master 的确进入了主观下线状态,则 Master 会被标记为客观下线。
- 在一般情况下,每个 Sentinel 会以每 10 秒一次的频率向它已知的所有 Master,Slave 发送 INFO 命令。
- 当 Master 被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
- 若没有足够数量的 Sentinel 同意 Master 已经下线,Master 的客观下线状态就会被移除。
- 若 Master 重新向 Sentinel 的 PING 命令返回有效回复,Master 的主观下线状态就会被移除。
Redis Sentinel优缺点
优点
- 监控主数据库和从数据库是否正常运行
- 主数据库出现故障时,可以自动将从数据库转换为主数据库,实现自动切换
- 如果 redis 服务出现问题,会发送通知
缺点
- 主数据库出现故障时,选举切换的时候容易出现瞬间断线现象
- 不能自动扩容
Redis Sentinel原理
首先, 哨兵模式是一种特殊的模式,它是 Redis 高可用的一种实现方案。首先哨兵是一个独立的进程, 可以实现对 Redis 实例的监控、通知、自动故障转移。
实际上,每个哨兵节点每秒通过 ping 去进行心跳监测(包括所有 redis 实例和 sentinel 同伴),并根据回复判断节点是否在线。
如果某个 sentinel 线程发现主库没有在给定时间( down-after-milliseconds)内响应这个 PING,则这个 sentinel 线程认为主库是不可用的,这种情况叫 “主观失效”(即SDOWN);这种情况一般不会引起马上的故障自动转移,但是当多个 sentinel 线程确实发现主库是不可用并超过 sentinel.conf 里面的配置项 sentinel monitor mymaster {#ip} {#port} {#number} 中的 #number 时候(这里实际上采用了流言协议),一般其余 sentinel 线程会通过 RAFT 算法推举领导的 sentinel 线程负责主库的客观下线并同时负责故障自动转移,这种情况叫 “客观失效”(即 ODOWN)。
具体流程如下图所示:
哨兵模式的配置项
配置项 | 参数类型 | 作用 |
port | 整数 | 启动哨兵进程端口 |
dir | 文件夹目录 | 哨兵进程服务临时文件夹,默认为/tmp,要保证有可写入的权限 |
sentinel down-after-milliseconds | <服务名称><毫秒数(整数)> | 指定哨兵在监控Redis服务时,当Redis服务在一个默认毫秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为30000(30秒) |
sentinel parallel-syncs | <服务名称><服务器数(整数)> | 指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求越高 |
sentinel failover-timeout | <服务名称><毫秒数(整数)> | 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟 |
sentinel notification-script | <服务名称><脚本路径> | 指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,比较常用 |
Redis哨兵模式配置
说明
Redis 三主三从可以最完整的保证数据的完整性,但是所需要的服务器资源也是最多的。在一般情况,统筹兼顾数据完整性和方案经济性,一般最优解是采用一主两从三哨兵的模式,我们使用的配置如下所示:
实例 | IP | 端口 | 备注 |
Redis(主) | 192.168.33.135 | 9500 | |
Redis(从) | 192.168.33.136 | 9501 | |
Redis(从) | 192.168.33.133 | 9502 | |
Sentinel(1) | 192.168.33.135 | 26379 | 默认端口 |
Sentinel(2) | 192.168.33.136 | 26379 | 默认端口 |
Sentinel(3) | 192.168.33.133 | 26379 | 默认端口 |
创建目录
首先,我们在 135 机器上,创建配置存放的目录,命令如下:
mkdir -p /usr/local/redis/master
mkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
接着,我们在 136 机器上,创建类似的目录,命令如下:
mkdir -p /usr/local/redis/slave
mkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
最后,我们在 133 机器上,创建目录,命令如下:
mkdir -p /usr/local/redis/slave
mkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
至此,所有的目录都创建完毕。
创建主从配置
我们首先,在 135 机器上,创建 master 的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/master/redis-master.conf
接着,我们写入如下配置内容:
bind 0.0.0.0
port 9500
logfile "9500.log"
dbfilename "dump-9500.rdb"
daemonize yes
rdbcompression yes
接着,我们在 136 机器上,配置从的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/slave/redis-slave.conf
接着,我们写入如下配置内容:
bind 0.0.0.0
port 9501
logfile "9501.log"
dbfilename "dump-9501.rdb"
daemonize yes
rdbcompression yes
slaveof 192.168.33.135 9500
我们再次配置 133 机器上的从配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/slave/redis-slave.conf
接着,我们写入如下配置内容:
bind 0.0.0.0
port 9502
logfile "9502.log"
dbfilename "dump-9502.rdb"
daemonize yes
rdbcompression yes
slaveof 192.168.33.135 9502
至此,我们的主从配置已经配置完毕了。
创建sentinel配置
我们首先,在 135 机器上,创建 sentinel 的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/sentinel/sentinel.conf
接着,我们写入如下配置内容:
port 26379
logfile "26379.log"
daemonize yes
# 这里定义主库的IP和端口,还有最后的2表示要达到2台sentinel认同才认为主库已经挂掉
sentinel monitor mymaster 192.168.33.135 9500 2
# 主库在30000毫秒(即30秒)内没有反应就认为主库挂掉(即主观失效)
sentinel down-after-milliseconds mymaster 30000
# 若新主库当选后,允许最大可以同时从新主库同步数据的从库数
sentinel parallel-syncs mymaster 1
# 若在指定时间(即180000毫秒,即180秒)内没有实现故障转移,则会自动再发起一次
sentinel failover-timeout mymaster 180000
接着,在 136 和 133 机器创建同样的配置文件,写入一模一样的配置内容。
启动
我们首先,在 135 机器启动 Redis 主,具体命令如下:
redis-server /usr/local/redis/master/redis-master.conf
接着,我们在 136 机器启动 Redis 从,具体命令如下:
redis-server /usr/local/redis/slave/redis-slave.conf
同样,我们在 133 机器启动 Redis 从,具体命令如下:
redis-server /usr/local/redis/slave/redis-slave.conf
至此,我们的主从已经启动完毕,现在,我们启动哨兵,首先在 135 机器启动,具体命令如下:
redis-server /usr/local/redis/sentinel/sentinel.conf --sentinel
接着,在 133 和 136 输入相同的命令启动即可。注意,这里我们直接使用了 redis-server 命令启动了 sentinel,也可以直接使用 redis 提供的 redis-sentinel 工具直接启动。全部启动完毕之后,我们可以使用 ps 命令,查看,具体命令如下:
ps -ef | grep redis-server
全部启动成功,则输出如下:
主从数据同步
我们首先,使用 redis-cli 登录 redis master,即 135 机器的 9500 端口,具体命令如下:
redis-cli -p 9500
接着,我们使用 GET 命令,查看键 URL 的内容,具体命令如下:
GET URL
执行完毕后,如下图所示:
同时,我们在 136 机器的 slave 上即 9501 端口,同样查看 URL 的值,执行完毕后,如下图所示:
最后,我们同样在 133 的 slave 上即 9502 端口查看 URL 的值,执行完毕后,如下图所示:
我们看到,此时三个机器上的 URL 都为空,现在,我们在 135 机器的 9500 端口也就是 redis master 上设置 URL 的值,具体命令如下:
SET URL www.haicoder.net
执行完毕后,如下图所示:
现在,我们可以在两台 slave 上,再次查看 URL 的值,我们发现,这两台 slave 都有对应的值了,如下图所示:
即,我们的主从配置完毕了。
高可用主从切换
现在,我们验证高可用,也就是能够实现自动的主动切换,我们首先停掉 master,也就是 135 机器的 9500 端口,我们执行如下命令即可:
shutdown
执行完毕后,如下图所示:
此时,我们模拟了主节点宕机了,现在,我们分别查看两个 slave 节点的配置,我们分别登录 133 和 136 机器的 slave,执行如下命令:
INFO Replication
在 9501 端口执行后,输出如下:
我们看到,此时原来是 slave 的已经自动切换为了 master,这就是哨兵在起作用,实现了故障后的主备切换,如果这时候我们在新的 9501 的 master 上设置数据,并在 9502 端口查看数据,此时也是可以同步数据的。
相关推荐
- MySQL数据库中,数据量越来越大,有什么具体的优化方案么?
-
个人的观点,这种大表的优化,不一定上来就要分库分表,因为表一旦被拆分,开发、运维的复杂度会直线上升,而大多数公司和开发人员是欠缺这种能力的。所以MySQL中几百万甚至小几千万的表,先考虑做单表的优化。...
- Redis的Bitmap(位图):签到打卡、用户在线状态,用它一目了然
-
你是不是每天打开APP,第一时间就是去“签到打卡”?或者在社交软件里,看到你的朋友头像旁边亮着“在线”的绿灯?这些看似简单的功能背后,都隐藏着一个有趣而高效的数据结构。如果让你来设计一个签到系统:用户...
- 想知道有多少人看了你的文章?Redis HyperLogLog几KB就搞定!
-
作为一名内容创作者,你每天最期待的,除了文章阅读量蹭蹭上涨,是不是还特别想知道,到底有多少个“独立用户”阅读了你的文章?这个数字,我们通常称为“UV”(UniqueVisitors),它比总阅读量更...
- Redis的“HyperLogLog”:统计网站日活用户,省内存又高效的神器
-
你可能从未听过这个拗口的名字——“HyperLogLog”,它听起来就像是某个高深莫测的数学公式。但请相信我,理解它的核心思想并不难,而且一旦你掌握了它,你会发现它在处理大数据统计问题时,简直就是“救...
- 阿里云国际站:为什么我的云服务器运行缓慢?
-
本文由【云老大】TG@yunlaoda360撰写一、网络性能瓶颈带宽不足现象:上传/下载速度慢,远程连接卡顿。排查:通过阿里云控制台查看网络流量峰值是否接近带宽上限34。解决:升级带宽(如从1M提...
- Java 近期新闻:Jakarta EE 11和Spring AI更新、WildFly 36.0 Beta、Infinispan
-
作者|MichaelRedlich译者|明知山策划|丁晓昀OpenJDKJEP503(移除32位x86移植版本)已从“ProposedtoTarget”状态进入到“T...
- 腾讯云国际站:怎样设置自动伸缩应对流量高峰?
-
云计算平台服务以阿里云为例:开通服务与创建伸缩组:登录阿里云控制台,找到弹性伸缩服务并开通。创建伸缩组时,选择地域与可用区,定义伸缩组内最小/最大实例数,绑定已有VPC虚拟交换机。实例模板需...
- 【案例分享】如何利用京东云建设高可用业务架构
-
本文以2022年一个实际项目为基础,来演示在京东云上构建高可用业务的整个过程。公有云及私有云客户可通过使用京东云的弹性IAAS、PAAS服务,创建高可用、高弹性、高可扩展、高安全的云上业务环境,提升业...
- Spring Security在前后端分离项目中的使用
-
1文章导读SpringSecurity是Spring家族中的一个安全管理框架,可以和SpringBoot项目很方便的集成。SpringSecurity框架的两大核心功能:认证和授权认证:...
- Redis与Java集成的最佳实践
-
Redis与Java集成的最佳实践在当今互联网飞速发展的时代,缓存技术的重要性毋庸置疑。Redis作为一款高性能的分布式缓存数据库,与Java语言的结合更是如虎添翼。今天,我们就来聊聊Redis与Ja...
- Redis在Java项目中的应用与数据持久化
-
Redis在Java项目中的应用与数据持久化Redis简介:为什么我们需要它?在Java项目中,Redis就像一位不知疲倦的快跑选手,总能在关键时刻挺身而出。作为一个内存数据库,它在处理高并发请求时表...
- Redis 集群最大节点个数是多少?
-
Redis集群最大节点个数取决于Redis的哈希槽数量,因为每个节点可以负责多个哈希槽。在Redis3.0之前,Redis集群最多支持16384个哈希槽,因此最大节点数为16384个。但是在Redi...
- Java开发岗面试宝典:分布式相关问答详解
-
今天千锋广州Java小编就给大家分享一些就业面试宝典之分布式相关问题,一起来看看吧!1.Redis和Memcache的区别?1、存储方式Memecache把数据全部存在内存之中,断电后会挂掉,数据不...
- 当Redis内存不足时,除了加内存,还有哪些曲线救国的办法?
-
作为“速度之王”的Redis,其高性能的秘密武器之一就是将数据存储在内存中。然而,内存资源是有限且昂贵的。当你的Redis实例开始告警“内存不足”,或者写入请求被阻塞时,最直接的解决方案似乎就是“加内...
- 商品详情页那么多信息,Redis的“哈希”如何优雅存储?
-
你每天网购时,无论是打开淘宝、京东还是拼多多,看到的商品详情页都琳琅满目:商品名称、价格、库存、图片、描述、评价数量、销量。这些信息加起来,多的惊人。那么问题来了:这些海量的商品信息,程序是去哪里取出...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- MySQL数据库中,数据量越来越大,有什么具体的优化方案么?
- Redis的Bitmap(位图):签到打卡、用户在线状态,用它一目了然
- 想知道有多少人看了你的文章?Redis HyperLogLog几KB就搞定!
- Redis的“HyperLogLog”:统计网站日活用户,省内存又高效的神器
- 阿里云国际站:为什么我的云服务器运行缓慢?
- Java 近期新闻:Jakarta EE 11和Spring AI更新、WildFly 36.0 Beta、Infinispan
- 腾讯云国际站:怎样设置自动伸缩应对流量高峰?
- 【案例分享】如何利用京东云建设高可用业务架构
- Spring Security在前后端分离项目中的使用
- Redis与Java集成的最佳实践
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)