服务端的应用缓存设计

1. 类型

客户端缓存

缓存可以存储在客户端(操作系统或浏览器、服务端、或者是独立的缓存系统中。

CDN缓存

CDN也可以被认为是一种缓存。

Web服务器缓存

反向代理或者像Varnish这样的缓存服务可以直接保存静态的或动态的缓存内容。Web服务器也可以缓存请求直接响应客户端从而避免请求再次触达应用。

数据库缓存

我们的数据库服务在默认的配置或者稍微针对通用场景进行优化的情况下通常包含不同级别的缓存,针对特定的使用场景进行适当的调整可以进一步提高性能。

应用缓存

像Memcached和Redis这种内存key-value缓存服务,通常是置于应用和数据库服务之间,因为数据存储在内存中,因此这要比将数据存储在磁盘的数据库要快的多。但是内存与磁盘相比往往受限于空间,因此用类似LRU这种缓存淘汰算法将相对较少访问的”冷”数据从内存置换出来将访问频率较高的“热”数据放入内存。

2. 应用缓存

通过数据库服务前置缓存服务,可以有效吸收不均匀的负载和抵挡流量高峰

2.1 缓存级别

查询级别缓存

每当我们查询数据库的时候,将查询(比如SQL)进行hash并作为key和查询结果关联存储,这种方法会遇到缓存过期的问题:
对于复杂的查询很难删除缓存的结果;
缓存粒度较大,如果查询结果中只有丁点数据被更新,则整个查询都要过期;

对象级别缓存

对象级别缓存是将数据看做对象:
如果数据被修改则将数据从缓存中移除;
使用异步的任务来更新缓存;

2.2 数据读取

通用策略是Lazy load (Cache-Aside)


Lazy load策略
Lazy load实现

2.3 一致性 [难点]

现状

脏数据,简单通过设置过期时间(TTL)来缓解,当时间过期将发生强制更新缓存

问题

一致性问题,需要处理缓存中的数据与原数据不一致的问题
增加了软件架构的复杂性
缓存过期主要体现在何时更新缓存上

2.4 缓存更新策略

缓存更新策略

3. 数据库缓存

3.1 SQL查询流程
SQL查询流程
3.2 缓存类型

a. 执行计划
b. SELETE查询结果 (MySQL支持)

3.3 命中条件

匹配SQL/Version
无不确定数据

3.4 消耗

所有SQL强制查询
某些场景下的更新(碎片,内存,修改)会导致缓存失效
并发分配,失效的时候可能导致僵死

3.5 存储

缓存采用内存中的哈希引用表,SQL结果使用缓存数据块存储。


缓存数据块
3.6 数据库缓存策略调整
image.png

4. Redis接入

数据库/缓存/消息中间件

4.1 单线程

问题

采用基于内存的,单进程单线程模型, KV 数据库。
单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),其他模块仍用了多个线程。
事件驱动、所有命令处理在一个事件循环中。

应对
  1. 避免大key
    string value 小于限定值
    hash/set/zset 元素小于限定值
  2. 避免使用长时间阻塞的命令
    禁用 keys/flushall 等命令
    大key的平滑删除
  3. 避免过热的key
    最大支持的qps有上限, 热key分拆

4.1 内存

问题

所有数据都存放在内存中, 时延低

应对
  1. 避免单实例容量过大
    单实例:有目标上限
    存储集群: 有目标上限的内容和节点
    其他选择:考虑HBase/ABase
  2. 控制key的生命周期,redis不是垃圾桶
  3. 打散过期时间,防止集中过期
扩容
  1. 水平扩容 -通过增加分片实例完成扩容
    优点:可扩展
    缺点:扩容流程长,对业务有影响,避免高峰时期操作
  2. 垂直扩容 -直接修改配置内存值
    优点:对业务无损
    缺点:单实例内存上限

4.1 持久化

问题
  1. 磁盘的持久化:一般配置秒级 sync,最多丢失秒级的数据
    主从同步:异步方式,遇到主从切换后,同步中的数据丢失;
  2. 数据淘汰策略:
    noeviction:无逐出
    allkeys-lru:默认的逐出策略(近似的LRU)
应对
  1. 不要将 redis 当做高可靠的存储来使用

5 应用缓存的架构设计参考

CacheManager

模型管理对象,可以是多实例的,也可以是单实例的。

Cache

通过 CacheManager 创建出来的缓存容器,内部包含了真正的缓存承载体,至少开放 add/remove/flush 等接口。

CacheMap

真正的缓存承载体,大致上都是一个 Map,各种类型的 Map。

CacheEntity

缓存条目,相当于 CacheMap 里面的每一条 Entry。

CacheEvent

缓存事件,比如 CacheEntity 的创建、更新、删除等等。

CacheEventListener

缓存事件相应的监听器。

CacheEvictionAlgorithm

缓存淘汰算法,常见的有 LRU、LFU、FIFO 等等。

客户端缓存

形式

文件/内存/轻量级DB

场景

配置文件
变化少的数据,优化离线体验
最近缓存(Http& Feed &Image)

图片缓存-Fresco设计

图片缓存是客户端比较复杂的缓存和重要的一块,参考Fackbook开源的Fresco设计:


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

推荐阅读更多精彩内容