Redis 高可用方案有哪些?(redis生产环境下的高可用)
mhr18 2024-11-09 12:19 29 浏览 0 评论
如果某个 slot 的数据只有部分迁移过去,没有迁移完成,节点收到客户端请求如果能根据 key -> slot -> node 映射关系定位到的节点存在该 key,则直接执行命令,否则就向客户端响应 ASK? 错误,表示该 key 所在的 slot 正在迁移到其他节点,客户端先给目标节点发送 ??ASKING?? 命令询问节点是否可以处理,接着才会发送操作指令。
Redis 高可用方案有哪些?
高可用有两个含义:一是数据尽量不丢失,二是服务尽可能提供服务。 Redis 高可用方案严格意义上来说有 3 种。
- 主从复制架构,这是后两个方案的基石。
- sentinel 哨兵集群。
- Redis Cluster 集群,极力推荐该方式。
一、主从异步复制架构
主从异步复制架构是高可用的基石,主要分为 RDB 内存快照文件全量同步和增量同步。
全量同步
Redis master 执行 bgsave 命令生成 RDB 内存快照文件,slave 收到 RDB 内存快照文件保存到磁盘,并清空当前数据库的数据,再加载 RDB 文件数据到内存中。最后,master 再把发送生成 RDB 文件至同步 slave 加载 RDB 期间接受到的新写命令同步到到 slave。
增量同步
只要主从连接不中断,就会持续进行基于长连接的命令传播复制。在 Redis 2.8 之前,如果主从复制在命令传播时出现了网络闪断,那么,slave 就会和 mater 重新进行一次全量复制,开销非常大。
从 Redis 2.8 开始,网络断了重连之后,slave 会尝试采用增量复制的方式继续同步。
增量复制:用于网络中断等情况后的复制,只将中断期间 mater 执行的写命令发送给 slave,与全量复制相比更加高效。
其中还涉及到 replication buffer 和 repl_backlog 的缓冲区的作用,说到这一块就已经让你脱颖而出了。
接着,你再补充在 Redis 7.0 之后,采用了共享缓冲区的设计。
“因为不管是全量复制还是增量复制,当写请求到达 master 时,指令会分别写入所有 slave 的 replication buffer 以及 repl_backlog_buffer。重复保存,太浪费内存了。
既然存储内容是一样,直接的做法就是主从复制在命令传播时,将这些写命令放在一个全局的复制缓冲区中,多个 slave 共享这份数据,不同 slave 引用缓冲区的不同内容,这就是共享缓冲区的核心思想。”
二、sentinel 集群
Sentinel 是 Redis 的一种运行模式,它专注于对 Redis 实例(主节点、从节点)运行状态的监控,并能够在主节点发生故障时通过一系列的机制实现选主及主从切换,实现自动故障转移,确保整个 Redis 系统的可用性。
sentinel 主要做四件事情。
- 监控 master 和 slave 状态,判断是否下线。
- 每秒一次的频率向 master 和 slave 以及其他 sentinel 发送 PING 命令,如果该节点距离最后一次响应 PING 的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线,当 master 被标记主观下线。
- 其他正在监视这个 master 的所有 sentinel 会按照每秒一次的频率确认 master 是否主观下线。
- 当足够多的 sentinel 都认为 master 主观下线,则标记这个 master 客观下线。
- 选举新 master,如果 master 出现故障,sentine 需要选举一个 slave 晋升为新 master。晋升为新 master 的 slave 是有条件的,先过滤不满足条件的,再打分排优先级。
- slave 优先级,通过 replica-priority 100 配置,值越低,优先级越高。
- 复制偏移量(processed replication offset),已复制的数据量越多越好,slave_repl_offset与 master_repl_offset 差值越小。
- slave runID,在优先级和复制进度都相同的情况下,runID 最小的 slave 得分最高,会被选为新主库。
- 过滤掉下线、网络异常的 slave。
- 过滤掉经常与 master 断开的 slave。
- 执行主从切换,从 sentinel 集群中选举一个 leader 执行故障自动切换。
- 成为 leader 的条件是收到的赞成票大于等于 quorum 的值且赞半数以上。
- 第一个判定 master 主观下线的 sentinel 收到其他 sentinel 节点的回复并确定 master 客观下线后,就会给其他 sentinel 节点发送命令申请成为 leader。
- 通知,通知其他 slave 执行 replicaof 与新的 master 同步数据,并通知客户端与新 master 建立连接。
三、Redis Cluster
Redis Cluster 在 Redis 3.0 及以上版本提供,是一种分布式数据库方案,通过分片(sharding)来进行数据管理(分治思想的一种实践),并提供复制和故障转移功能。
Redis Cluster 并没有使用一致性哈希算法,而是将数据划分为 16384 的 slots ,每个节点负责一部分 slots,slot 的信息存储在每个节点中。
集群 mater 节点最大上限是 16384(官方建议最大节点数为 1000 个),数据库的每个 key 会映射到这 16384 个槽中的其中一个,每个节点可以处理 1 个或者最多 16384 个槽。
“集群各个节点之间是如何通信呢?”
通过 Gossip 协议进行通信,节点之间不断交换信息,交换的信息包括节点出现故障、新节点加入、主从节点变更, slots 信息变更等。常用的 Gossip 消息分为 4 种,分别是:ping、pong、meet、fail。
- meet 消息:通知新节点加入。消息发送者通知接受者加入当前集群。
- ping消息:每个节点每秒向其他节点发送 ping 消息,用于检测节点在线和交换刺激状态信息。
- pong消息:节点接受到 ping 消息后,作为响应消息回复发送方确认正常,同时 pong 还包含了自身的状态数据,想集群广播 pong 消息来通知集群自身状态进行更新。
- fail消息:节点 ping 不通某节点后,则向集群所有节点广播该节点挂掉的消息。
“Redis Cluster 如何实现自动故障转移呢?”
- 故障检测:集群中每个节点都会定期通过 Gossip 协议向其他节点发送 PING 消息,检测各个节点的状态(在线状态、疑似下线状态 PFAIL、已下线状态 FAIL)。并通过 Gossip 协议来广播自己的状态以及自己对整个集群认知的改变。
- master 选举:使用从当前故障 master 的所有 slave 选举一个提升为 master。
- 故障转移:取消与旧 master 的主从复制关系,将旧 master 负责的槽位信息指派到当前 master,更新 Cluster 状态并写入数据文件,通过 gossip 协议向集群广播发送 CLUSTERMSG_TYPE_PONG消息,把最新的信息传播给其他节点,其他节点收到该消息后更新自身的状态信息或与新 master 建立主从复制关系。
“新增节点或者重新分配 slots 导致 slots 与节点之间的映射关系改变了,客户端如何知道把请求发到哪里?”
Redis Cluster 提供了请求重定向机制解决:客户端将请求发送到某个节点上,这个节点没有相应的数据,该 Redis 节点会告诉客户端将请求发送到其他的节点。
MOVED 重定向
当重新分配或者负载均衡,slots 数据已经迁移到其他节点,节点会响应一个 MOVED 错误指引客户端重定向到正确的节点,并且客户端会更新本地 slots 与节点映射关系,以便下次可以正确访问。
ASK 重定向
如果某个 slot 的数据只有部分迁移过去,没有迁移完成,节点收到客户端请求如果能根据 key -> slot -> node 映射关系定位到的节点存在该 key,则直接执行命令,否则就向客户端响应 ASK 错误,表示该 key 所在的 slot 正在迁移到其他节点,客户端先给目标节点发送 ASKING 命令询问节点是否可以处理,接着才会发送操作指令。
注意:ASK 错误指令并不会更新客户端缓存的 slot 分配信息。
为什么集群的 slots 是 16384?
- 正常的 ping 数据包携带节点的完整配置,用的是一个 bitmap 数据结构,它能以幂等方式来更新配置。如果采用 16384 个插槽,占空间 2KB (16384/8);如果采用 65536 个插槽,占空间 8KB (65536/8)。
- Redis Cluster 不太可能扩展到超过 1000 个主节点,太多可能导致网络拥堵。
- 16384 个 slot 范围比较合适,当集群扩展到 1000 个节点时,也能确保每个 master 节点有足够的 slot。
8KB 的心跳包看似不大,但是这个是心跳包每秒都要将本节点的信息同步给集群其他节点。比起 16384 个 slot ,header 大小增加了 4 倍,ping 消息的消息头太大了,浪费带宽。
相关推荐
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
-
在企业级运维、故障排查和性能调优过程中,准确了解服务器的运行环境至关重要。无论是物理机还是虚拟机,都存在各自的优势与限制。在很多场景下,尤其是当你继承一台服务器而不清楚底层硬件细节时,如何快速辨识它是...
- 第四节 Windows 系统 Docker 安装全指南
-
一、Docker在Windows上的运行原理(一)架构限制说明Docker本质上依赖Linux内核特性(如Namespaces、Cgroups等),因此在Windows系统上无法直...
- C++ std:shared_ptr自定义allocator引入内存池
-
当C++项目里做了大量的动态内存分配与释放,可能会导致内存碎片,使系统性能降低。当动态内存分配的开销变得不容忽视时,一种解决办法是一次从操作系统分配一块大的静态内存作为内存池进行手动管理,堆对象内存分...
- Activiti 8.0.0 发布,业务流程管理与工作流系统
-
Activiti8.0.0现已发布。Activiti是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速、稳定的BPMN2流程引擎。Activiti可以...
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
-
MyBatis动态SQL在日常开发中频繁使用,但大多数开发者仅掌握基础标签。本文将介绍五种高阶技巧,助你解锁更灵活的SQL控制能力。一、智能修剪(Trim标签)应用场景:动态处理字段更新,替代<...
- Springboot数据访问(整合Mybatis Plus)
-
Springboot整合MybatisPlus1、创建数据表2、引入maven依赖mybatis-plus-boot-starter主要引入这个依赖,其他相关的依赖在这里就不写了。3、项目结构目录h...
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
-
见证了两个月前勇士与猛龙那个史诗般的系列赛后,甲骨文球馆正式成为了历史。那个大大的红色标志被一个字母一个字母地移除,在周四,一切都成为了过去式。然而这座,别名为“Roaracle”(译注:Roar怒吼...
- Mybatis入门看这一篇就够了(mybatis快速入门)
-
什么是MyBatisMyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为M...
- Springboot数据访问(整合druid数据源)
-
Springboot整合druid数据源基本概念SpringBoot默认的数据源是:2.0之前:org.apache.tomcat.jdbc.pool.DataSource2.0及之后:com.z...
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
-
什么是/etc/profile.d/目录?/etc/profile.d/目录是Linux系统不可或缺的一部分保留配置脚本。它与/etc/profile文件相关联,这是一个启动脚本,该脚...
- 企业数据库安全管理规范(企业数据库安全管理规范最新版)
-
1.目的为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。2.适用范围本规范中所定义的数据管理内容,特指存放在信息系统数据库...
- Oracle 伪列!这些隐藏用法你都知道吗?
-
在Oracle数据库中,有几位特殊的“成员”——伪列,它们虽然不是表中真实存在的物理列,但却能在数据查询、处理过程中发挥出意想不到的强大作用。今天给大家分享Oracle伪列的使用技巧,无论...
- Oracle 高效处理数据的隐藏神器:临时表妙用
-
各位数据库搬砖人,在Oracle的代码世界里闯荡,处理复杂业务时,是不是总被数据“搅得头大”?今天给大家安利一个超实用的隐藏神器——临时表!当你需要临时存储中间计算结果,又不想污染正式数据表...
- Oracle 数据库查询:多表查询(oracle多表关联查询)
-
一、多表查询基础1.JOIN操作-INNERJOIN:返回两个表中满足连接条件的匹配行,不保留未匹配数据。SELECTa.emp_id,b.dept_nameFROMempl...
- 一文掌握怎么利用Shell+Python实现多数据源的异地备份程序
-
简介:在信息化时代,数据安全和业务连续性已成为企业和个人用户关注的焦点。无论是网站数据、数据库、日志文件,还是用户上传的文档、图片等,数据一旦丢失,损失难以估量。尤其是当数据分布在多个不同的目录、服务...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
- 第四节 Windows 系统 Docker 安装全指南
- C++ std:shared_ptr自定义allocator引入内存池
- Activiti 8.0.0 发布,业务流程管理与工作流系统
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
- Springboot数据访问(整合Mybatis Plus)
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
- Mybatis入门看这一篇就够了(mybatis快速入门)
- Springboot数据访问(整合druid数据源)
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- 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)