这篇文章给大家聊聊关于java如何解决内存缓存击穿问题,以及redis缓存穿透的解决办法对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。
本文目录
数据穿透是什么
缓存穿透:缓存和数据库中都没有的数据,而用户(黑客)不断发起请求。
例子
我们数据库的id都是从1自增的,如果发起id=-1的数据或者id特别大不存在的数据,这样的不断攻击导致数据库压力很大,严重会击垮数据库。
解决
1)增加校验。比如用户鉴权,参数做校验,不合法的校验直接return,比如id做基础校验,id<=0直接拦截;
2)布隆过滤器。Redis里还有一个高级用法布隆过滤器(BloomFilter)这个也能很好的预防缓存穿透的发生。
它的原理也很简单,就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查DB刷新KV再return。
redis是否可以代替mysql进行数据存储怎么样
Redis本身是支持数据持久化的,很多有些程序员都会觉得Redis应该可以替代MySQL,但是我们在使用一项技术的时候,不是看它能不能,而是要看它适合不适合;而在大部分场景下,Redis是无法替代MySQL的。
MySQL是关系型数据库,数据储存在磁盘上,数据的格式是我们熟知的二维表格的样式。关系型数据库具有很多强大的功能;大部分都支持SQL语句查询,对事务也有很好的支持。
Redis被称作非关系型数据库,属于内存数据库,数据都储存在内存中(Redis有RDB持久化策略),Redis支持的数据类型也比较多,比如字符串,HASH,List等。
MySQL和Redis没有竞争的关系,通常当并发访问量比较大的时候,特别是读操作很多,架构中可以引入Redis,帮助提升架构的整体性能,减少Mysql(或其他关系型数据库)的压力;
不是MySQLorRedis;而是MySQL+Redis;
因为Redis的性能十分优越,可以支持每秒十几万此的读/写操作,并且它还支持持久化、集群部署、分布式、主从同步等,Redis在高并发的场景下数据的安全和一致性,所以它经常用于这些场景:
经常要被查询,但是CUD操作频率低的数据;比如数据字典,确定了之后很少被修改,是可以放到缓存中的;还有热点数据,查询极为频繁的数据,放到Redis中可以减少MySQL的压力;
经常被查询,但是实时性要求不高数据,比如购物网站的热销排行榜,定时统计一次后把统计结果放到Redis中提供查询(请不要每次都使用selecttop10fromxxxx)。
缓存还可以做数据共享(Session共享),在分布式的架构中,把用户的Session数据放到Redis中。
高并发场景下的计数器,比如秒杀,把商品库存数量放到Redis中(秒杀的场景会比较复杂,Redis只是其中之一,例如如果请求超过某个数量的时候,多余的请求就会被限流);
因为Redis对高并发的支持和单线程机智,它也经常用作分布式锁;
Redis虽然功能强大、性能高效,但是也不是万能的,项目在引入Redis的时候,需要考虑的问题也比较多,并且会带来额外的开发和运维的工作量。
首先要判断数据是否适合缓存到Redis中,可以从几个方面考虑:数据会被经常查询么?命中率如何?写操作多么?数据大小?数据一致性如何保证?
我们经常采用这样的方式将数据刷到Redis中:查询的请求过来,现在Redis中查询,如果查询不到,就查询数据库拿到数据,再放到缓存中,这样第二次相同的查询请求过来,就可以直接在Redis中拿到数据;不过要注意【缓存穿透】的问题。
缓存的刷新会比较复杂,通常是修改完数据库之后,还需要对Redis中的数据进行操作;代码很简单,但是需要保证这两步为同一事务,或最终的事务一致性。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。redis雪崩和穿透的区别
雪崩:击穿比较侧重某一个key失效,当大量的key同时失效,会造成大量的请求怼到数据库,就会发生雪崩效应。
雪崩是大面积的key缓存失效;穿透是redis里不存在这个缓存key;击穿是redis某一个热点key突然失效,最终的受害者都是数据库。
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,过期时间使用随机算法,防止同一时间过期!
实际应用中,缓存雪崩是比较容易碰到的情况,还是尤其需要注意的,最近在持续分享JAVA相关的东西,需要的朋友可以关注。。。
关于java如何解决内存缓存击穿问题的内容到此结束,希望对大家有所帮助。
声明:本文内容来自互联网不代表本站观点,转载请注明出处:https://bk.oku6.com/11/87865.html