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

文章目录

    • 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.rhkb.cn/news/390138.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go中的值传递和指针传递

文章目录 1、& 和 *2、空指针3、nil4、用值传递还是指针传递?5、补充 1、& 和 * &后跟一个变量名,得到的是这个变量的内存地址*int类型的变量,代表这个变量里存的值是int类型的变量的内存地址数据类型的指针类型,即在…

Spring Boot 参数校验 Validation 使用

概述 当我们想提供可靠的 API 接口,对参数的校验,以保证最终数据入库的正确性,是必不可少的活。前、后端校验都是保证参数的准确性的手段之一,前端校验并不安全,任何人都可以通过接口来调用我们的服务,就算…

【linux】【操作系统】内核之traps.c源码阅读

C 文件traps.c 是 Linux 内核的一部分,主要处理硬件陷阱和故障。文件中包含多个函数来处理不同类型的异常和错误。下面是详细的解析: 概览 目的:此文件负责处理各种硬件异常和故障。它包括了处理特定类型错误以及初始化异常处理器的函数。文…

前端的学习-CSS(弹性布局-flex)

一:什么是弹性布局-Flex flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。 语法: .box{display: flex; } .box{display: inline-flex; } 注意,设为 Flex 布局以后&#xff0…

SpringBoot整合Knife4j接口文档

1. 在项目入口模块pom文件导入依赖 <!-- knife4j&#xff08;API 文档工具&#xff09; --><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>${knife4j…

新款奔驰S450升级动态按摩座椅有哪些功能

奔驰 S450 升级前排动态按摩座椅通常具有以下功能&#xff1a; 1. 多种按摩模式和强度选择&#xff1a;通过精心设计的气囊和机械装置&#xff0c;能够模拟如揉捏、敲击、推拿等不同的按摩手法&#xff0c;为驾驶者和前排乘客舒缓肌肉疲劳&#xff0c;放松身心。 2. 广泛的按…

6.C基础_输入输出函数

putchar 功能&#xff1a;输出一个字符 函数声明&#xff1a; int putchar(int c);返回值&#xff1a;参数c的ASCLL码值 c&#xff1a;要输出的字符&#xff0c;可以为字符常量、字符变量或表达式 注意点&#xff1a;输出的结果不带\n getchar 功能&#xff1a;从键盘读…

SpringCache集成Redis

1. 添加config配置类 配置SpringCache 与 redis 的集成 配置类 2. 在service层中加注解 在Service层中增加注解 CacheConfig() 里面的CacheNmes是redis的nameSpace命名空间 方法上的Cacheable是key的值 请求结果 第一次会查数据库&#xff0c;后面相同的查询会直接走redis&am…

LBS 开发微课堂|Polyline绘制优化:效果更丰富,性能更佳!

为了让广大的开发者 更深入地了解 百度地图开放平台的技术能力 轻松掌握满满的技术干货 更加简单地接入 开放平台的服务 我们特别推出了 “位置服务&#xff08;LBS&#xff09;开发微课堂” 系列技术案例 第一期的主题是 《Polyline 绘制优化升级》 你还想了解哪些…

vulhub:Apache解析漏洞CVE-2017-15715

Apache HTTPD是一款HTTP服务器&#xff0c;它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个换行解析漏洞&#xff0c;在解析PHP时&#xff0c;1.php\x0A将被按照PHP后缀进行解析&#xff0c;导致绕过一些服务器的安全策略。 #启动靶机 cd /Vulnhub/vulhub-mast…

程序员的魔法石!

本文由 ChatMoney团队出品 AI自己写代码&#xff0c;这只是传说&#xff1f;还是摸鱼新指南&#xff1f; AI出现之前&#xff0c;从来都是老板或产品经理提需求&#xff0c;程序员熬夜加班吭哧吭哧写代码或者是从Github&#xff0c;Stackoverflow上controlc&#xff0c;control…

JavaFX布局-GridPane

JavaFX布局-GridPane 常用实行alignmenthgapvgappaddinggridLinesVisible 实现方式Java实现fxml实现 使用行和列来组织其子节点将节点放置在二维网格中的任何单元格&#xff0c;同时也可以设置跨越行、跨越列 常用实行 alignment 对齐方式&#xff0c;设置内容居中&#xff0…

数据库文件管理

数据库文件与普通文件区别: 1.普通文件对数据管理(增删改查)效率低 2.数据库对数据管理效率高,使用方便 常用数据库: 1.关系型数据库&#xff1a; 将复杂的数据结构简化为二维表格形式 大型:Oracle、DB2 中型:MySql、SQLServer 小型:Sqlite 2.非关…

第三十一天 chrome调试工具

打开调试工具 页面空白处右击 检查 或者F12 使用调试工具 ctrl滚轮改变代码大小 左边是html 右边是css css可以直接改动数值左右箭头或者直接输入 查看颜色 ctrl0 复原浏览器大小 点击元素右侧出现样式引入 没有的话 说明类名或者样式引用错误 这里的.new-left是存在的 如果类…

【Android Studio】UI 布局

文章目录 view布局LinearLayout view 在Android开发中&#xff0c;View是一个非常重要的概念&#xff0c;它是所有用户界面组件的基类。View类及其子类构成了Android应用中的用户界面。每个View都占用屏幕上的一个矩形区域&#xff0c;并可以响应用户输入&#xff08;如触摸、按…

鸿蒙(API 12 Beta2版)NDK开发【JSVM-API使用规范】

JSVM-API使用规范 生命周期管理 【规则】 合理使用OH_JSVM_OpenHandleScope和OH_JSVM_CloseHandleScope管理JSVM_Value的生命周期&#xff0c;做到生命周期最小化&#xff0c;避免发生内存泄漏问题。 每个JSVM_Value属于特定的HandleScope&#xff0c;HandleScope通过OH_JSV…

MySQL精简笔记

基础类型 bit&#xff0c;tinyint&#xff0c;smallint&#xff0c;int&#xff0c;bigintfload&#xff0c;double&#xff08;M&#xff1a;整数小数的位数&#xff0c;D&#xff1a;小数的位数&#xff09;decimal&#xff0c;numeric&#xff08;M&#xff0c;D)&#xff0…

大模型分布式训练之DeepSpeed优化器并行(ZeRO)原理

由于大模型参数量非常庞大&#xff0c;所以我们常常需要用到分布式训练来解决训练过程中计算资源不足的问题&#xff0c;现在也出现了很多大模型相关的分布式训练框架&#xff0c;但是使用的比较多的还是deepspeed的数据并行&#xff0c;那么deepspeed是怎么实现数据并行的呢 文…

【Unity】web gl inputFied 中文输入,同时支持TextMeshInputFied,支持全屏

同时支持TextMeshInputFied&#xff0c;支持全屏。 使用github包【WebGLInput】&#xff1a;https://github.com/kou-yeung/WebGLInput 需要资源的在这里也可以下载 https://download.csdn.net/download/weixin_46472622/89600795 用于unity web gl 中文输入&#xff0c;只需…

【人工智能】边缘计算与 AI:实时智能的未来

&#x1f48e; 我的主页&#xff1a;2的n次方_ &#x1f48e;1. 引言 随着物联网设备数量的爆炸性增长和对实时处理需求的增加&#xff0c;边缘计算与人工智能&#xff08;Edge AI&#xff09;成为一个热门话题。Edge AI 通过在本地设备上运行 AI 算法&#xff0c;减少对云计…