Fork me on GitHub

Varnish介绍

是什么

  Varnish:缓存反向代理服务器。它是一款高性能且 开源 的反向代理服务器,具有高性能、速度块、管理方便等优点。
  例如:客户机要在成都访问sina,sina的服务器在北京,由于距离较远,访问速度很慢,这时为了解决此问题我们可以使用Varnish。它相当于客户机访问Varnish,Varnish在Cache池里看有没有sina的页面数据,如果有就直接返回给客户;如果没有Varnish会请求sina服务器,sina服务器把页面数据返回给Varnish,Varnish把页面数据传给客户机,并且把此数据存储到自己的Cache池里,下次其它客户机来访问相同页面时会直接把该数据返回给客户机。

  在nginx的基础上使用Varnish缓存来实现动静分离。
  
  Varnish的 核心功能: 能将后端web服务器返回的结果缓存起来,如果发现后续有相同的请求,Varnish将不会将这个请求转发到web服务器,而是返回缓存中的结果。这将有效的降低web服务器的负载,提升响应速度,并且每秒可以响应更多的请求。
  Varnish速度很快的另一个主要原因是其 缓存全部都是放在内存里的,这比放在磁盘上要快的多。诸如此类的优化措施使得Varnish的相应速度超乎想象。但考虑到实际的系统中内存一般是有限的,所以需要手工配置一下缓存的空间限额,同时避免缓存重复的内容。

缓存原理

  Varnish是按照访问的URL来进行缓存, 默认只缓存GET请求和HEAD请求
  varnish架构图:
  
  Varnish主要运行两个进程:Management进程和Child进程(也叫Cache进程)。
  management进程主要负责提供命令行接口、编译vcl,健康状态检测child子进程是否存活及其监控varnish,Management进程会每隔几秒钟探测
一下Child进程以判断其是否正常运行,如果在指定的时长内未得到Child进程的回应,Management将会重启此Child进程。
  而child子进程负责工作线程,生成缓存日志,查看缓存是否过期等一系列工作。

  vcl(varnish configuraltion languages):varnish域专用配置语言,是基于状态引擎,转台之间存在着相关性,但彼此之间相互隔离,每个引擎使用return来退出当前状态并进入下一个状态,不同的状态的引擎是不尽相同。
  vcl处理流程图:
  

请求流程

  请求分为为可缓存和不可缓存,当请求可缓存时,是否命中,命中则从本地缓存响应,未命中则到达后端主机取得相应的结果,公共缓存则可缓存,缓存一份到缓存后再次响应给客服端,如私有数据则不可缓存直接响应即可。
  Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。
  接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。
  分配缓存 的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据 LRU 机制,把最旧的 object 释放掉。
  释放缓存 的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。
  整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。

如何衡量缓存系统的优劣性

缓存命中率:

  在memcached服务器中,get_hits的值表示缓存命中的次数,get_misses的值表示没有命中的次数,那么命中率的计算公式就是:命中率=get_hits/(get_hits+get_misses)
  终端用户访问加速节点时,如果该节点有缓存住了要被访问的数据时就叫做命中,如果没有的话需要到原服务器取,就是没有命中。取数据的过程与用户访问是同步进行的,所以即使是重新取的新数据,用户也不会感觉到有延时。 命中率=命中数/(命中数+没有命中数), 缓存命中率是判断加速效果好坏的重要因素之一

命中率有两种衡量指标

  文档命中率:从命中的文档数量角度来衡量
  字节命中率:从命中的字节大小角度来衡量

应该让哪些资源被缓存

  1:静态资源中的 公共资源缓存
  2:静态资源中的 私有资源不缓存
  3:动态资源中的 公共资源缓存
  4:动态资源中的 私有资源不缓存

varnish对外监听web请求的端口,可是为什么是6081,而不是80 端口呢?

  配置文件中有一个监听端口,VARNISH_LISTEN_PORT=6081,之所以没有用80端口,是 因为varnish作为缓存服务器,常常是放在nginx反代的后面,这样不面对互联网,因此就不需要监听在80端口了

如何清缓存

  varnish4清缓存方法主要有,
  1.通过varnishadm 管理
  2.vcl配置。vcl配置可以让客户端手动请求清楚缓存(修改请求类型为PURGE),以保证局部数据及时更新,而不用重启varnish服务器。varnish4配置手动清除缓存

什么是动静分离

  动静分离是一种架构,就是把静态文件,比如JS、CSS、图片甚至有些静态页面交给独立的服务器集群处理,从而进行分流,使服务器降低压力。
  上面说把一些静态的文件分离出去,有读者就会笑了,静态文件能有多少,能消耗多少资源。
  读者以实际经验告诉大家,千万不要小瞧这些静态文件,现在大部分网站都是以视频、图片为主,试想下天猫、淘宝、京东之类,文字能有多少,图片、视频又是多少,就知道这个量到底是多么的庞大,而动静分离从笔者公司实际使用经验来看,效果是杠杠的。


参考文章:
  varnish入门理解
  nginx反代varnish缓存服务器实现后端amp动静分离架构
  Varnish缓存实现动静分离
  varnish缓存配置详解

-----------------本文结束,感谢您的阅读-----------------