江湖人称赵班长,曾在武警某部负责指挥自动化的架构和运维工作,2008年退役后一直从事互联网运维工作。曾带团队负责国内某电商的运维工作,《saltstack入门与实践》作者,某学院高级讲师。
学技术一定要成体系,这是我个人的学习目标,也就是在一个特定的范围内,把与此相关的技术都尽量的搞清楚、搞明白。
我把与Web缓存相关的内容从我编写的《Web运维知识体系》(链接1)中拿了出来,进行完善后,形成了一个单独的《Web缓存知识体系》(链接2),分享给大家,仅供参考。
链接1 : https://www.unixhot.com/page/ops
链接 2 : https://www.unixhot.com/page/cache
在Web架构中,我们经常会听到分级或者分层这个词,这就是架构中比较重要的一个理念:分层设计(分级设计)。
那么对于一个Web站点来说,从一个HTTP请求产生到服务器返回数据,会经过非常多不同层次的缓存,我整理了一个“相对”完善的Web缓存分层体系。
本体系从全局七个层面列举了各个层面涉及到的缓存技术和方法,此体系结构仅包含读缓存(Cache),不包含写缓冲(Buffer),所以很多缓冲区没有列举,请见谅。
由于缓存分级体系的内容比较多,很难在微信文章中深入阐述,那么我们下面来聊聊大家最熟悉,也是经常讨论的Buffer与Cache。
什么是Buffer?什么是Cache?我相信这个也是困扰很多初学者很久的问题。而且很多时候我们把一个区域会叫做Buffer Cache,就让大家更懵了,到底是Buffer还是Cache。
首先从字面上理解Buffer指的是缓冲、Cache指的是缓存。我个人的总结是:
我们先来说说Cache(缓存),这个是我们最容易理解的。Cache是为了提高数据的读取速度。
比如我们把经常用的数据从远处读取到一个离自己最近最快的缓存区后,这样再次使用这个数据,就可以直接从离自己最近最快的这个缓存区读取,这显然提高了性能。
这里我们拿CPU来举例说明,作为运维工程师我相信大家都知道CPU读取文件是要从内存来读取的,而且CPU的速度是远远高于内存的,那么如果每次CPU都从内存来读取显然是比较慢的。
于是CPU现在增加了缓存,一般服务器的CPU都支持三级缓存:
L1 Cache
L2 Cache
L3 Cache
CPU Cache是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多,CPU Cache中保存着CPU刚用过或循环使用的一部分数据。
当CPU再次使用该部分数据时可从Cache中直接调用,而不用去读取内存,这样就减少了CPU的等待时间,提高了系统的效率。
所以我们在实际的运维的一些场景中(例如KVM调优)也会使用taskset命令来将进程绑定到一个固定的CPU上,其实就是为了降低CPU的Cache Miss,从而提高性能。
我们理解了Cache,再来说说Buffer。目前Buffer和Cache之间是争议还是比较多的,主要是概念上。我准备拿生活中的一个例子来解释Buffer。
目前在中国,汽车的普及率很高,很多的朋友都有驾照,所以对于交规应该都很熟悉。我们先放下技术来做一个交规考试:
看下面这个图,请回答下图中白色虚线的区域叫做什么?
答案:这个白色的区域叫做左转弯待转区,我们先放下技术,来复习一下交规,保证大家上路行驶的安全性。
左转弯的车道增加了数米长的白色虚线框,直接连接到了马路中间。
这些白色虚框线就是设置的“左转弯待转区”,供同向直行道绿灯亮起时,左转弯车道的车辆越过停止线,提前进入这个区域等待转弯,等到左转弯信号灯变成绿色时再通过路口。
此举将有效地提高路口机动车通过量,减少车辆滞留,也就是让车辆更快的转弯。从图中我们可以看到这个待转区是一个弯曲的,离转弯的目的地更近。
这个左转弯待转区其实就是我们要讨论的Buffer(缓冲区)的一个生活例子。
这个待转区这就是一个缓冲区,这个缓冲区可以让我们把车辆停到离目的地更近的一个地方。就像我们把数据写到一个离目的更近的地方一样。
Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。
这次我们拿内存和磁盘来举例,刚才我们说了CPU速度比内存的速度要快很多,那么拿内存和硬盘相比呢?
内存的速度要比硬盘的速度快非常多。但是我们知道内存是易失性的存储,我们持久化的数据最终要保存到硬盘上。
但是硬盘又那么的慢,CPU要是等待数据完全写到硬盘上,那显然是不现实的。
所以就拿我们的Linux系统来说,会在内存设置一个缓冲区叫做“ 磁盘缓冲区 ”,更准确点称之为“内存的磁盘缓冲区”。
CPU把数据写入到“内存的磁盘缓冲区”之后就认为自己写完,然后转去做别的事情,而不用等数据最终写到硬盘。
然后linux有一个内核线程叫做pdflush,用来把缓存区的“相关”数据写入到磁盘。这显然提升了CPU处理的速度。当然这其中还有很多的奥秘,有兴趣的朋友可以深入研究。
回顾起我曾经对于Buffer和Cache的探索经历,大家读到这里,肯定心中还有很多疑惑,那么内存到底是Cache还是Buffer呢?
答案:又是Cache又是Buffer,因为它确实同时担任着两个角色的功能,所以我们经常把这些即担任的Cache角色又担任Buffer角色的称之为: Buffer Cache 。
当然也有别的称谓,我们不要太纠结,最简单的是我们能够按照他们的作用来区分。
好的,以后别人再问你什么是Buffer?什么是Cache的时候,你可以自信的回答:
首先Cache和Buffer解决的都是速度不一致有关的问题,他们都有一块存储区域。
但是:
注意:在很多时候我们把Buffer和Cache的名字混着用。也有统一叫做Cache的。
我们这次主要是关注在Web架构中,各个层级的Cache,即便有些层级不仅仅是Cache的功能还有Buffer的功能。那么既然使用Cache,我们就需要关注Cache几个特别重要的指标。
对于我们Web架构中的缓存存放可以分为三种位置:
很明显存储在用户浏览器中的速度最快,其次是Web服务器的内存中,最后是硬盘中。
内存快,但是毕竟价格贵、空间有限,所以我们也可以通过网络将数据写入到其它服务器的内存中,例如Memcached和Redis。
硬盘慢,但是价格低、空间相对充足。所以在设计缓存的时候经常会遇到分级设置,就像CPU的三级缓存。同时我们也可以将数据通过网络写入到其它服务器的硬盘中,例如NFS。
Cache既然是一个区域,那么这个区域的存储空间肯定是有限的,所有的缓存肯定有一个过期时间,不能一直存放。
在不同的层次,可以使用不同的方法设置缓存的过期时间
既然Cache有过期时间,那么在没有到达过期时间,我们又想让Cache马上过期,怎么办?
这个也是我们在使用和设计Cache的时候需要关注的问题,如何在源数据发生变化以后,让缓存强制过期。
缓存最重要的指标就是命中率了!也就是每次缓存查找的时候是否能在缓存区域,找到已经被缓存的内容。
我们可以想象如果加入了Cache层,命中率很低,先不说我们要在管理Cache增加的工作量,数据读写路径多了一层,理论上就会影响性能。
所以说一个完全没有命中率的缓存除了“极特殊”的需求外是不应该存在的。
最后,留下一个缓存相关的面试题:我们日常手机上使用的云服务,例如云通讯录、云短信、云图片(也就是可以同步你的通讯录、短信和图片到云上)需要使用CDN吗?
也许,你和我有一样的习惯就是每天在上下班途中阅读各类技术公众号,那么,我建议对于别人的分享,要善于总结和沉淀,只有这样才能成为自己的知识。
在此,感谢高效运维社区给我们提供了一个学习和交流的平台。