美文网首页
缓存使用常见问题归纳

缓存使用常见问题归纳

作者: 骊骅 | 来源:发表于2017-05-09 00:03 被阅读112次

缓存是一种提高系统读性能的常见技术,对于读多写少的应用场景,我们经常使用缓存来进行优化。无论使用哪一种缓存技术,有些问题是缓存都要面临的。总结归纳一下。


名词解释:
缓存的命中率 = 命中缓存请求个数/总缓存访问请求个数 = hit/(hit+miss)

缓存穿透

问题描述:
我们在项目中使用缓存通常都是先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回。这个时候如果我们查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB,这样缓存就失去了意义,在流量大时,可能DB就挂掉了。


解决思路:
将这个不存在的key预先设定一个值。比如,"key" , “&&”。
在返回这个&&值的时候,我们的应用就可以认为这是不存在的key,那我们的应用就可以决定是否继续等待继续访问,还是放弃掉这次操作。如果继续等待访问,过一个时间轮询点后,再次请求这个key,如果取到的值不再是&&,则可以认为这时候key有值了,从而避免了透传到数据库,从而把大量的类似请求挡在了缓存之中。

缓存并发

问题描述:
有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大。


解决思路:
【1】我们会想到类似“锁”的机制,在缓存更新或者过期的情况下,先尝试获取到锁,当更新或者从数据库获取完成后再释放锁,其他的请求只需要牺牲一定的等待时间,即可直接从缓存中继续获取数据。
这个方法不靠谱,性能会很差。分布式情况下,如果只是单机使用锁,还是会有DB并发问题
【2】定期从DB里查询数据,再刷到缓存里面,确保缓存里面的数据一直可以读到。
这种方法有个缺点是,有些业务的key可能是变化的,不确定的。
【3】两个key,一个key用来存放数据,另一个用来标记失效时间。
比如key是aaa,设置失效时间为30s,则另一个key为expire_aaa,失效时间为25s。在取数据时,同时取出aaa和expire_aaa,如果expire_aaa的value == null,则后台启动一个任务去查询DB,更新缓存。对于后台启动一个任务去查询DB,更新缓存,要保证一个key只有一个线程在执行,这个如何实现?
对于同一个进程,简单加锁即可。拿到锁的就去更新DB,没拿到锁的直接返回。
对于集群式的部署的,如何实现只允许一个任务执行?可以使用分布式锁。
当get expired_aaa是null时,则add expired_aaa 过期时间由自己灵活处理。比如设置为3秒。
如果成功了,再去查询DB,查到数据后,再set expired_aaa为25秒。set aaa 为30秒。
综上所述,来梳理下流程:
比如一个key是aaa,失效时间是30s。查询DB在1s内。
put数据时,设置aaa过期时间30s,设置expire_aaa过期时间25s;
get数据时,multiget aaa 和 expire_aaa,如果expired_aaa对应的value != null,则直接返回aaa对应的数据给用户。如果expire_aaa返回value == null,则后台启动一个任务,尝试add expire_aaa,并设置超时过间为3s。这里设置为3s是为了防止后台任务失败或者阻塞,如果这个任务执行失败,那么3秒后,如果有另外的用户访问,那么可以再次尝试查询DB。如果add执行成功,则查询DB,再更新aaa的缓存,并设置expire_aaa的超时时间为25s。
这种方法的好处是从缓存里面查询数据的线程不受阻塞,同时查询db的线程不会多,即使在分布式不使用分布式锁,至多线程数也就是机器数

缓存失效

问题描述:
引起这个问题的主要原因还是高并发的时候,平时我们设定一个缓存的过期时间时,可能有一些会设置1分钟啊,5分钟这些,并发很高时可能会出在某一个时间同时生成了很多的缓存,并且过期时间都一样,这个时候就可能引发一当过期时间到后,这些缓存同时失效,请求全部转发到DB,DB可能会压力过重。


解决思路:
将缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

更新缓存 VS 淘汰缓存

什么是更新缓存:数据不但写入数据库,还会写入缓存
什么是淘汰缓存:数据只会写入数据库,不会写入缓存,只会把数据淘汰掉


更新缓存的优点:缓存不会增加一次miss,命中率高
淘汰缓存的优点:简单

先操作数据库 vs 先操作缓存

假设先写数据库,再淘汰缓存:第一步写数据库操作成功,第二步淘汰缓存失败,则会出现DB中是新数据,Cache中是旧数据,数据不一致。
假设先淘汰缓存,再写数据库:第一步淘汰缓存成功,第二步写数据库失败,则只会引发一次Cache miss。
所以结论是:先淘汰缓存,再写数据库

缓存一致性问题

http://oicwx.com/detail/830856

相关文章

  • 高并发系统技术梳理

    缓存 缓存使用常见问题归纳Guava Cache系列之一Guava Cache系列之二Guava Cache系列之...

  • 缓存使用常见问题归纳

    缓存是一种提高系统读性能的常见技术,对于读多写少的应用场景,我们经常使用缓存来进行优化。无论使用哪一种缓存技术,有...

  • Redis总结

    一、数据类型 二、使用场景 二、redis缓存使用总结 三、redis缓存常见问题 四、布隆过滤器的方式解决缓存穿透问题

  • Redis缓存雪崩、缓存击穿、缓存穿透、缓存预热、缓存更新、缓存

    关于Redis常见问题:缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等概念的入门及简单解决方案。 一、缓存雪崩...

  • 《剖析缓存系列》—— 熟悉JSR-107 JAVA缓存规范

    本系列介绍 本系列《剖析缓存系列》,由浅到深的对缓存进行分析介绍,从缓存形式,更新策略,常见问题,以及JAVA缓存...

  • 《剖析缓存系列》—— 缓存介绍

    本系列介绍 本系列《剖析缓存系列》,由浅到深的对缓存进行分析介绍,从缓存形式,更新策略,常见问题,以及JAVA缓存...

  • 分布式锁-Redis

    一、缓存常见问题   对于访问频率高、读多写少、一致性要求不高的数据适合做缓存。 1.1 缓存穿透   缓存穿透:...

  • 常见问题归纳

    出现这种问题一般是因为:一:jar包没有导入二:jar包导入了,但是版本较低 pom.xml文件中报错,到远程仓库...

  • Redis-3大常见问题

    缓存常见问题 by shihang.mai 雪崩 大量的key同时失效,高并发请求导致压力全部到库。叫缓存雪崩。 ...

  • github 常见问题归纳

    git init 产生的目录解释 引起该错误的原因是,目录中没有文件,空目录是不能提交上去的 解决办法:重新执行 ...

网友评论

      本文标题:缓存使用常见问题归纳

      本文链接:https://www.haomeiwen.com/subject/jsgvtxtx.html