中文同类 xta0.me/2016/06/22/…
- app server 缓存
- 内容分发(或分布式) 网络 CDN
- 缓存失效
- 缓存驱逐策略
缓存
LB通过增加server数量,实现水平扩展。 cache能够更好的利用已有资源,无法实现的产品需求变成可能。 1. 缓存充分利用引用的局部性原则:最近请求的数据很可能会被再次请求。 2. 在几乎所有计算层使用:硬件、操作系统、网页浏览器、web应用等 缓存像短期记忆:空间有限
1. 应用层缓存——请求侧完整缓存
在请求层放缓存,可以在内存和节点的本地磁盘(比网络存储快)。 如果扩展到多个节点,LB使相同的请求随机到不同节点,将会加快缓存丢失。 解决方式是:全局缓存和分布式缓存
2. 分布式缓存——请求侧物理分割式缓存
分布式缓存中,每个节点保存缓存数据的一部分,典型的,缓存被一致性hash分成多块,请求会到一个确定的分片。每个节点有一小片缓存,会在请求最终源头前向另一个节点发送数据请求。 优点:可以通过增加节点到请求池的方式,增加分布式缓存空间。 物理上分开的,逻辑上是一个整体。
缺点:需要解决节点丢失(导致该节点所拥有的缓存数据不可用)。 解决方式:1. 增加数据副本到不同的节点上,但会导致请求层增加或删除节点逻辑变得复杂。 节点的缓存丢失,请求会发向最终源头,因此这种情况是可接受的
3. 全局缓存——独立缓存服务
所有节点使用同一个缓存空间。需要一个独立的服务,或者一个高效的文件存储,能够被请求层所有节点访问。 问题:随着客户端和请求数增加,单个缓存很容易支撑不住。 有时却很高效,专用硬件让全局缓存更快,或者需要存储固定大小的数据集
2种常见全局缓存: 1) 缓存中没有时,缓存从下层数据库获取数据。 大多应用选择这种方式,缓存自身管理数据驱逐和获取,来阻止客户端大量相同数据请求 2) 缓存中没有时,请求端主动从下层数据库获取,同时缓存自动拉取数据 场景:缓存会自动从数据库中读取该文件,由于数据较大,读取的耗时会很长,这会导致缓存中pending的查询越来越多。这时如果使用第二种方式,由业务查询DB则会大大降低缓存压力。 或者,存储在缓存中的数据是静态的,不会被驱逐。某些大型数据集,一些数据的需求非常快,相对缓存应用更了解驱逐策略。
全局缓存的优点是无状态,缓存节点的增删对集群没有太大的影响,缺点是单个节点能承受的数据容量有限,而且节点之间维护数据一致性也很麻烦。
4. 内容分发网络 CDN
如果系统不够庞大到用上CDN, 可以选择轻量级http服务nginx,单独子域名的方式提供静态资源换缓解请求转发。之后从DNS迁移到CDN。 由于缓存服务器部署在网络运营商的机房,而这些运营商又是用户的网络服务提供商,因此用户可以以最短的路径,最快的速度对网站进行访问。因此,CDN可以加速用户访问速度,减少源站中心负载压力。 juejin.cn/post/685457…
缓存失效
需要维护缓存一致性,源数据发生变化,则应当让缓存失效,避免应用行为不一致。 解决方式:
1) write-through cache(直写缓存)数据同时写入缓存和对应数据库。——保证了一致性
- 好处:缓存和存储之间保持一致,在崩溃、掉电、系统中断情况下不丢失内容
- 问题:写操作被执行2次,然后客户端返回success。从而造成写操作更大的延迟
2)write-around cache(绕过缓存):数据不经缓存,直接写入持久存储。——保证了客户端响应的及时性,写db
- 好处:减少缓存被写操作冲刷,而某些数据并不会在接下来被读取。
- 问题:对最近写入的数据读请求可能会产生"缓存丢失"(未命中),必须向更慢的后端存储获取。导致更高延迟。
3)Write-back cache(回写缓存):单独将数据写入缓存,然后立刻返回客户端响应。——保证及时性,写缓存 指定时间间隔或条件写,再写入db。
- 好处:对写操作密集型操作比较使用,低延迟、高吞吐。
- 问题:写入数据只在缓存,崩溃或其他情况是有数据丢失风险
缓存驱逐策略
- FIFO: 优先驱逐最先访问的第一个缓存块。忽略之前被访问的频率、次数
- LIFO (Last In First Out): 优先驱逐最近访问的块,忽略频率、次数
- LRU (Least Recently Used): (最近最少使用 时间) 优先驱逐最近最少使用的块
- MRU (Most Recently Used): (最近使用) 优先驱逐最近使用的块
- LFU (Least Frequently Used): (最不常用 频率) 优先驱逐低频使用的块
- RR (Random Replacement): 必要时随机选择一个块丢弃