缓存技术及相关概念
缓存技术
系统缓存:
buffer:
- 缓冲也叫写缓冲,一般用于写操作,可以将数据先写入内存再写入磁盘,
- 用于解决不同介质的速度不一致的缓冲,先将数据临时写入到里自己最近的地方,以提高写入速度,CPU会把数据先写到内存的磁盘缓冲区,然后就认为数据已经写入完成看,然后由内核在后续的时间在写入磁盘,所以服务器突然断电会丢失内存中的部分数据。
cache:
- 缓存也叫读缓存,一般用于读操作,CPU读文件从内存读,如果内存没有就先从硬盘读到内存再读到CPU,将需要频繁读取的数据放在里自己最近的缓存区域,下次读取的时候即可快速读取。
清除缓存:
建议: 生产环境一般不建议清除(特别是数据库)。推荐清除之前,把buffer中的数据写入到磁盘,用sync命令
drop_cache int 清除页面缓存、脏数据、inodes,分三级
1 清页面缓存
2 脏数据、inodes
3 页面缓存、脏数据、inodes
缓存的保存位置、分层结构:
- 用户层: 浏览器DNS缓存、应用程序DNS缓存、操作系统DNS缓存客户端
- 代理层: CND、反向代理缓存
- Web层: 解释器Opcache、Web服务器缓存
- 应用层: 静态页面
- 数据层: 分布式缓存、数据库
- 物理层: 磁盘cache、raid cache
cache的特性:
- 自动过期:给缓存的数据加上有效时间,超出时间后自动过期删除
- 过期时间:强制过期,源网站更新图片后CDN是不会更新的,需要强制是图片缓存过期
- 命中率:即缓存的读取命中率
用户层缓存:
DNS缓存:
查看客户端的dns缓存
chrome://net-internals/#dns 谷歌浏览器查看本地缓存
about:cache 火狐浏览器查看本地缓存
前端技术: dns-prefetch
基于html5的新特性,在html文件中提前把可能访问的域名做dns解析,例如: 京东的网页源码中有:
<link rel="dns-prefetch" href="//static.360buyimg.com"/>
浏览器缓存过期机制:
以上两种都需要发送请求,即不管资源是否过期都要发送请求进行协商,这样会消耗不必要的时间,因此有了缓存的过期时间,即第一次请求资源的时候带一个资源的过期时间,默认为30天,当前这种方式使用的比表较多,但是无法保证客户的时间都是准确并且一致的,因此会加入一个最大生存周期,使用用户本地的时间计算缓存数据是否超过多少天,下面的过期时间为2027年,但是缓存的最大生存周期计算为天等于3650天即10年
响应报文字段记录:
cache-control 秒为单位
expries 有效期
混合使用和缓存刷新:
通常last-modified、etag、expires是一起使用的
- last-modified和expries时,因为expires可以让浏览器完全部发起http请求,但浏览器强制刷新(F5)后,last-modified时间又更新了,可以避免服务端更新而客户端不知道的情况
- etag和expries时,先判断expries,如果已经过期,再次发起http请求。如果etag过期,则返回200响应码,没有过期则是304
- 三个一起时,先判断expries,再发起http请求,服务器判断last-modified,再判断etag,必须都没有过期才返回304
缓存刷新:
- 第一次访问200
- 鼠标点击页面,访问cache
- 按F5刷新304
- crtl+F5强制刷新200
- 地址栏输入访问,浏览器对本地所有没有过期的内容直接使用
- F5或刷新,会向服务器发送请求缓存协商信息,last-modified、etag有影响,但expries本地过期时间不受影响
- crtl+F5强制刷新,所有缓存不在使用,请求源网站内容
代理层缓存:
CDN缓存:
作用:
- 第一:降低机房的使用带宽,因为很多资源通过CDN就直接返回用户了
- 第二:解决不同运营商之间的互联,因为可以让联通的网络访问联通让电信的网络访问电信,起到加速用户访问的目的
- 第三:解决用户访问的地域问题,就近返回用户资源
优势:
- 调度准确-将用户调度到最近的边缘节点
- 性能优化-CDN 专门用于缓存响应速度快
- 安全相关-抵御攻击
- 节省带宽:由于用户请求由边缘节点响应,因此大幅降低到源站带宽。
分层缓存:
根据数据的访问热度,进行不同级别缓存,如:访问最多的资源放于内存中,其次防御SSD或SATA,最后再是云存储
腾讯云的CDN节点:根据数据冷热不同,动态识别
- 访问率40%~90%的数据,首先放在OC节点内存cache中,提供8~64G的数据空间存储
- 访问率30%~50%的数据,放在OC节点的SSD/SATA硬盘cache中,提供1~15T的数据空间存储
- 其他数据放在云存储中,采用回源拉取的方式进行处理
应用层缓存:
Nginx、PHP等web服务可以设置应用缓存以加速响应用户请求
解释性语言比如PHP/Python/Java不能直接运行,需要先编译成字节码,但字节码需要解释器解释为机器码之后才能执行,因此字节码也是一种缓存,有时候会出现程序代码上线后字节码没有更新的现象
数据层缓存:
分布式缓存服务:
- redis
- memcache
数据库:
- mysql查询缓存
- innodb缓存、myisam缓存
硬件缓存:
- CPU缓存(L1的数据缓存和L1的指令缓存)、二级缓存、三级缓存
- 硬盘缓存
- 磁盘阵列缓存: raid cache可使用电池防止断电丢失数据
缓存考虑的相关问题
说实话。我们这干运维的了解就好,实际这些还是看开发怎么写代码
博主以redis举例,在设置一个key时,是可以指定key的有效期的:
set key value [expiration EX seconds | PX milliseconds] [NX | XX]
缓存穿透:
- 访问一个缓存和数据库都不存在的 key,此时会直接打到数据库上,并且查不到数据,没法写缓存,所以下一次同样会打到数据库上
- 此时,缓存起不到作用,请求每次都会走到数据库,流量大时数据库可能会被打挂。此时缓存就好像被“穿透”了一样,起不到任何作用
缓存击穿
- 某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库
解决方案:
- 加互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存
缓存雪崩
- 大量的热点 key 设置了相同的过期时间,导在缓存在同一时刻全部失效,造成瞬时数据库请求量大、压力骤增,引起雪崩,甚至导致数据库被打挂
- 缓存雪崩其实有点像“升级版的缓存击穿”,缓存击穿是一个热点 key,缓存雪崩是一组热点 key
解决方案:
-
过期时间打散。既然是大量缓存集中失效,那最容易想到就是让他们不集中生效。可以给缓存的过期时间时加上一个随机值时间,使得每个 key 的过期时间分布开来,不会集中在同一时刻失效
-
热点数据不过期。该方式和缓存击穿一样,也是要着重考虑刷新的时间间隔和数据异常如何处理的情况
-
加互斥锁。该方式和缓存击穿一样,按 key 维度加锁,对于同一个 key,只允许一个线程去计算,其他线程原地阻塞等待第一个线程的计算结果,然后直接走缓存即可

浙公网安备 33010602011771号