• 聊聊缓存穿透、雪崩及解决方案


    在平常工作中,为了减少数据库的压力,往往我们会将频繁使用的数据查询后写入redis缓存,在下次请求时读取redis获取数据,今天就聊聊使用redis时
    可能会遇到的一些问题场景以及解决方案。
    一、缓存穿透
    1.定义
      缓存穿透,指的是当查询不到某一个key的value,程序从而直接进行查询数据库。由于缓存不命中,每次都查询持久层,若数据库量大或者高并发等因
    素直接造成的数据库由于压力大而奔溃。

    2.解决方案
      2.1.读取DB是在缓存未命中的时候进行的动作,不管什么原因,若DB返回的数据为null,都将查询结果进行缓存,且该缓存的过期时间尽可能的短。

    $redis = new Redis();
    $cache = $redis->get($cacheKey);
    if(empty($cache)){
        //伪代码,从数据库中获取数据。若DB返回为null,也将null值进行缓存
        $data = $conn->query($sql);
        $redis->set($cacheKey, $data, $expire);
    }

      2.2.使用布隆过滤器,布隆过滤器是一种空间效率极高的概率型算法和数据结构,主要用来判断一个元素是否在集合中存在。当一个查询请求过来时,
    先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃。
    二、缓存雪崩
    1.定义
      缓存雪崩,指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,
    缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

    2.解决方案
      2.1.从条件“数据大批量到过期时间”出发,在设置缓存的时候给各缓存设置随机过期时间,不让大量key的过期时间一致。
      2.2.导致大量数据直接查库的另一种原因是redis挂掉,为了尽量避免redis挂掉,应该实现Redis的高可用(主从架构+哨兵 或者集群),同时设置本
    地缓存以及请求限流,尽量避免大流量直接请求数据库造成数据库压力剧增挂掉,进行redis持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据。

     
    慢慢来才是最快的
  • 相关阅读:
    JavaIO流(四) File文件对象
    Java IO流(三) 字符流Reader和Writer
    Java IO流(二) 字节流InputStream和OutputStream
    Java IO流(一)入门
    Decorator(装饰者)模式
    Listener(监听器)
    Filter(过滤器)
    Java开发入门
    啊哈哈,写博客的第一天
    MySQL变量
  • 原文地址:https://www.cnblogs.com/jongty/p/14076467.html
Copyright © 2020-2023  润新知