缓存技术及相关概念

缓存技术

系统缓存:

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可使用电池防止断电丢失数据

缓存考虑的相关问题

说实话。我们这干运维的了解就好,实际这些还是看开发怎么写代码image
博主以redis举例,在设置一个key时,是可以指定key的有效期的:

set key value [expiration EX seconds | PX milliseconds] [NX | XX]

缓存穿透:

  • 访问一个缓存和数据库都不存在的 key,此时会直接打到数据库上,并且查不到数据,没法写缓存,所以下一次同样会打到数据库上
  • 此时,缓存起不到作用,请求每次都会走到数据库,流量大时数据库可能会被打挂。此时缓存就好像被“穿透”了一样,起不到任何作用

缓存击穿

  • 某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库
解决方案:
  • 加互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存

缓存雪崩

  • 大量的热点 key 设置了相同的过期时间,导在缓存在同一时刻全部失效,造成瞬时数据库请求量大、压力骤增,引起雪崩,甚至导致数据库被打挂
  • 缓存雪崩其实有点像“升级版的缓存击穿”,缓存击穿是一个热点 key,缓存雪崩是一组热点 key
解决方案:
  1. 过期时间打散。既然是大量缓存集中失效,那最容易想到就是让他们不集中生效。可以给缓存的过期时间时加上一个随机值时间,使得每个 key 的过期时间分布开来,不会集中在同一时刻失效

  2. 热点数据不过期。该方式和缓存击穿一样,也是要着重考虑刷新的时间间隔和数据异常如何处理的情况

  3. 加互斥锁。该方式和缓存击穿一样,按 key 维度加锁,对于同一个 key,只允许一个线程去计算,其他线程原地阻塞等待第一个线程的计算结果,然后直接走缓存即可

posted @ 2022-02-14 17:03  suyanhj  阅读(250)  评论(0)    收藏  举报