Linux——Redis

一、Redis概念

1.1 Redis定义

Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,通常用作数据库、缓存或消息代理。它支持多种数据结构,如字符串(string)、哈希(hashes)、列表(list)、集合(sets)、有序集合(sorted sets)等,并提供丰富的操作命令。

1.2 Redis的特点

**高性能:**数据存储在内存中,读写速度极快,适合高并发场景。

**持久化:**支持RDB(快照)和AOF(日志)两种持久化机制,确保是数据安全。

**数据结构丰富:**支持多种数据结构,满足不同业务需求。

**原子操作:**所有操作都是原子性的,适合分布式锁等场景。

**扩展性:**支持主从复制、分片(集群)等功能。

1.3 Redis为什么要持久化?

Redis是一个内存数据库,也就是说,你的数据默认是放到内存里的。

内存的特点是什么?速度飞快,但是一断电全都没了 ,所以为了防止Redis重启或者服务器宕机后数据丢失,他必须把内存里的数据保存到磁盘上,这个把内存数据保存到硬盘的动作就叫持久化

什么是RDB?(像给游戏存档拍一张快照)

怎么理解?

RDB是Redis的"快照"持久化方式

它的核心动作是:在某个时间点,把Redis内存中的所有数据,完整的写入磁盘上的一个二进制文件,理解成给Redis数据库拍了一张"全量照片"。

比如你在玩一个大型单机游戏,玩了两个小时,此时点一下存档(BGSAVE),游戏会把你当前这一刻的完整进度,全部压缩成一个存档文件存在硬盘里,这个"存档文件",就是Redis里的RDB文件

RDB什么时候会"拍照存档"?

手动按保存:Redis执行BGSAVE命令

设置自动定时存档:比如配置save 60 100,意思是"如果60s内至少有100个数据被修改了,就自动存一次档"

正常退出:Redis正常关闭时,也会自动存一次档

RDB是怎么拍快照的?

RDB最精妙的地方:利用Linux的fork()系统调用,创建子进程来生成快照,不影响主进程继续处理客户端请求。

主进程(Redis Server)

|

fork()

|

├── 主进程继续处理请求(不阻塞)

└── 子进程(独立)

|

遍历内存中的所有数据

|

写入临时 RDB 文件

|

完成后替换旧 RDB 文件

关键技术点:(写时复制)

fork()出的子进程和父进程共享同一块物理内存页。

父进程(主redis)在写入数据时,如果发现某个内存页被共享,会先复制一份新页面再修改

子进程从头到尾读的都是触发快照那一瞬间的完整数据,不会受后续写入的影响

RDB有什么优缺点?

优点:文件非常小;恢复极快

缺点:容易丢数据;存档时耗性能

什么是AOF?(像给游戏写操作日记)

怎么理解?

比如你玩游戏,旁边坐了一个书记员,你每做一个动作,书记员就立马在日记本上记一笔:玩家获得了一把剑;玩家砍死了一只猪;玩家走到河边

这个日记本就是Redis里的AOF文件。

AOF什么时候记日记?

Redis默认是每执行一条写命令,就会立刻把这条命令写到AOF文件末尾。

写到硬盘还是写到内存?

**最勤快:**写完一条命令,立马把日记放到磁盘里锁好

**一般勤快:**先把命令记住,每隔一秒才统一写到硬盘里

**最懒:**什么时候写到硬盘里交给操作系统决定

AOF的"日记本"会无限变大,怎么办?

很重要的机制:重写机制

分身不看旧的日记本,而是直接去看当前游戏的最终状态(重写)

玩了一整天游戏,书记员的日记本已经写了有一万页了。其中有一页写"拿到一块钱",后面有1000页都在写"花掉1块钱",最后还有一页写"银行存款0"

如果要恢复今天的游戏进展,书记员要从头翻这一万页日记,逐条执行,太慢了

所以Redis会不定期做一件事:重新整理日记本(AOF重写)

  • Redis叫来一个分身
  • 分身不看旧的日记本,而是直接去当前最终的状态
  • 把这一万页日记,浓缩成两页:SET 银行存款 0;删除前面那一万页废话
  • AOF重写,就是把"过程日记"精简成"当前结果状态",让日记本永远保持苗条
AOF优缺点?

优点:数据安全性高;实时性好

缺点:文件体积大;恢复速度慢

1.4 Redis的用途

缓存:加速数据访问,减轻后端数据库压力

会话存储:存储用户会话信息,支持分布式系统

消息队列:利用列表或者发布/订阅模式实现消息传递

实时排行榜:使用有序集合实现实时排行榜功能,使用Redis有序集合(ZSET)

Redis的ZSET,完美解决了这个问题。它像是一个自动排序的花名册,每个元素都有一个分数(score),内部通过跳表(skip list)实现,让增删改查排名的操作时间复杂度都变为O(logN)

可以把它当作一个自带排序功能的超级数组,无论有几百万个元素,插入一个新数据或者查询某个数据的排名都非常快

缓存策略:redis和Buffer Pool是如何协作的?

实际采用的是旁路缓存模式

读请求:

应用->先查redis

->命中->直接返回

->未命中->查MySQL(此时MySQL可能查Buffer Pool或者磁盘)

->将查到的结果写入Redis(设置过期时间)

->返回

写请求:

应用->先更新Mysql(数据落盘/落到 Buffer Pool)

->然后删除Redis 中的旧缓存(或更新)

为什么先更新MySQL,而不是先更新Redis?

因为要保证最终数据一致性。如果先更新Redis成功了,但是MySQL更新失败了,Redis里就成了脏数据,所以一般都是先更新数据库,再删缓存(下次要读请求重新加载)

相关推荐
Oo_行者_oO1 小时前
删库先别跑路,万一修复呢?MySQL 误删数据恢复可落地运维文档
数据库·面试
曾阿伦1 小时前
深入了解MongoDB 两地三中心架构
数据库·mongodb·架构
代码雕刻家2 小时前
1.24.MySQL-idea中连接MySQL的基本操作
数据库·mysql·intellij-idea
csjane10792 小时前
Redisson 限流原理
java·redis
ThanksGive2 小时前
Go 服务里的 Redis 锁惊群问题:一次本地合流优化实践
redis
炘爚2 小时前
MySQL——事务和隔离级别
数据库·mysql
DeboPXK2 小时前
NSK VH25EM 高防尘法兰型导轨技术手册
服务器·网络·数据库·经验分享·规格说明书
小挪号底迪滴2 小时前
Redis 和 MySQL 数据不一致怎么办?缓存更新策略实战
redis·mysql·缓存
翼龙云_cloud2 小时前
阿里云国际代理商:如何使用RDS MySQL 构建网站数据库?
数据库·mysql·阿里云