Redis入门——缓存设计

新垣结衣ヾ(๑╹◡╹)ノ"

日常开发中,缓存能够有效加速应用的读写速度,同时也可以降低后端负载,不过也随之带来一些问题。(参考付磊、张益军两位大神的《Redis开发与运维》

缓存优点

加速读写:缓存通常是全内存的(例如Redis、Memcache),而存储层通常读写性能不够强悍,通过缓存的使用可以有效地加速读写,优化用户体验;
降低后端负载:帮助后端减少访问量和复杂计算(比如很复杂的sql逻辑),很大程度上降低了后端的负载。

缓存缺点

数据不一致性:缓存层和存储层的数据存在着一定时间窗口的不一致性,时间窗口跟更新策略有关;
代码维护成本:加入缓存后,需要同时处理缓存层和存储层的逻辑,增大了开发者维护代码的成本;
运维成本:比如Redis Cluster,加入后无形中增加了运维成本。

P.S. 分析缓存优缺点,不难看出缓存主要用于两种场景,一是开销大的复杂计算,比如很复杂的sql计算等;二是加速请求响应。

缓存更新策略

缓存中的数据一般是有生命周期的,需要在指定时间后被删除或更新,从而来保证缓存空间在一个可控的范围内,但缓存中的数据会和数据源的真实数据有一段时间窗口的不一致,需要利用某些策略进行更新。常见的有三种缓存的更新策略:

  1. LRU/LFU/FIFO算法剔除
    剔除算法一般用于缓存使用量超过预设最大值,如何对现有的数据进行剔除。Redis使用maxmemory-policy作为内存最大值对数据进行剔除。清理哪些数据交由算法决定,开发人员只能决定选择何种算法,所以数据的一致性最差,但也意味着维护成本低,不需要自己设计算法,只要选择适合的算法即可。
  2. 超时剔除
    超时剔除一般用于给缓存设置过期时间,让其过期后自动删除。Redis使用expire来实现。不过一段时间内窗口内(取决于过期时间长短)存在一致性问题,即缓存数据和真实数据源不一致。该策略的优点在于维护成本较低,只需设置expire过期时间即可,当然也要接受其不一致的缺点。
  3. 主动更新
    这种一般用于应用对于数据一致性要求很高,需要在真实数据更新后,立即更新缓存数据。比如可以利用消息系统或其他方式通知缓存更新。其一致性是三种策略中最高的,维护成本也是最高的。

P.S.低一致性业务建议配置最大内存和淘汰策略;高一致性业务建议结合使用超时剔除和主动更新

穿透优化

缓存穿透是指查询一个不存在的数据,存储层和缓冲层都不会命中,通常用于容错考虑,如果存储层查不到数据则不写入缓冲层。如下图

缓存穿透模型

缓存穿透将导致不存在的数据每次请求都要都存储层去查询,失去了缓存保护后端存储的意义。
缓存穿透问题可能会使后端存储负载加大,并且由于很多后端存储不具备高并发性,严重的会导致后端存储宕掉。可以在程序中分别统计总调用数、缓存层命中数、存储层命中数,如果发现大量存储层命中,说明可能发生了缓存穿透。
缓存穿透基本原因有两个,一是自身业务代码或数据出现问题;二是恶意攻击或爬虫。
目前解决方案有两种,一是缓存空对象,二是布隆过滤器拦截

  1. 缓存空对象
    缓存穿透过程中,当存储层不命中后,仍将空对象保留到缓存层中,之后再访问这个数据将会从缓存中获取,这样就可以保护后端数据源。
    这种方案有两个问题,一是空对象做了缓存,意味着缓存层中存了更多的键,需要分配更多的内存空间。可以通过对这类数据设置一个较短的过期时间,让其自动剔除,释放内存空间。二是缓存层和存储层会有一段时间窗口的不一致,可以利用消息系统或其他方式消除掉缓存层中的空对象。
  2. 布隆过滤器拦截
    在访问缓存层和存储层之前,将存在的key用布隆过滤器(BloomFilter)提前保存,做一层拦截。
    举个例子,一个推荐系统有1亿个id,一定时间算法会根据用户之前历史行为计算出推荐数据,并将其存入缓存层,但是如果用户没有历史行为,那么就会发生缓存穿透,因为可以将所有推荐数据的用户做成布隆过滤器。过滤器判定是否存在该历史用户,如果不存在,就不让访问存储层,一定程度上保护后端数据源。

无底洞优化

随着业务的发展,需要添加更加庞大的节点,批量操作需要从不同节点上获取,而且键值分布到更多的节点上,网络和性能开销变得更高,即投入越多产出却不一定越多。无底洞优化也就是在分布式缓存中批量操作的优化。
一般的IO优化方案有:优化命令;减少网络通信次数;降低接入成本。
Redis批量操作获取n个字符串,有三种实现思路:
1.客户端n次get:n次网络+n次get命令,具体方案有串行命令
2.客户端1次pipeline get:1次网络+n次get命令,具体方案有串行 IO并行IO
3.客户端1次mget:1次网络+1次mget命令,具体方案有hash_tag实现

雪崩优化

由于缓存层承载着大量请求,有效地保护了存储层,但由于某种原因缓存层挂了,所有请求都直接达到存储层,造成存储层出现级联宕机,这就是缓存雪崩。
预防和解决缓存雪崩有三种思路:
1.保证缓存层服务高可用性。这样个别节点、个别机器或者是机房宕机都能继续提供服务。
2.依赖隔离组件为后端限流并降级。简单来说,就是隔离和降级。
3.提前演练。模拟缓存层宕掉的情况,然后对后端负载等其他情况进行方案演练。

热点key重建优化

前面讲过“缓存+过期时间”的策略可以满足大部分需求,但是如果当前key是很热门的key(热门新闻等),并发量非常大,或者是由于有复杂计算,重建缓存不能短时间内完成。
在缓存失效的瞬间,有大量线程来重建缓存,会造成后端负载加大,严重可能会导致应用崩溃。
简单来分析,需要做到减少重建缓存次数,数据尽可能一致,减少潜在危险。有两种解决方案:
1.互斥锁:只允许一个线程重建缓存,其他线程等待其重建结束,重新重缓存获取数据。思路简单,但如果重建缓存时间过程或出现问题,可能会存在死锁或线程池阻塞的风险。不过这种方案能较好地降低后端存储负载,保持不错的一致性。
2.“永远不过期”:从缓存角度上,不设置过期expire时间,从功能角度上,为每个value设置逻辑过期时间,当发现超过逻辑过期时间,则使用单独线程去构建缓存。这种方案很明显会存在一致性问题,并且代码复杂度会增大,不过热点key导致的问题基本能根除。

小结

聊了缓存设计,很多方案有其长处短处,需要根据实际业务要求,采用合适的方案进行缓存设计,不存在所谓的“万能钥匙”,这就需要我们开发和运维人员熟悉了解缓存设计,活用设计方案。

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

推荐阅读更多精彩内容