• Redis常见问题


    一.Redis的持久化方式?

    RDB:定时对数据内存做快照存储
    AOF:记录执行的命令
    默认开启RDB,AOF需手动设置开启使用;实际的应用中,采取RDB+AOF结合使用

    二者区别

    RDB AOF
    数据完整性 低(两次备份有丢失数据的风险)
    宕机恢复速度 快(数据) 慢(记录的命令)
    数据优先级 低(数据完整性低于AOF)
    文件大小 小(文件可以压缩,并且记录值)
    内存占用 大量CPU和内存消耗 AOF主要占用磁盘IO资源,在重写时,会占用CPU和内存消耗
    应用场景 追求更快的启动速度使用RDB 追求数据的安全性

    触发条件

    RDB触发机制有三种,分别是:save触发、bgsave触发和自动触发

    1. bgsave触发
      具体流程是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。bgsave命令也是Redis内部RDB操作的默认方式。
      image
    2. 自动触发
      配置:save second changes
      作用:满足限定时间范围内key的变化数量达到指定数量即进行持久化
      参数:second:监控时间范围,changes:监控key的变化量
      位置:在conf文件中进行配置
      范例:
      image
      配置的含义:
      900秒之内至少一次写操作、300秒之内至少发生10次写操作、60秒之内发生至少10000次写操作;只要满足任一条件,均会触发bgsave

    AOF触发的条件有三种可以设置
    image

    二.Redis为什么这么快?

    1. 单线程,避免了多线程的频繁切换开销
    2. 内存操作
    3. IO多路复用
    4. 跳跃表

    三.Redis的过期删除策略和内存淘汰机制

    1.过期删除策略

    定时: redis中存入一个带有过期时间的key时,会为这个key生成一个专属的定时器,用来监视这个key的过期时间,当过期时间达到后,立即进行删除;优点是redis中的数据可以保持为最新的数据,但缺点是每个带有过期时间的key都会分配一个定时器,对CPU和内存占用消耗是很大的;
    定期: redis每隔100ms会抽取一部分key检验其过期时间,达到后将其删除;但是可能有些过期了的key始终抽取不到,导致内存占用问题,于是定期删除策略都和惰性删除策略结合使用;
    惰性: 当使用到某个key是,redis会先检验key的过期时间,时间达到进行删除,弊端是某个不经常使用的key清楚不掉,占用内存;
    在使用redis的过期删除策略时,采取的是定期+惰性,还会使用redis的内存淘汰机制!

    2.内存淘汰机制

    1. novecation:当内存不足以容纳新数据时,抛出异常;
    2. allkeys-lru:当内存不足以容纳新数据时,使用lru算法,从所有的key中找出最不常使用的key进行删除;
    3. allkeys-random :当内存不足以容纳新数据时,随机抽取某个key进行删除;
    4. volatile-lru:当内存不足以容纳新数据时,使用lru算法,从已设置过期时间的key中,找出最近不常使用的key进行删除;
    5. volatile-random:当内存不足以容纳新数据时,从已设置过期时间的key中,随机抽取某个key进行删除;
    6. volatile-ttl:删除到期时间最早的key;

    四.Redis的五种数据类型

    List、String、Set、ZSet、Hash
    详细命令可参考redis中文网:https://www.redis.net.cn/

    五.雪崩、击穿、穿透

    1.雪崩

    如果在某一时刻缓存集中失效,或者缓存系统出现故障,所有的并发流量就会直接到达数据库。数据存储层的调用量就会暴增,用不了多长时间,数据库就会被大流量压垮,这种级联式的服务故障,就叫作缓存雪崩。
    image

    解决方案

    1. 解决缓存雪崩问题最常用的一种方案就是保证Redis的高可用,将Redis缓存部署成高可用集群(必要时候做成异地多活),可以有效的防止缓存雪崩问题的发生。
    2. 为了缓解大并发流量,我们也可以使用限流降级的方式防止缓存雪崩。例如,在缓存失效后,通过加锁或者使用队列来控制读数据库写缓存的线程数量。具体点就是设置某些Key只允许一个线程查询数据和写缓存,其他线程等待。则能够有效的缓解大并发流量对数据库打来的巨大冲击。
    3. 另外,我们也可以通过数据预热的方式将可能大量访问的数据加载到缓存,在即将发生大并发访问的时候,提前手动触发加载不同的数据到缓存中,并为数据设置不同的过期时间,让缓存失效的时间点尽量均匀,不至于在同一时刻全部失效。

    2.击穿

    缓存中的数据在某个时刻批量过期,导致大部分用户的请求都会直接落在数据库上,这种现象就叫作缓存击穿。
    image

    解决方案

    1. 对于比较热点的数据,我们可以在缓存中设置这些数据永不过期;也可以在访问数据的时候,在缓存中更新这些数据的过期时间;如果是批量入库的缓存项,我们可以为这些缓存项分配比较合理的过期时间,避免同一时刻失效。
    2. 还有一种解决方案就是:使用分布式锁,保证对于每个Key同时只有一个线程去查询后端的服务,某个线程在查询后端服务的同时,其他线程没有获得分布式锁的权限,需要进行等待。不过在高并发场景下,这种解决方案对于分布式锁的访问压力比较大。

    3.穿透

    在查询某个Key对应的数据时,Redis缓存中没有相应的数据,则直接到数据库中查询。数据库中也不存在要查询的数据,则数据库会返回空,而Redis也不会缓存这个空结果。导致查询每次都会请求到数据库;
    image

    解决方案

    1. 当进行查询时,发现key不存在,则为其设置个空值并设置合理的过期时间,减少数据库的压力
    2. 布隆过滤器:设置布隆过滤器,相当于redis的网关,会对redis的key进行三次hash计算,得到的结果都为1的话证明redis中存在对应的key,才会进入redis中,key有值返回数据,无值访问数据库,得到结果再存储到redis中;

    __EOF__

  • 本文作者: weiboyaonuli
  • 本文链接: https://www.cnblogs.com/weiboyaonuli/p/redis.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    虚拟现实环境下的远程教育和智能评估系统(五)
    国家级专新特精“小巨人”「皖仪科技」携手企企通,打造采购数字化平台成功上线
    Go语言hash/fnv应用实战:技巧、示例与最佳实践
    动态规划合集
    随时记录解决
    C - Matrix Reducing
    使用Python抢购商品
    经典算法——直接插入排序
    arm64 aarch64 rust 在线安装过程
    【windows】新手小白准备python环境
  • 原文地址:https://www.cnblogs.com/weiboyaonuli/p/redis.html