临桂建设局安全股网站,远程医疗型网站开发,劳务工程信息平台,“网站制作”Redis相关概念#xff1a;缓存击穿、雪崩、穿透、预热、降级、一致性等
Redis缓存雪崩、缓存击穿、缓存预热热点key、缓存降级、短链接、分布式锁秒杀、预减库存、
堆外缓存Redis架构设计、Redis动态刷新、Redis和DB双写一致性、过期删除策略、集群数据倾斜等一、缓存雪崩 缓…Redis相关概念缓存击穿、雪崩、穿透、预热、降级、一致性等
Redis缓存雪崩、缓存击穿、缓存预热热点key、缓存降级、短链接、分布式锁秒杀、预减库存、
堆外缓存Redis架构设计、Redis动态刷新、Redis和DB双写一致性、过期删除策略、集群数据倾斜等一、缓存雪崩 缓存雪崩是指当缓存中的大量数据在同一时间失效导致大量请求直接访问数据库从而引起数据库的压力过大
严重影响系统的性能。redis 主机挂了 Redis全盘崩溃偏硬件运维redis 中有大量key 同时过期大面积失效偏软件开发1、缓存数据的随机过期时间
在缓存数据的过期时间上增加随机因素从而避免大量数据在同一时间失效的情况//将数据缓存到Redis中并增加随机的过期时间//int random new Random().nextInt(600) 600;2、预热缓存
在系统启动时预热缓存将系统中的热点数据提前加载到缓存中从而避免了大量请求同时访问数据库的情况。
Component
public class AdmdvsDimCacheManager implements InitializingBean {Overridepublic void afterPropertiesSet() {//预热处理}}3、分布式锁
使用分布式锁从而避免大量请求同时访问数据库的情况。
public ListUser getUserList() {ListUser userList redisTemplate.opsForValue().get(userList);if (userList null) {// 如果Redis中不存在则尝试获取分布式锁RLock lock redissonClient.getLock(userListLock);try {// 尝试加锁并设置锁的过期时间为5秒boolean success lock.tryLock(5, TimeUnit.SECONDS);if (success) {// 如果获取到了锁则查询数据库并将数据缓存到Redis中userList userDao.getUserList();if (userList ! null userList.size() 0) {redisTemplate.opsForValue().set(userList, userList, 1, TimeUnit.HOURS);}}} catch (InterruptedException e) {e.printStackTrace();} finally {// 释放锁lock.unlock}} return userList;
}二、缓存击穿 缓存击穿问题也叫热点Key问题就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了无 数的请求访问会在瞬间给数据库带来巨大的冲击。描述假设线程1在查询缓存之后本来应该去查询数据库然后把这个数据重新加载到缓存的 此时只要线程1走完这个逻辑其他线程就都能从缓存中加载这些数据了但
是假设在线程1没有走完的 时候后续的线程2线程3线程4同时过来访问当前这个方法 那么这些线程都不能从缓存中查询到 数据那么他们就会同一时刻来访问查询缓存
都没查到接着同一时间去访问数据库同时的去执行 数据库代码对数据库访问压力过大.1、互斥锁 如果未命中缓存先获取互斥锁获取锁之后要再次检查缓存如果还是未命中进行缓存重建这样当其他线程来的时候就会获取锁失败这时我们让这个线程休眠一会重新
查询缓存如果命中就返回嘛如果没命中再次尝试获取锁假设这次获取锁成功了还是再次检查缓存如果未命中重建缓存。描述假设现在线程1过来访问他查询缓存没有命中但是此时他获得到了锁的资源那么线程1就会一个人 去执行逻辑假设现在线程2过来线程2在执行过程中并没有
获得到锁那么线程2就可以进行到休 眠直到线程1把锁释放后线程2获得到锁然后再来执行逻辑此时就能够从缓存中拿到数据了。优点可保证数据高一致性缺点性能低可能发生死锁2、逻辑过期 我们把过期时间设置在 redis的value中注意这个过期时间并不会直接作用于redis而是我们后续 通过逻辑去处理。假设线程1去查询缓存然后从value中判断出来当
前的数据已经过期了此时线程1 去获得互斥锁那么其他线程会进行阻塞获得了锁的线程他会开启一个 线程去进行 以前的重构数据 的逻辑直到新开的线程完成这个逻辑
后才释放锁 而线程1直接进行返回假设现在线程3过来访 问由于线程线程2持有着锁所以线程3无法获得锁线程3也直接返回数据只有等到新开的线程2把 重建数据构
建完后其他线程才能走返回正确的数据。优点性能高缺点数据可能不一致实现复杂三、缓存穿透 缓存穿透是指查询一个不存在的数据由于缓存中没有数据请求会直接穿透到数据库中从而引起数据库的压力过大严重影响系统的性能。1、布隆过滤器 布隆过滤器是一种高效的数据结构可以判断一个元素是否存在于一个集合中同时也可以减轻数据库的压力。在使用布隆过滤器的时候首先将所有的数据hash到一个位图
中如果查询的数据在位图中不存在那么直接返回不存在从而避免了对数据库的查询操作。优点内存占用较少没有多余key缺点实现复杂存在误判可能2、空对象存储 采用空对象缓存的方式即当查询的数据不存在时将一个空对象缓存到Redis中。这样下次查询同样不存在的数据时就可以直接从Redis中获取到一个空对象从而避免了
对数据库的查询操作。优点实现简单方便维护缺点占内存可能造成短期数据不一致四、缓存预热热点KEY 缓存预热是指在系统启动或者高峰期之前提前将数据加载到缓存中避免在用户请求的时候先查询数据库这样第一个查询的人就会比较慢再把查询结果回写到redis
当中去。通过LRU数据删除策略可以得到高频数据队列。通过脚本的方式将热点数据提前加入。处理方案1、配置一个job定时刷新数据缓存。2、直接写个缓存刷新页面上线后手动刷新。3、项目启动的时候直接将热点KEY缓存到redis五、缓存降级 当站点的访问量剧增、服务出现卡顿问题或非关键服务影响到关键流程的性能时仍然需要保证服务还是可用的即使是有损服务。系统可以根据一些关键数据进行自动降级
放弃一些不重要的加载项也可以配置开关实现人工降级。降级的最终目的是保证关键核心服务的正常运行比如涉及财务的网站购物的购物车结算等重要模块是不能降级的。六、缓存一致性
缓存一致性指的是缓存与DB之间的数据一致性我们需要通过各种手段来防止缓存与DB不一致我们要保证缓存与DB的数据一致或者数据最终一致。处理方案1.数据库层在数据库层面可以使用事务来确保数据的一致性。通过将读写操作放在同一个事务中可以保证数据的更新和查询是一致的。
使用数据库的触发器或者存储过程在数据更新的同时主动触发缓存的更新操作确保缓存与数据库的数据保持一致。2.缓存层在缓存层面可以使用缓存更新策略通过定时任务、异步消息队列等方式定期或者在数据更新时异步地更新缓存保持缓存与数据库的数据一致性。
使用互斥锁或者分布式锁来保证对缓存的读写操作的原子性避免数据冲突。
设置合适的缓存过期时间避免缓存数据长时间过期而导致数据不一致的问题。3.应用层在应用层面可以采用读写分离策略将读请求和写请求分发到不同的节点读请求直接从缓存中获取数据写请求则更新数据库并更新缓存保持数据的一致性。
使用缓存中间件或者缓存组件提供自动更新缓存的功能减少手动维护缓存的复杂性。4.监控和报警建立监控和报警机制通过监控缓存层和数据库层的状态、数据一致性等指标及时发现异常情况并触发报警以便及时处理问题。