缓存问题

用了缓存之后,有哪些常见问题?

常见的问题,可列举如下:

写入问题

缓存何时写入?并且写时如何避免并发重复写入?

缓存如何失效?

缓存和 DB 的一致性如何保证?

经典三连问

如何避免缓存穿透的问题?

如何避免缓存击穿的问题?

如果避免缓存雪崩的问题?

如何避免缓存”穿透”的问题?


缓存穿透:是指查询一个一定不存在缓存中的数据,缓存不命中就会对到DB去查询,并且处于容错考虑,如果DB中不存在该数据,就不会更新缓存,这样每条请求都会去查一遍DB,这样缓存就会失去其意义。

如果存在黑客攻击,大量的请求打进来,可能mysql就会崩掉。

当然缓存击穿不一定是攻击,也可能是自己写的程序有问题,疯狂的请求不存在的数据,又或者无脑的爬虫请求。

如何去处理:

1.将不存在数据缓存起来

将不存在DB的书库,更新到缓存中,当然,要使用特殊的标识将该数据和正式的数据区分开来,做另外的请求反馈,并且还要配置好该缓存数据的过期策略,一般不要超过五分钟。

2.布隆过滤器(BloomFilter)

在缓存服务的基础上,构建BloomFilter布隆过滤器,在 BloomFilter 中存储对应的 KEY 是否存在,如果存在,说明该 KEY 对应的值不为空

这里流程即为:

布隆过滤器:如果存在对应的KEY值则进行下一步,否则直接返回。

数据缓存,如果存在KEY值,返回数据,否则直接返回。

查询到DB:如果存在则返回数据,并更新缓存。

这里需要注意:

BloomFilter存在误判,总而言之,就是不同过滤器中,存在不一定存在,不存在则一定不存在。

因为BloomFilter不能删除数据的特点,数据如果刚开始存在,后来删除了,那么BloomFilter中该数据存在,但DB不存在,会出现误判的情况。

当然,使用 BloomFilter 布隆过滤器的话,需要提前将已存在的 KEY ,初始化存储到【BloomFilter 缓存】中。

并且常用的缓存 Redis 默认不支持 BloomFilter 数据结构。

实际情况下,使用方案二比较多(BloomFilter)。因为,相比方案一来说,更加节省内容,对缓存的负荷更小。

如果避免缓存雪崩的问题?

缓存雪崩:由于某些原因导致无法提供服务(例如:缓存挂了),所有请求到达DB,导致DB负载严重,最终DB挂掉

如何解决雪崩

1.实现缓存高可用,如果其中一个缓存挂掉了,还有备用,

假设我们使用 Redis 作为缓存,则可以使用 Redis Sentinel 或 Redis Cluster 实现高可用。

2.引用本地缓存

即使分布式缓存服务挂掉了,也可以将DB查询到的数据缓存到本地,不至于一下将DB暴露出来。

当然引入本地服务,需要考虑实时性,

1.可以引入消息队列,在数据更新时,发布数据更新的消息;而进程中有相应的消费者消费该消息,从而更新本地缓存。

2.设置较短的过期时间,过期时从 DB 重新拉取。

每个进程可能会本地缓存相同的数据,导致数据浪费?

方案一,需要配置本地缓存的过期策略和缓存数量上限。

如果我们使用 JVM ,则可以使用 Ehcache、Guava Cache 实现本地缓存的功能。

3.请求 DB 限流

通过限制 DB 的每秒请求数,避免把 DB 也打挂了。这样至少能有两个好处:

可能有一部分用户,还可以使用,系统还没死透。

未来缓存服务恢复后,系统立即就已经恢复,无需再处理 DB 也挂掉的情况。

当然,被限流的请求,我们最好也要有相应的处理,走【服务降级】,提供一些默认的值,或者友情提示,甚至空白的值也行。

如果我们使用 Java ,则可以使用 Guava RateLimiter、Sentinel、Hystrix 实现限流的功能。

如何避免缓存"击穿"的问题?

缓存击穿,是指某个极度“热点”数据在某个时间点过期时,恰好在这个时间点对这个 KEY 有大量的并发请求过来,这些请求发现缓存过期一般都会从 DB加载数据并回设到缓存,但是这个时候大并发的请求可能会瞬间 DB 压垮。

对于一些设置了过期时间的 KEY ,如果这些 KEY 可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑这个问题。

如何解决:

1.使用互斥锁

请求发现缓存不存在后,去查询DB,使用分布式锁,保证有且只有一个线程去查询 DB ,并更新到缓存

流程如下

1、获取分布式锁,直到成功或超时。如果超时,则抛出异常,返回。如果成功,继续向下执行。

2、获取缓存。如果存在值,则直接返回;如果不存在,则继续往下执行。😈 因为,获得到锁,可能已经被“那个”线程去查询过 DB ,并更新到缓存中了。

3、查询 DB ,并更新到缓存中,返回值。

2.使用手动过期

缓存上从不设置过期时间,功能上将过期时间存在 KEY 对应的 VALUE 里。

流程如下:

1、获取缓存。通过 VALUE 的过期时间,判断是否过期。如果未过期,则直接返回;如果已过期,继续往下执行。

2、通过一个后台的异步线程进行缓存的构建,也就是“手动”过期。通过后台的异步线程,保证有且只有一个线程去查询 DB。

3、同时,虽然 VALUE 已经过期,还是直接返回。通过这样的方式,保证服务的可用性,虽然损失了一定的时效性。(无法保证缓存一致性)

区别:

缓存"击穿"和缓存"雪崩"的区别在于,前者针对某一 KEY 缓存,后者则是很多 KEY 。

缓存"击穿"和缓存"穿透"的区别在于,这个 KEY 是真实存在对应的值的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容