java如何解决内存缓存击穿问题?
简要说下缓存穿透,缓存击穿,缓存雪崩的出现情景和解决方案!
出现上述问题的前提:因为数据库使用磁盘存取数据,往往比较慢,而缓存使用内存(而且通常是key-value型),存取较快!
这样先使用内存缓存来缓存数据库数据,读取数据的时候先从缓存读取,只有获取不到的时候才从数据库获取!
下面分别从概念,出现场景,解决方案来说:
①,缓存穿透
概念:访问一个不存在的key,所有的读取都会访问数据库,通常数据库中也没有这样的数据,造成穿透,数据量大时,导致数据库卡死!
出现情景:一般数据库都是使用正整数来做id,然后使用id作为key缓存,如果有人恶意攻击,传一个负数(-100)做大量查询,那么数据库崩溃!
解决办法:
1,设置拦截,对不符合要求的id直接拦截!
2,缓存不存在,数据库也不存在也进行数据保存,key-null,并设置过期时间(短点好,1min),这样能拦截短时间内大量的同一个key的穿透!
②,缓存击穿
概念:缓存击穿通常发生在超高并发的时候,缓存中的key超时过期,这时候大量的请求同一时间落到数据库,造成数据库卡死!
出现场景:秒杀活动通常会把商品id等提前进行缓存,如果某个正想辞职的程序员在设置过期时间的时候,把过期时间设在了秒杀前一刻,那秒杀开始的时候,大量的请求将直接访问数据库!
解决办法:
1,热点数据设置超长的过期时间(甚至forever)
2,人为干预:在活动开始前先对所有热点数据进行设置!
③,缓存雪崩
概念:大批量的key过期,导致大量的查询到了持久层,引起卡死!主要是大量的key,而缓存击穿通常是一个或者少量key!
出现场景:缓存服务器宕机,代码错误等导致key大量过期等原因!
解决方法:
1,高可用缓存集群,保证缓存不挂!
2,过期时间使用随机算法,防止同一时间过期!