在分布式系统中的缓存,有 Redis,Memcached 等后端存储,在前端页面,浏览器,网络 CDN 中也有缓存
Redis,或者 Memcached 等服务端缓存,在缓存分类中只是一小部分
从前端 Web 请求,到网络传输,再到服务端和数据库服务
各个阶段都有缓存的应用
打开淘宝或京东,查看一个商品详情页面,这个过程涉及多种缓存的协同
前端缓存
前端缓存包括页面和浏览器缓存,如果使用的是 App,在 App 端也会有缓存
页面缓存属于客户端缓存的一种
第一次访问时,页面缓存将浏览器渲染的页面存储在本地
当用户再次访问相同的页面时,可以不发送网络连接,直接展示缓存的内容
HTML5 支持本地存储,本地存储包括 localStorage 和 sessionStorage
- localStorage 没有时间限制
- sessionStorage 与 session 的有效期内相关
HTML5 支持离线缓存——Application Cache 技术,实现应用离线的缓存
Application Cache 是基于 manifest 文件实现的缓存机制
浏览器会通过这个文件上的清单解析存储资源
页面缓存用于数据更新比较少的数据,大部分浏览器自身会实现缓存功能
对于页面中的图片和视频等,浏览器都会进行缓存
App 内的各级缓存更加复杂,在 Android 和 iOS 开发中也有区别
只需要知道客户端缓存是非常重要的优化手段
网络传输缓存
大多数业务请求是通过 HTTP / HTTPS 协议实现的
它们工作在 TCP 协议上,多次握手后,浏览器和服务器建立 TCP 连接,然后进行数据传输
在传输过程中,会涉及多层缓存,比如 CDN 缓存等
CDN(Content Delivery Network,内容分发网络)实现的关键包括内容存储和内容分发
- 内容存储——对数据的缓存功能
- 内容分发——CDN 节点支持的负载均衡
前端请求在经过 DNS 之后,会被指向网络中最近的 CDN 节点
该节点从真正的应用服务器获取资源返回给前端,同时将静态信息缓存
在新的请求过来后,可以只请求 CDN 节点的数据
同时 CDN 节点也可以和服务器之间同步更新数据
负载均衡服务器主要实现的是请求路由——负载均衡功能
也可以实现部分数据的缓存,比如一些配置信息等很少修改的数据
用户请求在达到应用服务器之前,会选访问 Nginx 负载均衡器
- 有缓存信息,直接返回给用户
- 没有发现缓存信息,Nginx 会回源到应用服务器获取信息
服务端缓存
服务端缓存是缓存的重点,是业务开发平时打交道最多的缓存
服务端缓存又分为 本地缓存和外部缓存
本地缓存可以叫作应用内缓存
比如 Guava 实现的各级缓存,或者 Java 语言中使用各类 Map 结构实现的数据存储
特点——随着服务器重启后失效,作用时间很短
好处——应用比较灵活
外部缓存是 Redis,Memchaed 等 NoSQL 存储的分布式缓存
是在系统设计中对整体性能提升最大的缓存
如果外部缓存使用不当,会导致缓存穿透,缓存雪崩等业务问题
数据库缓存
在 Java 开发中,一般使用 MyBatis 或者 Hibernate 作为数据库访问的持久化层
MyBatis 为每个 SqlSession 都创建了 LocalCache , LocalCache 可以实现查询请求的缓存
如果查询语句命中了缓存,返回给用户
否则查询数据库,并且写入 LocalCache,返回结果给用户
在数据执行查询语句时,MySQL 会保存一个 Key-Value 的形式缓存在内存中
Key 是查询语句,Value 是结果集
如果缓存 Key 被命中,会直接返回给客户端
否则会通过数据库引擎进行查询,并且把结果缓存起来
当数据有修改时,需要删除缓存
总结
本文讲解了 分布式系统设计中的缓存应用
包括前端缓存,网络缓存,服务端缓存,以及数据库缓存
计算机操作系统设计的多种缓存,比如 Page Cache, Buffer Cache 等技术