java如何解决内存缓存击穿问题(java如何处理内部缓存对象)

高并发下该先更新缓存还是数据库 踩完这些坑你就懂了

这篇文章给大家聊聊关于java如何解决内存缓存击穿问题,以及redis缓存穿透的解决办法对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

本文目录

  1. 数据穿透是什么
  2. redis是否可以代替mysql进行数据存储怎么样
  3. redis雪崩和穿透的区别
  4. java如何解决内存缓存击穿问题

数据穿透是什么

缓存穿透:缓存和数据库中都没有的数据,而用户(黑客)不断发起请求。

例子

我们数据库的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

相关推荐