`
hbxflihua
  • 浏览: 678470 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

高并发下,如何防止缓存被“击穿”

阅读更多

对于一些设置了过期时间的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)

    **高并发缓存器(基于ehcache)** 在IT行业中,面对高并发场景时,缓存技术是提高系统性能和响应速度的关键手段。基于ehcache的缓存器是一种常见的解决方案,它能够在内存中存储常用数据,减少对数据库的访问,从而...

    如何应对redis缓存雪崩,redis缓存穿透,redis缓存击穿,redis应对高并发的解决方案

    redis缓存雪崩,redis缓存穿透,redis缓存击穿 redis应对高并发造成的雪崩、穿透、击穿

    Redis缓存穿透,缓存击穿,缓存雪崩面试题解析

    缓存击穿是指在高并发的情况下,缓存中的某个热点数据失效或过期,导致大量请求直达数据库,导致数据库压力增大,甚至宕机。缓存击穿的原因主要是缓存热点数据的失效或过期。 解决方案: 1. 使用缓存热点数据的...

    Redis系统学习之缓存穿透,缓存击穿,缓存雪崩的概念及其解决方案.docx

    缓存穿透是指在高并发场景下,大量的请求访问了一个既不在缓存中也不在数据库中的数据。这种情况通常发生在非法用户尝试利用不存在的数据ID进行恶意访问时,或者是系统设计缺陷导致请求直接跳过缓存访问数据库。 **...

    缓存击穿的介绍.zip

    这个问题在高并发场景下尤为突出,因此理解和防范缓存击穿至关重要。 缓存击穿的原因通常有两种:一是缓存过期,二是缓存未命中。在大多数情况下,缓存系统会设置一个过期时间,当这个时间到达时,缓存的数据将不再...

    缓存击穿的定义.zip

    缓存击穿是分布式系统中一个重要的问题,特别是在高并发、大数据量的场景下,它可能导致后端数据库不堪重负,影响服务的稳定性和性能。本文将深入探讨缓存击穿的概念、原因、影响以及应对策略。 缓存击穿是指在缓存...

    缓存击穿概念讲解.zip

    缓存击穿是分布式系统中一个重要的问题,它发生在高并发场景下,当大量请求同时穿透缓存,直接访问后端存储系统,如数据库或文件系统,可能导致后端负载过高,甚至服务崩溃。理解并解决缓存击穿是保证系统稳定性和...

    缓存击穿问题解释 .zip

    缓存击穿问题在IT行业中是一个重要的概念,尤其是在高并发、大数据量的系统设计中,理解和解决这个问题至关重要。缓存通常被用作减轻数据库压力、提高系统响应速度的关键技术。然而,当缓存失效时,如果处理不当,就...

    如何设计缓存系统:缓存穿透,缓存击穿,缓存雪崩解决方案分析.docx

    缓存击穿对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一 ...

    缓存穿透、缓存击穿、缓存雪崩区别和解决方案1

    **缓存击穿**发生在缓存中的某条数据刚好过期,而数据库中存在该数据的情况下,大量并发请求同时绕过缓存直接访问数据库,可能导致数据库瞬间压力剧增。解决方法之一是设置热点数据永不过期,确保这些数据始终存在于...

    Redis缓存穿透缓存雪崩缓存击穿的原因和解决方案.docx

    Redis缓存穿透、缓存雪崩、缓存击穿的原因和解决方案 Redis缓存穿透、缓存雪崩、缓存击穿是 Redis 缓存中常见的问题,它们可能会导致数据库的负载加大,影响系统的性能。本文将详细讨论这些问题的原因和解决方案。 ...

    Redis缓存穿透,缓存击穿和缓存雪崩

    缓存击穿是指缓存中的某个数据项正好到期,这时大量并发请求会直接打到数据库上,可能导致数据库压力骤增。处理方法包括: 1. **热点数据永不过期**:设置关键数据的缓存永不过期,避免因缓存失效而引发的大规模...

    缓存击穿的现象及解决方案.pdf

    这种现象通常发生在高并发环境下,当某个或某些热点Key(即那些频繁被访问的数据项)在缓存中的存储时间到期而失效时,所有对这些Key的访问请求会瞬间集中地转向后端数据库,从而给数据库带来极大的压力。...

    缓存雪崩,缓存穿透,缓存击穿出现的原因及解决方案.docx

    缓存击穿是指设置了过期时间的 key,承载着高并发,是一种热点数据,从这个 key 过期到重新从 MySQL 加载数据放到缓存的一段时间,大量的请求有可能把数据库打死。解决方法包括:设置 key 永远不过期,或者快过期时...

    缓存穿透,缓存击穿,缓存雪崩解决方案分析.docx

    缓存击穿对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。 解决方案: 1. 使用互斥锁(mutex key),在缓存失效的时候(判断拿出来的值为空),不是...

    面试被问:缓存击穿有什么解决方案.docx

    缓存击穿通常发生在高并发环境下,当某个热点数据的缓存过期后,短时间内大量的请求直接打到后端数据库,导致数据库压力剧增,甚至可能导致服务不可用的情况。这种情况下的缓存失效就像是缓存墙上的一个缺口,大量的...

    使用Golang的singleflight防止缓存击穿的方法

    在高并发场景下,缓存系统是提升应用性能的重要手段之一。然而,当某个热门数据项(通常由一个特定的key标识)在缓存中过期时,如果恰好有大量用户同时请求该数据,那么所有的请求将直接穿透缓存层,直接到达后端...

    缓存穿透、缓存击穿、缓存雪崩区别和解决方案【php】.docx

    在IT领域,特别是针对高性能和高并发的应用场景中,缓存穿透是一种常见的问题。它指的是客户端请求的数据既不在缓存中也不在数据库中,但客户端仍频繁发起请求,试图获取该数据的情况。这种情况尤其容易被恶意攻击者...

    缓存击穿、缓存雪崩和缓存穿透的区别及解决方案

    **缓存击穿**是指一个非常热门的数据项在缓存中过期,这时大量的并发请求会直接冲击数据库,因为数据库中仍有该数据。为了解决这个问题,可以采用加锁策略。例如,使用Java的`ReentrantLock`或分布式锁来确保只有一...

    深入理解高并发编程-核心技术原理

    **面试篇**包含了高并发场景下的优化策略和常见问题,比如优化加锁方式可能导致的死锁,缓存穿透、击穿和雪崩的现象及其解决方案,以及Java中synchronized和Lock的区别和使用场景。 **系统架构篇**涉及高并发下的...

Global site tag (gtag.js) - Google Analytics