redis分布式知识点概念

  1. 缓存穿透

    • 什么是缓存穿透?

      客户端大量集中恶意访问一些不存在的数据,例如访问id=-1的数据,这样在缓存层就无法查询到该数据,直接击穿缓冲层,到达数据库端,导致数据库压力过大,最终停止服务。

    • 解决方案

      在代码层面做判断限制非法数据的请求;

      使用布隆过滤器,记录key是否存在,不存在则直接返回,使请求不达到数据层面;

  2. 缓存击穿

    • 什么是缓存击穿?

      缓存击穿是指因并发原因,大量数据请求同一个key值,而该key值刚好过期,导致所有请求都去数据库层面获取数据,最终导致数据库停止服务。

    • 解决方案

      在代码层面使用并发锁,如果某个key无法获取,则先获取锁,再去数据库层获取数据,回写到缓存层,其他并发请求,如果没有获取到锁,则等待一段时间后再尝试去缓存层获取数据;

      将数据设置为一个合理的过期时间,例如永不过期,或并发量低时过期;

  3. 缓存雪崩

    • 什么是缓存雪崩?

      缓存雪崩是指,大量缓存数据集中过期,导致数据库层的压力过大。与缓存击穿的区别是,缓存击穿是单个key值的过期,同时大量并发请求,而缓存雪崩是大量key值集中过期,同时访问量较大。

    • 解决方案

      合理设置过期时间,避免同一时刻缓存数据过期;

      使用数据库分布式部署,降低单节点数据库读压力过大;

      合理选择热点数据,并设置为永不过期;

  4. 如何保证无锁的原子操作

    • 将多个操作在Redis中实现成一个操作,例如读取数据、数据增减、写回数据,使用INCRE/DECRE命令操作;

    • 将多个操作写在一个Lua脚本中,Redis回将Lua脚本当作一个整体执行,不会被其他命令打断。Lua脚本进来些成复用度高的脚本,并通过Script load命令先把脚本在Redis中加载,避免每次都要将脚本从客户端发送到服务端,减少网络IO的开销;

  5. 分布式锁

      使用redis实现分布式锁,需要把获取锁,设置过期时间作为一个原子操作执行,可使用上面介绍的Lua脚本执行,释放锁应只能由获取锁的客户端才能释放,避免别的客户端释放锁。多节点高可用分布式锁采用redlock算法实现分布式锁,java的Redisson就是基于redlock实现的分布式锁。redlock算法流程是

    a. 客户端获取当前时间;

    b. 客户端顺序依次向N个redis实例执行加锁操作;

    c. 判断加锁是否成功,需要满足俩个条件,1是客户端超过半数的redis实例上成功加锁,2是客户端获取锁的总耗时没有超过锁的有效时间;

      基于redis实现的分布式锁不是完全可靠的,可能出现死锁获取多个客户端同时获取锁的情况,例如以下情景:

    1、SETNX 执行成功,执行 EXPIRE 时由于网络问题设置过期失败

    2、SETNX 执行成功,此时 Redis 实例宕机,EXPIRE 没有机会执行

    3、SETNX 执行成功,客户端异常崩溃,EXPIRE 没有机会执行

      在这个场景中,由于没有设置过期时间,那么如果客户端崩溃,没有释放锁,其他客户端就无法再获取到锁。分布式锁的实现方案对比如下:

    方案优点缺点适用场景
    基于数据库锁的方式 简单,方便,可靠性高 性能低,并发程度低 小并发量的场景
    基于单节点redis实现 性能最优,有比较成熟的客户端框架及方案实现,例如jedis 1. 可靠性不太高,会出现死锁的情况;2. 无法实现公平锁;3. 需客户端轮询获取锁,成本大 高并发,允许部分锁异常的场景
    基于多节点的redis实现 解决了redis单节点失效导致不可用的情况 脑裂、客户端阻塞等一场都可能导致锁的异常问题,可靠性不太高 高并发,高可用,允许部分锁异常的场景
    基于etcd 1.性能较好,支持并发度高;2.能实现公平锁;3.通过回调通知客户端获取锁,不需要轮询;4.可靠性高,基于raft分布式算法实现 没有现成的集成框架,需要自研 高并发、高可用场景
    基于zookeeper实现 1能实现公平锁;2.通过回调通知客户端获取锁,不需要轮询;3.可靠性高 性能较etcd和redis较低 并发量不太大,锁的可靠性要求高
  6. 缓存策略

    •   旁路策略
      •   场景:适合读多写少
      •   说明:

            读场景 :直接从缓存读取,如果没有,则读取数据库数据,并更新缓存;

            写场景:先写数据库,再删除缓存,等待下一次读时从数据库读数据并写入缓存;

        该策略在写场景下,如果大并发读写,会造成数据的不一致,理论上概率比较小。可以使用双删的策略,即在完成写操作并删除缓存后,使用一个延时操作再删一次缓存。

    •   读写穿透
      •   场景:写操作比较多的场景
      •   说明:此策略以缓存作为主要的数据存储介质,应用直接与缓存交互,由缓存直接维护数据库的值。该策略较少缓存支持。
    •   异步写入
      •   场景:写操作频繁,对数据一致性要求不高,例如点赞、评论的场景
      •   说明:直接写入缓存,然后通过消息队列或文本存储数据,批量将操作写会数据库中,也可能会对操作进行压缩,比如点赞数量的更新

posted @ 2020-12-01 13:26  少羽大怪兽  阅读(99)  评论(0编辑  收藏  举报