Redis 小记

为啥使用Redis

 大量读写请求同时到来,导致频繁进行磁盘I/O,导致性能下降,体验很差,为了解决此问题,redis诞生了,就像CPU一样,这里给数据库相当于加了一个缓存。应用程序从数据库查询到的数据后,在redis这里记录一下,后面再需要用到的时候,就先查询redis,redis没有再去查询数据库。

缓存过期

场景

redis缓存的数据在内存中,内存是有限的,无限制写入迟早导致内存占满

解决方案

给缓存内容设置一个超时时间,具体设置多长交给应用程序们去设置,过期了的内容会被redis删除掉。

删除策略

1.定期删除,例如100ms一次,1s就是10次,由于缓存了大量数据,全部扫描一遍,会导致耗时过长,所以一般随机选择一部分清理,缓解内存压力,

2.惰性删除,有可能一些键运气好,每次都没有被随机算法选中,导致一直霸占内存空间,所以一旦遇到查询,发现该键过期,立马删除。这种方式是被动的,不查询不会发生,所以叫惰性删除。

缓存淘汰

场景

一些键已经过期,但是从未被查询,又或者设置的过期时间很长,还没清理,内存就占满了

解决方案

提供了8种策略,在内存不足时采用:

* noeviction:返回错误,不会删除任何键值

* allkeys-lru:使用LRU算法删除最近最少使用的键值

* volatile-lru:使用LRU算法从设置了过期时间的键集合中删除最近最少使用的键值

* allkeys-random:从所有key随机删除

* volatile-random:从设置了过期时间的键的集合中随机删除

* volatile-ttl:从设置了过期时间的键中删除剩余时间最短的键

* volatile-lfu:从配置了过期时间的键中删除使用频率最少的键

* allkeys-lfu:从所有键中删除使用频率最少的键
 

缓存穿透

场景

缓存穿透是指缓存和数据库中都没有的数据,用户(黑客)不断发起请求,导致请求直接查询数据库

解决方案

  • 在请求接口层可以做一些校验,比如用户签权、参数校验,不合法的请求直接return,

  • 还可以针对有效id做认证或直接拦截,不符合的id直接过滤或采用统一key保存到redis,下次不合法的id请求时,直接到缓存中获取数据

  • 采用redis的高级接口Bloom Filter(布隆过滤器),利用高效的数据结构和算法快速判断出你这个 Key 是否在数据库中存在,不存在你 return 就好了,存在你就去查 DB 刷新 KV 再 return

缓存击穿

场景

某个key非常热点,请求非常频繁,处于集中式访问现象,当这个key失效(过期)时,大量的请求就会击穿了缓存,直接请求数据库,就像在屏障中凿开了一个洞

解决方案

  • 数据基本不变:热点数据value基本不更新时,可以设置成永不过期

  • 数据更新不频繁:缓存刷新流程耗时较少时,可采用redis、zookeeper等分布式中间件的分布式互斥锁或者本地互斥锁保证少量的请求能请求到数据库并重新更新缓存,其他的流程等锁释放后才可以访问新缓存

  • 数据更新频繁:采用定时线程,在缓存过期前主动重新构建缓存或延长过期时间,保证所有的请求能一直访问缓存

缓存雪崩

场景

  • 大量Redis缓存数据同时过期,导致所有的发送到Redis请求都无法命中数据,只能到数据库中进行查询。

  • Redis服务器宕机,所有请求都无法经Redis来处理,只能转向数据库查询数据。

解决方案

针对大量缓存随机过期时间,解决方法就是在原始过期时间的基础上,再加一个随机过期时间,比如1到5分钟之间的随机过期时间,这样可以避免大量的缓存数据在同一时间过期。

而针对Redis解决宕机的导致的缓存雪崩,可以提前搭建好Redis的主从服务器进行数据同步,并配置哨兵机制,这样在Redis服务器因为宕机而无法提供服务时,可以由哨兵将Redis从服务器设置为主服务器,继续提供服务。再就是做redis持久化,一旦Redis重启,可从磁盘中快速恢复数据。

数据一致性

如何保持redis和数据库的数据性

场景

1.先更新数据库,再跟新缓存(并发读请求)

 2.先更新缓存,再更新数据库(并发读请求)

 3.先删除缓存,再更新数据库(并发读写请求)

 4. 先更新数据库,再删除缓存(并发读写请求)

解决方案

1.延时双删,适用于先删除缓存,再更新数据库

2.重试机制,适用于先更新数据库,再删除缓存

3.订阅binlog,再操作缓存,适用于先更新数据库,再删除缓存

数据持久化

场景

redis是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。

解决方案

RDB模式

原理

在指定的时间间隔内将内存中的数据库快照写入磁盘,再次恢复时再将快照文件直接读到内存里。

在此期间,redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何io操作的。

这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。但RDB存在缺陷是最后一次持久化的数据可能丢失。当我们安装好的redis,其默认持久化模式是RDB模式【一般情况下不需要修改】,RDB保存的文件是dump.rdb。都是在redis配置文件中快照中进行配置的。

RDB是默认方式,不需要进行配置,默认就使用这种机制,在一定的间隔时间中,检测key的变化情况,然后持久化数据。

触发机制

三种情况下会触发RDB规则

1.sava的规则满足的情况下,会自动触发rdb规则
2.执行fushall命令,也会触发我们的rdb规则
3.退出redis,也会产生rdb文件

恢复机制

只需要将rdb文件放在redis启动目录下即可,redis启动的时候回自动检测dump.rdb,恢复数据

优缺点

RDB模式的优势是适合大规模的数据恢复、且对数据的完整性不高。但与之相对,不足之处是需要一定的时间间隔进程操作,如果redis意外宕机,这个最后一次修改数据就没有了,且fork进程的时候,会占用一定的内存空间

AOF模式

原理

【append only file】将开发者操作redis的所有命令都记录下来,恢复的时候就把文件内所有写的操作执行一遍。

它以日志的形式来记录每个写操作,将redis执行过的所有指令记录下来(读操作不记录),且只许追加文件但不可以改写文件。当redis启动之初会读取该文件重新构建数据。换句话说,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

aof模式保存的文件名是appendonly.aof。在redis配置中,默认是不开启的,开发者需要手动配置,只需要将appendonly改为yes即可开启、再进行重启redis,就可以生效了。

如果aof文件有错位,这时候redis是启动不起来的,开发者需要修复aof文件,redis为开发者提供了一个工具,也就是bin目录下的redis-check-aof,开发者只需在redis bin目录下执行redis-check-aof --fix appendonly.aof即可
如果文件正常了,重启后就可以直接恢复了。

简单理解aof是日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据

重写规则

aof默认就是文件的无限追加,文件会越来越大,如果aof文件大于64m,redis会fork一个新的进程来将文件进行重写

优缺点

AOF模式的优势是每一次修改都同步时,文件的完整性会更好;每秒同步一次方式时,可能会丢失1s的数据;从不同步时,效率最高。
相对于数据文件来说,AOF文件远远大于RDB;修复的速度也比RDB慢;AOF运行效率要比RDB慢,所以redis默认的配置就是RDB持久配置

参考文档:(7条消息) redis详解(全)_Ferao的博客-CSDN博客_redis

(7条消息) 什么是redis_dameng_cc的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

破浪征程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值