有过相关软件开发经验的朋友们对redis肯定不会陌生,就是不清楚各位亲们平时在使用redis的时候有没有注意过它的缓存原理呢?你们知道使用redis缓存时应该注意些什么吗?
redis 是以key-value形式存储,和传统的关系型数据库不一样。不一定遵循传统数据库的些基本要求,比如说,不遵循sql标准,事务,表结构等等,非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。 Java中数据结构:String,数组,list,set map…redis提供了很多的方法,可以用来存取各种数据结构的数据。
redis是以key-value形式存储,和传统的关系型数据库不一样。不一定遵循传统数据库的些基本要求,例如,不遵循sql标准,事务,表结构等等,非关系型数据库严格意义上不是一种数据库,而是一种数据结构化存储方法的集合。
Java中数据结构:Srig,数组,lis,semap…redis提供了很多的方法,可以用来存取各种数据结构的数据。我们需要注意以下几个问题:
一.redis和数据库双写一致性问题。
一致性问题是分布式常见问。数据库和缓存双写,就一定会存在不一致的问题。想要答这个问题,首先要明白一个前提。那就是数据如果有强一致性要求,不能放缓存,我们所做的这一切,最终只能保证最终一致性。此外,其实我们做的方案从根本上来说,只是说降低不一致发生的概率,其实并没办法完全避免。因此,如果有强一致性要求的数据,我们是不能放缓存的。我们可以采取正确的更新策略,先更新数据库,然后再删缓存就可以。其次,可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。
二.如何应对缓存穿透和缓存雪崩问题。
这两个问题,说句实话,一般中小型传统软件企业,很难碰到这个问题。但是如果一旦有大并发的项目,比如说流量有个几百万上下。那么这两个问题就一定要深刻考虑。缓存穿透,即黑客故意去请求缓存中不存在的数据,使得数据库连接异常。解决方法如下所示:
方法一:利用互斥锁,首先缓存失效的时候,会先去获得锁,锁得到了,再去请求数据库。如何没得到锁,就休眠一段时间重试。
方法二:用异步更新策略,不管key是不是取到值,都直接返回。value值中会去维护一个缓存失效时间,一旦缓存过期,异步了一个线程去读取数据库,然后更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
方式三:提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求它所携带的Key是不是合法有效。如果不合法,则直接返回。
缓存雪崩,这个时候又来了一波请求,结果请求都返回到数据库上,然后导致数据库连接异常。解决方法如下所示:
方法一:给缓存的失效时间,加上一个随机值,避免集体失效。
方法二:使用互斥锁,但是该方案吞吐量明显下降了。
方法三:双缓存。我们有两个缓存,缓存1和缓存2。
缓存1的失效时间为25分钟,缓存2不设失效时间。
a.从缓存1读数据库,有则直接返回。
b.1没有数据,直接从2读数据,直接返回,并且异步启动一个更新线程。
c.更新线程同时更新缓存1和缓存2。
三.如何解决redis的并发竞争key问题。
这个问题大致就是,同时有多个子系统去se一个key。这个时候要注意什么呢?如下所示:
如果对这个key操作,不要求顺序。面对这种情况,准备一个分布式锁,大家去抢锁,抢到锁就做se操作即可,比较简单。如果对这个key操作,要求顺序。
好了,以上就是有关redis缓存的的所有需要注意的地方了,如果还需要了解更多相关信息,敬请关注本站消息。