当前位置: 首页 > article >正文

Redis入门到精通(二):入门Redis看这一篇就够了

文章目录

  • 一、Redis的双写一致性
    • 1.延迟双删
    • 2.添加分布式锁
    • 3.异步监听+可靠消息
      • 基于MQ消息队列的异步监听
      • 基于Canal的异步通知
  • 二、Redis的持久化
    • 持久化流程
    • 1.RDB机制
      • 1.1save
      • 1.2bgsave
      • 1.3自动触发
    • 2.AOF机制
      • 三种触发机制
      • 3.RDB和AOF的对比
  • 三、Redis的数据删除策略
    • 1.惰性删除
    • 2.定期删除
  • 四、Redis的淘汰策略

一、Redis的双写一致性

当修改了数据库的内容,同时也要更新缓存的数据,缓存和数据库的数据要保持一致

1.延迟双删

  • 读操作:缓存命中,直接返回;缓存未命中,查询数据库并写入缓存,设置超时时间
  • 写操作:延迟双删
  • 特点:
    在这里插入图片描述
  1. 为什么是要删除缓存而不是更新缓存呢?
    1.1 更新缓存的优缺点:更新缓存的优点是每次数据变化都能够及时地更新缓存,这样不容易出现查询未命中的情况,但这种情况的消耗很大,如果数据需要经过复杂的计算再写入缓存的话,频繁的更新会影响到服务器的性能。如果是写入数据比较频繁的场景,可能会导致频繁的更新缓存而没有业务读取该数据
    1.2 删除缓存的优缺点: 删除缓存的优点是操作简单,缺点是删除了缓存,下一次操作容易出现未命中的情况,此时就需要读取数据库
    对比而言,删除缓存是更优选

  2. 是先删除缓存还是先删除数据库呢?
    无论先后顺序,都会有脏数据的风险

  3. 为什么要删除两次缓存?
    因为删除缓存,修改数据库后,会造成脏数据的风险,所以还需要再次删除缓存

  4. 为什么要延迟删除?
    因为数据库是主从模式,是读写分离的,我们需要等待一会数据库将数据从主节点同步到从节点,所以需要延迟删除

  5. 那么这样的设定是否一致能保证一致性呢?
    不能保证,因为时间无法控制,不能保证数据库”从库“更新后删除缓存。如果在”从库“更新前删除,用户再在更新前查”从库“又把脏数据写在缓存中了。

2.添加分布式锁

这里有一种添加分布式锁的方案来保证数据的强一致性
我们存入缓存中的数据,一般都是读多写少的数据,那么我们可以添加读写锁的方式来保证数据的强一致性。在读数据时,添加共享锁readLock,加锁之后m,其他线程可以共享读操作。在写数据时,添加排他锁writeLock,加锁之后,阻塞其他线程写的写操作。这样做可以保证数据强一致性,但是性能较低。

3.异步监听+可靠消息

基于MQ消息队列的异步监听

在这里插入图片描述

基于Canal的异步通知

在这里插入图片描述
什么是binlog?

Binlog(Binary Log) 是MySQL数据库中的二进制日志文件,用于记录数据库的所有更改操作。它以二进制的形式存储,包含了对数据库执行的所有修改操作的详细信息,如插入、更新、删除等。Binlog是MySQL事务日志的一部分,与Redo Log(重做日志)一起,确保数据库的一致性、持久性,以及提供一些关键的数据库管理功能。

二、Redis的持久化

redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失。Redis为我们提供了持久化的机制,分别是RDB(Redis DataBase)和AOF(Append Only File)

持久化流程

  1. 客户端向服务端发送写操作(数据在客户端的内存中)
  2. 数据库服务端接收到客户端的写数据的请求(数据在服务端的内存中)
  3. 服务端调用write这个系统调用,将数据向磁盘上写(数据在系统内存的缓存区中)
  4. 操作系统将缓存区中的数据转移到磁盘控制器上(数据在磁盘缓存中)
  5. 磁盘控制器将数据写到磁盘的物理介质上(数据真正写在磁盘上)

1.RDB机制

RDB其实就是把数据以快照的形式保存在磁盘上

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

RDB机制是通过把某个时刻的所有数据生成一个快照来保存,颞部有一种触发机制,是实现这个过程。对于RDB来说,提供了三种机制:save、bgsave、自动化

1.1save

该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止

1.2bgsave

执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:
在这里插入图片描述

具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

1.3自动触发

除了通过客户端发送命令外,还有一种方式,就是在Redis配置文件中的save指定到达触发RDB持久化的条件,比如【多少秒内至少达到多少写操作】就开启RDB数据同步。

例如我们可以在配置文件redis.conf指定如下的选项:

# 900s内至少达到一条写命令
save 900 1
# 300s内至少达至10条写命令
save 300 10
# 60s内至少达到10000条写命令
save 60 10000

之后在启动服务器时加载配置文件。

# 启动服务器加载配置文件
redis-server redis.conf

这种通过服务器配置文件触发RDB的方式,与bgsave命令类似,达到触发条件时,会forks一个子进程进行数据同步,不过最好不要通过这方式来触发RDB持久化,因为设置触发的时间太短,则容易频繁写入rdb文件,影响服务器性能,时间设置太长则会造成数据丢失。

RDB默认生成的文件名为dump.rdb,当然,我可以通过配置文件进行更加详细配置,比如在单机下启动多个redis服务器进程时,可以通过端口号配置不同的rdb名称,如下所示:

# 是否压缩rdb文件
rdbcompression yes

# rdb文件的名称
dbfilename redis-6379.rdb

# rdb文件保存目录
dir ~/redis/

save和bgsave的对比

命令savebgsave
IO类型同步异步
阻塞?是(阻塞发生在fork)
复杂度O(N)O(N)
优点不会消耗额外内存不阻塞客户端命令
缺点阻塞客户端命令想要fork消耗内存

2.AOF机制

量备份总是耗时的,有时候我们提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。


持久化原理

在这里插入图片描述


文件重写原理
AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。
在这里插入图片描述
Redis默认不开启AOF持久化方式,我们可以在配置文件中开启并进行更加详细的配置,如下面的redis.conf文件:

# 开启aof机制
appendonly yes

# aof文件名
appendfilename "appendonly.aof"

# 写入策略,always表示每个写操作都保存到aof文件中,也可以是everysec或no
appendfsync always

# 默认不重写aof文件
no-appendfsync-on-rewrite no

# 保存目录
dir ~/redis/

三种触发机制

(1)每修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好

(2)每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失

(3)不同no:从不同步

配置项刷盘时机优点缺点
always同步刷盘可靠性高,几乎不丢失数据性能影响大
everysec每秒刷盘性能适中最多丢失1s数据
no操作系统控制性能最好可靠性较差,可能丢失大量数据

3.RDB和AOF的对比

在实际开发中,往往会结合二者使用

目录RDBAOF
持久化方式定时对整个内存做快照记录每一次执行的命令
数据完整性不完整,两次备份之间会丢失性相对完整,取决于刷盘策略
文件大小会有压缩,文件体积小记录命令,文件体积很大
宕机恢复速度很快
数据恢复优先级低,因为数据完整性不如AOF
系统资源占用高,大量cpu消耗和内存消耗低,主要是磁盘IO资源但AOF重写时会占用大量CPU和内存资源
使用场景可以容忍数分钟的数据丢失,追求更快的启动速度对数据安全性要求较高

三、Redis的数据删除策略

1.惰性删除

惰性删除:设置该key的过期后,我们不去管它,当下次需要该key时,我们检查其是否过期,如果过期,我们就删除该key,反之则返回key

  • 优点: 对CPU友好
  • 缺点:对内存不友好,可能会有大量的过期key存在于内存中

2.定期删除

定期删除:每隔一段时间,我们就对一些key进行检查,过期就删除
定期删除有两种模式: SLOW 和 FAST
SLOW:SLOW模式是定时任务,执行频率默认为10HZ(每秒执行10次),每次不超过25ms,可以通过修改配置文件redis.conf的hz选项来调整次数
FAST:FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

优点:可以通过限制执行删除操作的时常和频率来减少CPU的消耗,同时定期删除也能释放内存
缺点:难以确定执行操作的时常和频率

四、Redis的淘汰策略

我们设置完redis内存之后,我们就像里面放数据,但是内存总有满的时候,满的时候redis又是怎么处理的呢?

每进行一次redis操作的时候,redis都会检测可用内存,判断是否要进行内存淘汰,当超过可用内存的时候,redids 就会使用对应淘汰策略。

redis内存淘汰策略,具体如下:

  1. no-envicition:该策略对于写请求不再提供服务,会直接返回错误,当然排除del等特殊操作,redis默认是no-envicition策略。

  2. allkeys-random: 从redis中随机选取key进行淘汰

  3. allkeys-lru: 使用LRU(Least Recently Used,最近最少使用)算法,从redis中选取使用最少的key进行淘汰

  4. volatile-random: 从redis中设置过过期时间的key,进行随机淘汰

  5. volatile-ttl: 从redis中选取即将过期的key,进行淘汰

  6. volatile-lru: 使用LRU(Least Recently Used,最近最少使用)算法,从redis中设置过过期时间的key中,选取最少使用的进行淘汰

  7. volatile-lfu: 使用LFU(Least Frequently Used,最不经常使用),从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉

  8. allkeys-lfu: 使用LFU(Least Frequently Used,最不经常使用),从所有的键中选择某段时间之内使用频次最少的键值对清除


那么有这么多的淘汰策略,我们应该选取哪一种呢?

  • 优先使用allkeys-lru策略。充分利用LRU算法的优势。 将最常访问的数据(热数据)留在缓存中
  • 如果业务中数据访问频率差别不大,没有明显的冷热数据之分,建议使用allkeys-random,随机进行淘汰
  • 如果业务有置顶的需求,可以使用volatile-lru策略,同时设置置顶数据不设置过期时间,这些数据就一直不会被删除,会淘汰其他设置了过期时间的数据
  • 如果业务中有短时高频访问的数据,则推荐使用allkeys-lfu或者volatile-lfu策略

http://www.kler.cn/news/356260.html

相关文章:

  • 云黑系统全解无后门 +搭建教程
  • 保研考研机试攻略:python笔记(1)
  • 初识git · 远程操作
  • DAY52WEB 攻防-XSS 跨站反射型存储型DOM 型标签闭合输入输出JS 代码解析
  • Python 独立成分分析(ICA) 详解与应用案例
  • 什么是ASC广告?Facebook ASC广告使用技巧
  • 量纲分析的巅峰之作:Taylor点源爆炸模型产生始末
  • 【软件】Ubuntu下QT的安装和使用
  • 深入剖析:.Net8 引入非root用户运行的新特性提升应用安全性
  • 【AI学习】Mamba学习(九):HiPPO LegS版本
  • 05.栈介绍+实现
  • NGINX 的 Event Loop
  • 3.3关节组件
  • setuptools封装自己python包
  • Linux与Windows文件共享:Samba的详细配置(Ubuntu)
  • Spring 和 javaEE的关系
  • 基于 UDP 协议的 socket 编程:实现 UDP 服务器
  • 概率 多维随机变量与分布
  • 枸杞常见病虫害识别数据集(猫脸码客 第220期)
  • 【Linux系列】set -euo pipefail 命令详解