美文网首页
Redis相关(缓存雪崩,缓存穿透,缓存击穿)

Redis相关(缓存雪崩,缓存穿透,缓存击穿)

作者: Rain_z | 来源:发表于2020-09-17 16:59 被阅读0次

redis有哪些数据结构

String,hash,list,set,sortedSet,另外还有几个特殊结构HyperLogLog、Geo、bitmap

持久化

redi提供了RDB和AOF两种持久化方式,RDB就是讲将内存中的数据集以快照的形式写入磁盘,使用二进制压缩存储,保存在单一文件中,适合做灾备,缺点就是在保存快照完成之前宕机,那么这段时间的数据就丢失了;AOF是以文本记录的方式 记录redis处理的每一个写入和删除的操作

Redis 和 Memcached 有啥区别

  1. 数据结构上redis有更多的数据结构
  2. redis可以的缓存设置失效失效时间,expire name 10;
    memcache设置缓存不会监测是否过期,只会在get的时候检查记录时间戳,判断是否过期,过期的数据不会被删除,只是在分配空间时会优先使用过期的键值对空间,然后当分配的内存满了以后,会调用LUR算法分配空间,删除最近很少用的key/value键值对,不管是否过期。
    3.memcache挂掉以后,数据就没了,redis有持久化策略可以通过AOF恢复数据
  3. memcacha没有原生的的集群模式,只能依靠客户端实现,redis支持cluster模式
  4. memcache更适合数据量大的场景

使用redis实现分布式锁

原理:先拿setnx(set if not exists)争抢锁,抢到以后,再用expire设置过期时间钢制锁忘记了释放

如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?

set指令有非常复杂的参数,可以同时执行setnx和expire合成一个指令操作

redis是单线程的,为什么还这么快

1.redis是用C语言写的,更接近于系统

  1. 基于内存操作
  2. 数据接结构简单
    4.虽然是单线程,但也减少了多线程的切换消耗cpu,也没有加锁和释放锁的操作
  3. IO多路复用:有三个实现机制epoll,poll.selct,默认使用epoll;传统BIO操作(Blocking)都是按照顺序执行,但是读写操作等待用户输入或者输出的时候都是阻塞的,所以I/O操作一般情况下不能直接返回的,某一个文件的I/O阻塞导致整个进程无法对其他客户服务,IO多路复用就是解决这个问题,他可复用一个线程,监听多个io事件,找出能读出数据,或者写入数据的流,对他们进行操作,并且只依次顺序的处理就绪的流。
    在NIO中如果一个连接不能读写,我们可以把这件事记下来,记录方式是在Selector上注册标记位,然后切换到其他就绪的连接继续进行读写

缓存雪崩

目前很多电商首页以及热点数据会做缓存,一般缓存都是用定时任务去刷新,或者是查询不到更新,定时任务刷新会有一个问题,缓存同一时间大面积失效,这时候大量的请求进来直接达到数据库里,对于数据库来讲是灾难性的,会直接吧数据库搞挂掉。
解决方案:既然是同一时间大面积失效,那就在设置爱失效时间上加个随机值,保证数据不在同一时间失效

缓存穿透

就是指缓存和数据库里都没有的数据,而用户不断的发起请求,会导致大量的请求打到数据库给数据库造成很大的压力,严重会击垮数据库。(比如我们数据库表id都是从1自增上去的,我拿一个0或者-1不断请求你,这样每次都能绕开redis直接打到数据库)
解决方案:
1.增加校验,在接口层增加用户鉴权检验,参数校验,不合法的直接return,
2.设置这个key的value为null,这样直接从redis中取,不会在走到数据库
3.像正常用户不会再单秒内发起这么多的请求,这种恶意攻击的请求在nginx可以配置,单个IP每秒访问次数超过阈值的IP都拉黑
4.布隆过滤器:
布隆过滤器的核心就是一个bit数组和K个hash函数,数组的每个元素只能为0和1,key值经过k个hash函数对其进行k次hash计算的到hash值,在数组中把对应下标的数据改为1;判断是否存在过滤器中的时候,就对key进行k次hash计算,得到的值在bit数组中如果都为1,key就可能存在过滤器中,如果有一个为0,就可定不在过滤器中(存在误判的情况,比如有些位置别的元素先占了)

缓存击穿

和缓存雪崩有点像,但不是大面积的,指的是一个热点key 不停的扛着高并发,当这个key失效的时候,大量的请求直接请求到数据库,相当于在一个水桶上打了一个洞
解决方案:
1.设置永不过期

  1. 或者加上互斥锁ReentrantLock实现

Redis实现分布式锁

1.加锁,通过set key value NX PX 5000来设置
其中NX:键值不存在时才会设置
XX:键值存在时才会设置
EZ:设置失效时间为秒
PX:设置失效时间为毫秒
2.释放锁,通过lua脚本保证原子操作,
lua为什么是原子性操作:eval方法在执行lua脚本的时候他会把lua脚本当成一个命令执行,直到eval命令执行完成,才会进行其他的任务

相关文章

网友评论

      本文标题:Redis相关(缓存雪崩,缓存穿透,缓存击穿)

      本文链接:https://www.haomeiwen.com/subject/mvwbfktx.html