Redis基础总结、持久化、主从复制、哨兵模式、内存淘汰策略、缓存

news2024/12/25 9:19:44

文章目录

    • Redis 基础
      • Redis 是什么,有哪些特点
      • 为什么要使用 Redis 而不仅仅依赖 MySQL
      • Redis 是单线程吗
      • Redis 单线程为什么还这么快
    • Redis 数据类型和数据结构
      • 五种基本数据结构及应用场景
      • 其他数据类型
      • Redis 底层数据结构
    • Redis 持久化
      • 数据不丢失的实现
      • AOF 日志
      • RDB 快照
      • 混合持久化
      • AOF 和 RDB 的选择
      • AOF 重写的执行过程
      • RDB 快照的执行过程
      • 混合持久化的执行过程
    • Redis 功能和高可用性
      • 主从复制
        • 全量复制
        • 增量复制
        • 全量复制使用 RDB 的原因
      • 哨兵模式
      • 切片集群
      • 集群脑裂
    • 过期删除
    • 内存淘汰策略
      • LRU 和 LFU 算法
    • Redis缓存
      • 缓存雪崩
        • 应对策略
      • 缓存击穿
      • 缓存穿透
        • 常见原因及处理方法
      • 保证数据库和缓存的一致性
        • 写策略
        • 读策略
      • 保证删除缓存操作一定能成功
        • 重试机制
        • 订阅BINLog

Redis 基础

Redis 是什么,有哪些特点

Redis 是一个开源的基于内存的数据库,具有以下特点:

  1. 基于内存:读写速度非常快,适用于缓存、高性能应用场景。
  2. 持久性:支持将数据持久化到磁盘,防止数据丢失。
  3. 多数据结构:支持字符串、哈希表、列表、集合、有序集合等。
  4. 原子性操作:保证操作的原子性,确保数据一致性。
  5. 分布式特性:提供多种集群方案,提高可扩展性和可用性。

为什么要使用 Redis 而不仅仅依赖 MySQL

  • 高性能:读写速度快,适用于频繁读写的数据。
  • 高并发:高效处理并发请求,适用于快速响应的场景。
  • 丰富的数据结构:处理特定类型数据和实现特定功能更灵活。
  • 减轻数据库压力:缓存常用数据,减轻 MySQL 等数据库的压力。

Redis 是单线程吗

Redis 的网络请求模块是单线程的,但其他模块使用多线程,以提高性能。

Redis 单线程为什么还这么快

  1. 基于内存存储:内存访问速度快。
  2. 非阻塞单线程:避免多线程竞争和同步开销。
  3. 高效的数据结构:如 STRING、LIST、HASH 等。
  4. I/O 多路复用:同时监听多个 Socket,实现高效并发处理。

Redis 数据类型和数据结构

五种基本数据结构及应用场景

  1. String(字符串):缓存对象、计数、分布式锁。底层的数据结构实现主要是SDS(简单动态字符串)
  2. List(列表):消息队列。底层数据结构是双向链表或者压缩列表
  3. Set(集合):点赞、共同关注、抽奖活动。底层由哈希表或整数集合(都是整数且元素个数小于 512个)实现
  4. Hash(哈希):缓存对象、购物车。底层由哈希表或压缩列表(哈希类型元素个数小于512个,所有值小于 64 字节)实现
  5. Zset(有序集合):排行榜。底层数据结构压缩列表或跳表
    image-20240802164324909|500|500

其他数据类型

  1. BitMap:签到统计、用户登陆态判断。
  2. HyperLogLog:基数统计,如网页面 UV 计数。不准确。优点在输入元素的 数量或者体积非常非常大时,所需的内存空间总是固定的、并且很小
  3. GEO:存储地理位置信息。
  4. Stream:消息队列。自动生成全局唯一ID,支持以消费组形式消费数据

Redis 底层数据结构

  1. SDS(简单动态字符串):动态扩容,支持字符串和二进制数据。
  2. 双端链表:快速插入和删除。无法很好的利用CPU缓存,内存开销比较大
  3. 压缩列表:压缩列表是一种紧凑的、可变⻓度,由连续内存块组成的顺序型数据结构。在内存使用效率上比较高
  4. 哈希表:快速查询,采用了拉链法解决哈希冲突。
  5. 整数集合:高效存储整数值。二进制表示
  6. 跳表:多层有序链表,查找复杂度 O(logN)。
  7. quicklist:双向链表+压缩列表的组合。quicklist 就是一个链表,而链表中的每个元素又是一个压缩列 表
  8. listpack:只记录当前节点的长度,避免连锁更新问题。
    image-20240802164814316|500|500

Redis 持久化

数据不丢失的实现

Redis 通过以下三种方式实现数据持久化,将数据存储到磁盘,确保在重启时可以恢复数据:

  • AOF 日志:记录每个写操作命令,以日志形式存储。
  • RDB 快照:定期将内存数据快照保存为二进制文件。
  • 混合持久化:结合 AOF 和 RDB 的优点,提供更快的恢复速度和较少的数据丢失。

AOF 日志

  • 机制:先执行命令,把数据写入内存,记录每个写操作命令,重启时重放日志恢复数据。
  • 优点:避免记录错误命令,不阻塞当前写操作。
  • 写回策略
    • Always:每次写操作后立即写回磁盘,最安全,但性能较低。
    • Everysec:每秒写回一次,折中方案,性能和数据安全性较好。
    • No:由操作系统控制写回时机,性能最高,但数据安全性较低。
  • 重写机制:扫描数据中所有的键值对数据,然后为每一个键值对生成一条写操作命令,接着将该命令写入到新的 AOF 文件,重写完成后,就替换掉现有的 AOF 日志。重写的过程是由后台子进程完成的,这样可以使得主进程可以继续正常处理命令。
    • 触发时机
      • 手动执行 bgrewriteaof 命令。
      • 主从复制完成。
      • AOF 重写被设置为待调度执行。
      • AOF 文件大小比例超出阈值,以及 AOF 文件的大小绝对值超出阈值。

RDB 快照

  • 机制:记录某一时刻的内存数据快照,以二进制方式保存到磁盘。
  • 优点:数据恢复速度快,文件体积小。
  • 缺点:频率太低会丢失数据,频率太高会影响性能。
  • 生成方式
    • save:在主线程执行,可能阻塞 Redis 的其他操作。
    • bgsave:在子进程执行,避免阻塞主线程,适合大规模数据保存。

混合持久化

  • 机制:结合 AOF 和 RDB,先将内存数据以 RDB 方式写入 AOF 文件,然后将增量命令以 AOF 方式写入。文件前半部分是 RDB 格式的全量数据(加载速度快),后半部分是 AOF 格式的增量数据(数据丢失更少)。
  • 优点:快速恢复数据,降低数据丢失风险,结合了 RDB 的快速加载和 AOF 的持久性优势。
  • 缺点:AOF 文件可读性变差,兼容性较差(Redis 4.0 之前版本不支持)。

AOF 和 RDB 的选择

  • AOF 优点:持久性更好,丢失数据较少,但恢复速度较慢。
  • RDB 优点:数据恢复速度快,但快照频率难以掌控。
  • 混合持久化:综合两者优点,适合需要快速恢复数据且不希望数据丢失的场景。

AOF 重写的执行过程

  1. 启动重写:手动或触发条件满足时,Redis 启动 AOF 重写。
  2. 生成新文件:子进程遍历所有数据,生成新的 AOF 文件。
  3. 处理增量数据:在生成新文件过程中,增量数据被记录到缓冲区。
  4. 替换旧文件:新 AOF 文件生成完毕后,增量数据写入新文件,替换旧 AOF 文件。

RDB 快照的执行过程

  1. save 命令:主线程执行,阻塞其他操作。
  2. bgsave 命令:子进程执行,避免主线程阻塞。
  3. 文件生成:快照生成的文件包含当前内存中的所有数据。
  4. 文件加载:重启时加载 RDB 文件恢复数据。

混合持久化的执行过程

  1. 启动重写:AOF 重写过程中,子进程将内存数据以 RDB 方式写入 AOF 文件。
  2. 记录增量数据:主线程处理的操作命令记录到重写缓冲区,以 AOF 方式写入新文件。
  3. 文件替换:新文件生成后,通知主进程将其替换旧文件。新文件前半部分为 RDB 格式数据,后半部分为 AOF 格式数据。
  4. 快速恢复:重启时,先加载 RDB 部分,快速恢复大部分数据,再加载 AOF 部分,确保数据一致性。

Redis 功能和高可用性

主从复制

image.png|500|500
Redis 通过主从复制模式实现数据的高可用性,保证数据副本的一致性。主从复制模式下,读写操作分离:

  • 读操作:主库和从库都可以接收。
  • 写操作先在主库执行,然后同步到从库
全量复制
  1. 建立连接:从库与主库建立连接,主库确认后开始同步。
  2. 主库发送数据:主库发送当前数据的 RDB 快照及增量写命令。
  3. 从库接收数据:从库接收 RDB 文件和增量写命令,更新数据状态。
    image.png|500|500
增量复制

从库发生宕机,重新连接后数据的同步操作(增量复制)
image.png|500|500

  1. 从库宕机重连:从库发生宕机,主库会把断连期间收到的写操作命令,写到repl_backlog_buffer中;从库重新连接主库后,发送 psync 命令并传递当前的复制偏移量slave_repl_offset。
  2. 数据同步:主库根据从库的复制偏移量,决定进行增量复制还是全量复制(从库相差 > repl_backlog_buffer)。
全量复制使用 RDB 的原因
  1. 压缩数据:RDB 文件内容是经过压缩的二进制,文件较小。
  2. 性能影响小:AOF 文件需要选择文件刷盘的策略,选择不当会影响性能,而 RDB 文件只在备份和同步时生成。

哨兵模式

Redis 的哨兵模式用于监控主从服务器,提供主从节点故障转移的功能,实现自动故障转移和高可用性。哨兵的功能包括:

  • 监控:定期检查主从服务器状态。
  • 通知:发现问题时通知相关人员。
  • 故障迁移:自动主从切换。
  • 配置管理:统一管理主从地址。

切片集群

当缓存数据量大到一台服务器无法承载时,使用 Redis 切片集群将数据分布在多个服务器上,降低系统对单主机点的依赖,提高读写性能。切片集群的工作原理:

  1. 数据分片:将数据集划分为 16384 个槽,每个节点管理部分槽的数据。
  2. 节点间通信:节点通过 gossip 协议互相通信,保持一致性。
  3. 数据分布:根据键的 CRC16 哈希值确定数据属于哪个槽,并存储到相应节点。
  4. 故障检测:哨兵机制检测节点状态,重新分配槽并选举新主节点。
  5. 客户端路由:客户端根据键的哈希值确定目标节点,直接与负责数据的节点通信。
  6. 数据复制:每个槽有一个主节点和若干个从节点,数据写入主节点后异步复制到从节点。

集群脑裂

脑裂是指在网络故障时,主节点的网络突然发生了问题与所有的从节点都失联,但与客户端正常通信,这些数据被主节点缓存到了缓冲区里。哨兵 也发现主节点失联了,就会在从节点中选举出一个leader作为主节点,导致出现多个主节点。解决方法:

  1. 主节点写保护:主节点在发现从节点断开或通信超时数量少于阈值时,禁止写操作。
  2. 从节点配置:设置主节点需要从节点的 ACK 消息数量和延迟限制,确保数据一致性。

过期删除

Redis 支持为键设置过期时间,自动删除过期键值对,采用以下删除策略:

  1. 定时删除:设置定时事件,到时间自动删除键,占用 CPU 时间多。
  2. 惰性删除:不主动删除,访问键时检查其是否过期,节省 CPU 时间,但可能浪费内存。
  3. 定期删除:每隔一段时间随机抽取部分键进行检查和删除,均衡 CPU 和内存使用。
    Redis 选择「惰性删除+定期删除」这两种策略配和使用,以求在合理使用 CPU 时间和避免内存浪费之间取得平衡

内存淘汰策略

当内存不足时,Redis 会根据配置的淘汰策略删除一些键以释放内存。常见策略:

  1. NoEviction:不进行数据淘汰,内存不足时返回错误。
  2. VolatileTTL:优先淘汰更早过期的键。
  3. VolatileLRU:对带过期时间的键使用 LRU 策略,其他键使用 NoEviction 策略。
  4. VolatileRandom:对带过期时间的键随机淘汰,其他键使用 NoEviction 策略。
  5. VolatileLFU:对带过期时间的键使用 LFU 策略,其他键使用 NoEviction 策略。
  6. AllKeysLRU:根据最近最少使用原则淘汰最久未使用的键。
  7. AllKeysRandom:随机选择一个键进行淘汰。
  8. AllKeysLFU:根据最少频繁使用原则淘汰最少使用的键。
    可以使用 config get maxmemory-policy 命令,来查看当前 Redis 的内存淘汰策略

LRU 和 LFU 算法

  1. LRU(Least Recently Used):淘汰最近最少使用的对象。
    • 实现:随机取若干值,淘汰最久未使用的对象。
  2. LFU(Least Frequently Used):淘汰使用频率最低的对象。
    • 实现:维护使用计数,淘汰使用计数最低的对象。

区别

  • LRU:关注最近访问情况,认为最近访问的对象更可能被再次访问。
  • LFU:关注使用频率,认为使用频率低的对象未来访问概率低。

Redis缓存

由于用户请求频繁访问数据库,直接访问数据库可能导致数据库崩溃,因此常常使用Redis作为数据库的缓存层。

缓存雪崩

缓存雪崩:某个时间点,缓存中的大量数据同时失效,大量请求涌向数据库,导致数据库压力剧增。原因可能是缓存过期时间设置相近或Redis故障。

应对策略
  1. 大量数据同时过期

    • 均匀设置过期时间:加随机数,避免大量数据同一时间失效。
    • 使用互斥锁:确保同一时间只有一个请求构建缓存。
    • 后台线程定时更新缓存:让缓存设置“永久有效”。
  2. Redis故障宕机

    • 服务熔断或请求限流:减少直接对数据库的压力。
    • 构建Redis高可靠集群:通过主从节点切换确保服务连续。

缓存击穿

缓存击穿:热点数据过期时,大量并发请求查询该数据,导致直接访问数据库,增加数据库负载。可以通过互斥锁或后台更新缓存来解决。

缓存穿透

缓存穿透:请求的数据既不在缓存中,也不在数据库中,导致所有请求直接访问数据库,增加负载。

常见原因及处理方法
  • 业务误操作或恶意攻击
  • 对非法请求做限制
  • 缓存中设置空值或默认值
  • 使用布隆过滤器判断数据是否存在
  • image.png|500|500

保证数据库和缓存的一致性

Cache Aside策略

写策略
  • 更新数据库后删除缓存。
读策略
  • 缓存命中返回数据;未命中从数据库读取数据后写入缓存并返回。

为了高缓存命中率,可以采用更新数据库加更新缓存的方法,但需解决并发导致的一致性问题,例如加分布式锁或设置较短的缓存过期时间。

保证删除缓存操作一定能成功

重试机制

引入消息队列,应用删除失败从消息队列重新读取数据再进行删除,重试多次未成功则报错。

订阅BINLog

订阅binlog日志,准确删除缓存中的数据。通过模拟MySQL从节点获取binlog,解析后删除缓存数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1972882.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何理解复信号z的傅里叶变换在频率v<0的时候恒为0,是解析信号

考虑例子2.12.1的说法。 首先我尝试解释第二个说法。需要注意一个事实是 实函数f的傅里叶变换F的实部是偶函数,虚部是奇函数。如图所示: 注意的是这个图中虽然是离散傅里叶变换的性质,但是对于一般的傅里叶变换的性质是适用的。 推导过程如下…

Tecplot安装error找不到指定模块之解决方案

最近有小伙伴反应,在安装Tecplot 2023版本时,参考教程来操作很顺利,但是在开启软件后,有一个error弹窗,内容如下: 随后用中英文翻译:找不到指定模块 同时,软件内部的Tool工具栏打不…

液位传感器- 从零开始认识各种传感器【二十四期】

液位传感器|从零开始认识各种传感器 1、什么是液位传感器 ? 液位传感器是一种用于检测和测量液体位置和高度的装置,广泛应用于工业、农业、环保和家庭等领域。液位传感器可以实时监测液体的水平,以实现自动化控制和安全防护。 2、液位传感器…

java之方法引用 —— ::

目录 一、简介 二、引用静态方法 1.格式 2.示例 ​编辑 3.条件解析 三、引用成员方法 1.格式 2.示例 四、引用构造方法 1.格式 2.示例 五、类名引用成员方法 1.格式 2.略微不同的方法引用规则 3.示例 六、引用数组的构造方法 1.格式 2.示例 一、简介 方…

C语言笔记39 •数据结构--栈队列-OJ•

栈&队列-OJ 1.给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符串需满足: (1).左括号必须用相同类型的右括号闭合。 (2).左括号必须以正确的顺序闭合。 (3).每个右括…

MQ消息队列篇:三大MQ产品的必备面试种子题

MQ有什么用? MQ(消息队列)是一种FIFO(先进先出)的数据结构,主要用于实现异步通信、削峰平谷和解耦等功能。它通过将生产者生成的消息发送到队列中,然后由消费者进行消费。这样,生产…

【Kubernetes】k8s集群中kubectl的陈述式资源管理

目录 一.k8s集群资源管理方式分类 1.陈述式资源管理方式 2.声明式资源管理方式 二.陈述式资源管理方法 三.kubectl命令 四.项目生命周期 1.创建 kubectl create命令 2.发布 kubectl expose命令 3.更新 kubectl set 4.回滚 kubectl rollout 5.删除 k…

notes for datawhale summer camp chemistry task3

Transformer transformer的诞生 循环神经网络:由于所有的前文信息都蕴含在一个隐向量里面,这会导致随着序列长度的增加,编码在隐藏状态中的序列早期的上下文信息被逐渐遗忘。 卷积神经网络:受限的上下文窗口在建模长文本方面天…

木卫四发布《2024半年度汽车漏洞及威胁情报-简报》

随着智能汽车技术的飞速发展,其安全问题也日益成为行业关注的焦点。木卫四威胁情报中心对2024年上半年国内外智能汽车领域的漏洞情报及安全事件进行了全面研究和分析,发布了《2024半年度汽车漏洞及威胁情报-简报》。本报告中智能汽车威胁情报的来源多样&…

宏集方案 | 传统建筑智能化改造,迈向物联新时代

前言 智能建筑涉及多个系统的集成,如照明、空调、安防等,这些系统的兼容性和协调运作是一大挑战。然而,传统的工业建筑和商业楼宇受早期设计的局限,多个控制系统间互不兼容,并且难以重新部署通信线缆。 针对传统建筑…

Java:查看线程信息

示例用代码 public class Main {static class MyThread extends Thread {Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}public st…

【Canvas与艺术】九角大楼

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>九角大楼</title><style type"text/css">.cen…

“光影魔术手”:一款让照片编辑更高效的软件工具

&#x1f680;&#x1f680;&#x1f680; 摄影爱好者和技术控们&#xff0c;想要照片编辑技能更上一层楼吗&#xff1f;“光影魔术手”带你探索照片美化的高级技巧&#xff0c;这款软件不仅是工具&#xff0c;更是你的技术利器&#xff01; &#x1f308;【专业调色功能解析】…

AS400==使用COBOL写个HELLWORLD

登录后输入命令WRKOBJPDM 可以看到在我的lib下拥有的FILES列表 随便选一个&#xff0c;在OPT输入12回车打开这个FILE&#xff0c;最下面一排提示了&#xff0c;F6创建一个新的MEMBER输入这个FILE FILE相当于文件夹&#xff0c;MEMBER相当于一个代码文件test.py。 移动光标输入…

Leetcode—400. 第 N 位数字【中等】

2024每日刷题&#xff08;151&#xff09; Leetcode—400. 第 N 位数字 算法思想 参考自k神 实现代码 class Solution { public:int findNthDigit(int n) {int digitSize 1;int startNum 1;long long count 9;while(digitSize * count < n) {n - count * digitSize;di…

用Python打造精彩动画与视频,5.1 Matplotlib基础及其动画功能

5.1 Matplotlib基础及其动画功能 在本小节中&#xff0c;我们将介绍Matplotlib的基础知识及其动画功能。Matplotlib是Python中最流行的绘图库之一&#xff0c;它可以生成静态、动态和交互式的图表。通过Matplotlib的动画模块&#xff0c;我们可以创建各种动画效果&#xff0c;…

达梦数据库系列—44.SQL调优

目录 SQL优化思路 1、定位慢sql 2、SQL分析方法 2.1 执行计划 2.2 ET 工具 2.3 dbms_sqltune 工具 3、SQL语句优化 3.1 索引 3.2 SQL语句改写 3.3 表设计优化 3.4 表的连接方式 3.5 HINT 4、统计信息 SQL优化思路 1、定位慢sql 待优化的SQL大致可分为两类&#…

PCIe学习笔记(15)

设备就绪状态 (Device Readiness Status&#xff0c;DRS)消息 &#xff08;Device Readiness Status (DRS) 是PCIe规范中引入的一种机制&#xff0c;旨在改进设备初始化和就绪状态的检测与报告。 在以往的PCIe版本中&#xff0c;系统通常依赖于固定的超时机制来判断设备是否已…

天机学堂 第四天 高并发优化总结

前端每隔15秒就发起一次请求&#xff0c;将播放记录写入数据库。 但问题是&#xff0c;提交播放记录的业务太复杂了&#xff0c;其中涉及到大量的数据库操作&#xff1a; 如何进行优化 单机并发能力 变同步为异步 合并写请求 提高单机并发&#xff1a;优化SQL&#xff0c;尽…

vscode中WSL插件的安装配置

1.安装WSL插件 2.点击左下角的蓝色区域&#xff0c;Connect to WSL连接下载Linux系统&#xff0c;我这里下载Ubuntu ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7ec21d81b4ec49f3856be2d8013bc12f.png 3.输入用户名和密码 4.成功连接 5.配置过程中出现的问题 …