2021-04-20

中间件之缓存

  1. 缓存简介
  2. 缓存分类
  3. 缓存应用
  4. 缓存问题
  5. 缓存深入理解
  6. 总结

缓存简介

本章节我们的目的是弄清楚三个问题,什么是缓存,缓存用来干什么,缓存内部的算法和原理,首先提出几个我们日常开发中遇到的问题和现象

  1. 当我们从数据库读取大量数据java的集合无法承载,即使能也是对系统计算,和对内存的浪费,我们都知道在jvm中对于超大对象是直接进入老年代,yuangGC是无法回收年轻代的对象的,考虑到能提高计算能力,减少数据库开销,此时把数据放入缓存是非常必要的,
  2. 对于秒杀,抢购等高并发等场景,一方面由于对数据实时性要求比较高,另外为了可以扛着比较大的流量,此时提前把热点数据提前预热到缓存中,可以有效应对高并发,当然处理高并发和高可用不只是缓存设计,这涉及到整个系统层面的架构,但是缓存设计是其中重要组成部分,本章主要分析,深入了解缓存技术。
    从上面的问题我们大致了解一下缓存是什么,当然上面只是简单介绍两个例子,所以我们大致能了解到 缓存其实一个中间组件,用来承接上层和下层之间的缓冲作用,其实系统设计中常用的到一种方法,如果两层之间不能解决实际问题的时候,我们通常通过增加一层或几层,用空间换取时间,对层与层之间进行拆分。

缓存分类

  1. 本地缓存
  2. 分布式缓存
  3. session,cookie
  4. CDN 静态资源存储技术

本地缓存主要有guava, caffeine分布式缓存有 redis,memcache,mongdb,session 主要用来存储服务端用户信息,cookie 用来存储客户端用户信息。 CDN是指 静态资源存储,主要用到nginx ,squid,varnish实现web静态资源缓存。

缓存之redis

在这里插入图片描述

  1. 缓存雪崩
    所有key同一时间过期,所有请求打到数据库中,造成数据库宕机
    解决方法,
    1,设置可以不同的过期时间,如在过期时间加一个随机数。

  2. 缓存击穿
    大量请求 请求同一个key ,热点key承受高并发,高负载 而失效造成请求打到数据库,造成数据库宕机,
    解决办法:
    1:热点数据永不过期。
    2:接口限流,熔断,降级
    3. 互斥锁
    4. 布隆过滤器

  3. 缓存穿透
    请求key ,key 在缓存中不存在,请求数据库也存在的现象
    解决方法

    1. 布隆过滤器
  4. 缓存持久化
    AOF 记录操作的二进制文件,存储的数据比较全,用于全面备份恢复缓存数据,缺点是速度比较慢,
    不会丢失数据
    RDB 操作日志的快照文件,记录的数据没有AOF全,用于快速恢复数据,速度比较快,但是可能存在数据丢失的情况,通常是结合这两种持久化方式使用。

  5. 缓存淘汰策略
    淘汰策略主要从以下几个方面去考虑, 随机,过期时间,频率
    5.1. noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键

    5.2. allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键

    5.3. volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键

    5.4. allkeys-random:加入键的时候如果过限,从所有key随机删除

    5.5. volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐

    5.6. volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键

    5.7. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键

    5.8. allkeys-lfu:从所有键中驱逐使用频率最少的键

  6. 主从复制,sentinal, 集群
    主从复制 可以分为 :同步复制 ,异步复制,全部同步,部分同步。
    主从复制 支持一主多从,从服务器每隔一秒报告自己复制流状态,当从服务器初次同步,或者建立新的从从服务器,从服务器会发送一个sync命令给主服务器,主服务器收到命令执行BGSAVE 操作 把数据存储在.rdb快照文件中,如果此时主服务器还有中间操作,此时主服务器会把中间操作数据存储在一个缓冲区,当主服务器把.rdb 文件同步给从服务器之后在把缓存区的数据也同步给从服务器。即使多个从服务器会发送多个sync 命令但是主服务器只会执行一次bgsave操作,另外主服务器正在同步数据也不会阻塞主服务器其他写操作。除非是缓存更新的情况可能会阻塞其他操作。
    sentinal (哨兵机制): 主要用到raft 算法,此算法主要用来选举leader,
    sentinal 用于管理多台redis服务器,本身也是分布式的,主要有三个方面的任务,监控,提醒,自动故障迁移。
    主观下线,客观下线。分布式架构中可以启动多个sentinel 进程,当只要有一个sentinel进程 捕获到lead 下线,此时进入主观下线状态,当只有超过半数的sentinel 都任务lead 下线之后,lead进入客观下线,进入自动故障迁移,首先通过raft 算法选举出 leader sentinel , 此算法首先淘汰 ping 超过五秒的从服务器,淘汰客观下线之后设定十倍的从服务器,再根据偏移量,和最少运行ID,保障只会 选举出一个leader
    根据当前纪元自增之后,在当前纪元中选择出主服务器,通过 发布订阅模式把当前sentinel 配置跟其他sentinel 进行同步,同时从服务器也重新主服务器为刚当选的服务器,最后leader sentinel 终止这次自动故障迁移操作。

  7. 分布式锁
    原则:可重入的,阻塞的,高效的获取锁,释放锁,
    分布式锁是分布式系统中,保障数据一致性和同步操作的重要一环,通常有三种方式实现分布式锁,
    1,利用数据库表锁机制,行锁,表锁,新建一张操作表进来记录操作数据记录,当开始操作是在此表插入一条新的数据,完成操作是删除这条记录,
    缺点,对并发不友好,增加数据库额外开销,实现繁琐复杂,单点故障,不可重入,非阻塞的,
    2:redis:利用redis setnx 的原子性操作,同时设置key 过期时间去释放锁。
    3: zookeeper :创建临时节点,可保证最小的序号能在该持久节点下创建临时节点,同时保证当前线程获得锁,完成操作后只要删除 临时节点即可释放锁。
    三种方案的比较
    从理解的难易程度角度(从低到高)
    数据库 > 缓存 > Zookeeper
    从实现的复杂性角度(从低到高)
    Zookeeper >= 缓存 > 数据库
    从性能角度(从高到低)
    缓存 > Zookeeper >= 数据库
    从可靠性角度(从高到低)
    Zookeeper > 缓存 > 数据库

缓存更新

主动更新缓存 ,三种,删除缓存再更新数据库,更新数据库再删除缓存再更新缓存,更新数据库更新缓存,需要考虑的中间过程是,如果删除缓存失败,或者数据库更新失败,或者更新缓存失败 同事考虑并发问题,会出现数据不一致的情况。此上三种情况在一定条件下都会出现数据不一致的情况,所以在分布式缓存中我们一般会设置,主服务器负责写,从服务器负责读,同时设置key合理的过期时间,当发生写比读数据快的情况的时候是可能发生数据不一致的。我们通常在日常中会选择 先更新数据库,然后删除缓存,然后再更新缓存这种模式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值