对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑另外一个问题:缓存被“击穿”的问题。
/** * 启用新的get方法,防止缓存被“击穿” * <p> * 击穿 :缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来, * 这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。 * 如何解决:业界比较常用的做法,是使用mutex。 * 简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成 * 功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行 * load db的操作并回设缓存;否则,就重试整个get缓存的方法。 * </p> * @param key * @param pjp * @param cache * @return * @throws Throwable */ private Object get(final String key, final ProceedingJoinPoint pjp, final Cacheable cache) throws Throwable { @SuppressWarnings("unchecked") ValueOperations<String, Object> valueOper = redisTemplate.opsForValue(); Object value = valueOper.get(key); // 从缓存获取数据 if (value == null) { // 代表缓存值过期 // 设置2min的超时,防止del操作失败的时候,下次缓存过期一直不能load db String keynx = key.concat(":nx"); if (CacheUtils.setnx(keynx, "1", ExpireTime.TWO_MIN)) { // 代表设置成功 value = pjp.proceed(); if (cache.expire().getTime() <= 0) { // 如果没有设置过期时间,则无限期缓存 valueOper.set(key, value); } else { // 否则设置缓存时间 valueOper.set(key, value, cache.expire().getTime(), TimeUnit.SECONDS); } CacheUtils.del(keynx); return value; } else { // 这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可 Thread.sleep(10); return get(key, pjp, cache); // 重试 } } else { return value; } }
相关推荐
**高并发缓存器(基于ehcache)** 在IT行业中,面对高并发场景时,缓存技术是提高系统性能和响应速度的关键手段。基于ehcache的缓存器是一种常见的解决方案,它能够在内存中存储常用数据,减少对数据库的访问,从而...
redis缓存雪崩,redis缓存穿透,redis缓存击穿 redis应对高并发造成的雪崩、穿透、击穿
缓存击穿是指在高并发的情况下,缓存中的某个热点数据失效或过期,导致大量请求直达数据库,导致数据库压力增大,甚至宕机。缓存击穿的原因主要是缓存热点数据的失效或过期。 解决方案: 1. 使用缓存热点数据的...
缓存穿透是指在高并发场景下,大量的请求访问了一个既不在缓存中也不在数据库中的数据。这种情况通常发生在非法用户尝试利用不存在的数据ID进行恶意访问时,或者是系统设计缺陷导致请求直接跳过缓存访问数据库。 **...
这个问题在高并发场景下尤为突出,因此理解和防范缓存击穿至关重要。 缓存击穿的原因通常有两种:一是缓存过期,二是缓存未命中。在大多数情况下,缓存系统会设置一个过期时间,当这个时间到达时,缓存的数据将不再...
缓存击穿是分布式系统中一个重要的问题,特别是在高并发、大数据量的场景下,它可能导致后端数据库不堪重负,影响服务的稳定性和性能。本文将深入探讨缓存击穿的概念、原因、影响以及应对策略。 缓存击穿是指在缓存...
缓存击穿是分布式系统中一个重要的问题,它发生在高并发场景下,当大量请求同时穿透缓存,直接访问后端存储系统,如数据库或文件系统,可能导致后端负载过高,甚至服务崩溃。理解并解决缓存击穿是保证系统稳定性和...
缓存击穿问题在IT行业中是一个重要的概念,尤其是在高并发、大数据量的系统设计中,理解和解决这个问题至关重要。缓存通常被用作减轻数据库压力、提高系统响应速度的关键技术。然而,当缓存失效时,如果处理不当,就...
缓存击穿对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一 ...
**缓存击穿**发生在缓存中的某条数据刚好过期,而数据库中存在该数据的情况下,大量并发请求同时绕过缓存直接访问数据库,可能导致数据库瞬间压力剧增。解决方法之一是设置热点数据永不过期,确保这些数据始终存在于...
Redis缓存穿透、缓存雪崩、缓存击穿的原因和解决方案 Redis缓存穿透、缓存雪崩、缓存击穿是 Redis 缓存中常见的问题,它们可能会导致数据库的负载加大,影响系统的性能。本文将详细讨论这些问题的原因和解决方案。 ...
缓存击穿是指缓存中的某个数据项正好到期,这时大量并发请求会直接打到数据库上,可能导致数据库压力骤增。处理方法包括: 1. **热点数据永不过期**:设置关键数据的缓存永不过期,避免因缓存失效而引发的大规模...
这种现象通常发生在高并发环境下,当某个或某些热点Key(即那些频繁被访问的数据项)在缓存中的存储时间到期而失效时,所有对这些Key的访问请求会瞬间集中地转向后端数据库,从而给数据库带来极大的压力。...
缓存击穿是指设置了过期时间的 key,承载着高并发,是一种热点数据,从这个 key 过期到重新从 MySQL 加载数据放到缓存的一段时间,大量的请求有可能把数据库打死。解决方法包括:设置 key 永远不过期,或者快过期时...
缓存击穿对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。 解决方案: 1. 使用互斥锁(mutex key),在缓存失效的时候(判断拿出来的值为空),不是...
缓存击穿通常发生在高并发环境下,当某个热点数据的缓存过期后,短时间内大量的请求直接打到后端数据库,导致数据库压力剧增,甚至可能导致服务不可用的情况。这种情况下的缓存失效就像是缓存墙上的一个缺口,大量的...
在高并发场景下,缓存系统是提升应用性能的重要手段之一。然而,当某个热门数据项(通常由一个特定的key标识)在缓存中过期时,如果恰好有大量用户同时请求该数据,那么所有的请求将直接穿透缓存层,直接到达后端...
在IT领域,特别是针对高性能和高并发的应用场景中,缓存穿透是一种常见的问题。它指的是客户端请求的数据既不在缓存中也不在数据库中,但客户端仍频繁发起请求,试图获取该数据的情况。这种情况尤其容易被恶意攻击者...
**缓存击穿**是指一个非常热门的数据项在缓存中过期,这时大量的并发请求会直接冲击数据库,因为数据库中仍有该数据。为了解决这个问题,可以采用加锁策略。例如,使用Java的`ReentrantLock`或分布式锁来确保只有一...
**面试篇**包含了高并发场景下的优化策略和常见问题,比如优化加锁方式可能导致的死锁,缓存穿透、击穿和雪崩的现象及其解决方案,以及Java中synchronized和Lock的区别和使用场景。 **系统架构篇**涉及高并发下的...