6.1 Varnish缓存

分布式缓存


  • 缓存概念

缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题。提供高性能的数据快速访问。

WebCache web 缓存,是一种缓存技术,用于临时存储(缓存)的网页文件,如 HTML 页面和图像等静态资源(此处不绝对,也可以缓存动态页面,但是存储到本地后也为静态文件),减少带宽以及后端服务器的压力,通常一个 WebCache 也是一个反向代理软件,既可以通过缓存响应用户的请求,当本地没有缓存时,可以代理用户请求至后端主机。

缓存的原理

  1. 将数据写入/读取速度更快的存储(设备)
  2. 将数据缓存到离应用最近的位置
  3. 将数据缓存到离用户最近的位置

缓存的类型

CDN缓存
CDN主要解决将数据缓存到离用户最近的位置,一般缓存静态资源文件(页面,脚本,图片,视频,文件等)。国内网络异常复杂,跨运营商的网络访问会很慢。为了解决跨运营商或各地用户访问问题,可以在重要的城市,部署CDN应用。使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。

反向代理缓存
反向代理是指在网站服务器机房部署代理服务器,实现负载均衡,数据缓存,安全控制等功能。

分布式Cache
分布式缓存,主要指缓存用户经常访问数据的缓存,数据源为数据库。一般起到热点数据访问和减轻数据库压力的作用。

本地应用缓存
本地缓存是指应用内部的缓存,标准的分布式系统,一般有多级缓存构成。本地缓存是离应用最近的缓存,一般可以将数据缓存到硬盘或内存。

  • 代理缓存

6.1 Varnish缓存_第1张图片

与 Redis 或者 Memcached 不同,代理缓存通常运行在代理服务器上,而前者则旁挂在后端服务器外侧,为后端服务器提供数据缓存。

缓存有效性验证机制

    如果原始内容未发生改变,则仅响应首部(不附带body部分),响应码304(Not Modified)
    如果原始内容发生改变,则正常响应,响应码200
    如果原始内容消失,则响应404,此时缓存中的cache object应被删除

代理缓存HTTP报文

6.1 Varnish缓存_第2张图片

Cache-Control:针对上述的“Expires时间是相对服务器而言,无法保证和客户端时间统一”的问题,http1.1新增了 Cache-Control 来定义缓存过期时间。注意:若报文中同时出现了 Expires 和 Cache-Control,则以 Cache-Control 为准。

    语法:"Cache-Control" ":" cache-directive

当该字段值为no-cache的时候,会知会客户端不要对该资源读缓存,即每次都得向服务器发一次请求才行。Cache-Control也是一个通用首部字段,这意味着它能分别在请求报文和响应报文中使用。
也就是说优先级从高到低分别是 Pragma -> Cache-Control -> Expires 。

6.1 Varnish缓存_第3张图片

Pragma:设置页面是否缓存,为Pragma则缓存,no-cache则不缓存

If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match(Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。

If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头 If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。

Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器觉得)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。

Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。

Expires:有了Pragma来禁用缓存,自然也需要有个东西来启用缓存和定义缓存时间,对 http1.0 而言,Expires 就是做这件事的首部字段。 Expires的值对应一个 GMT(格林尼治时间),如果还没过该时间点则不发请求。

6.1 Varnish缓存_第4张图片

Varnish


  • Varnish构架

6.1 Varnish缓存_第5张图片

Management

Management进程主要实现应用新的配置、编译VCL、监控varnish、初始化varnish以及提供一个命令行接口等。 Management进程会每隔几秒钟探测一下Child进程以判断其是否正常运行,如果在指定的时长内未得到Child进程的回 应,Management将会重启此Child进程
varnishadm 命令行接口,目前 vagent 2 为收费接口,而 telnet 是纯文本传输,所以只能使用varnishadm.Varnish 服务运行时监听在两个套接字上,一个监听前端发送来的请求(tcp:6081),另一个监听管理接口的管理命令(tcp:6082)

Child/Cache Process

Acceptor:接收新的连接请求
Worker:用于处理并响应用户请求
Expiry:从缓存中清理过期cache object

Shared Memory Log

shared memory log,共享内容日志方式存储,一般其大小为90MB,分为两部分:前一部分为计数器、后一部分为客户请求相关的数据
可以使用 varnishlog 将日志文件从内存提取到磁盘当中保存

VCL(Varnish Configuration Language)

VCL 是 varnish 配置缓存策略的工具,它是一种基于“域”(domain specific)的简单编程语言,它支持有限的算术运算和逻辑运算操作、允许使用正则表达式进行字符串匹配、允许用户使用set自定义变量、支持if判 断语句,也有内置的函数和变量等。使用VCL编写的缓存策略通常保存至.vcl文件中,其需要编译成二进制的格式后才能由varnish调用。事实上,整 个缓存策略就是由几个特定的子例程如vcl_recv、vcl_fetch等组成,它们分别在不同的位置(或时间)执行,如果没有事先为某个位置自定义子 例程,varnish将会执行默认的定义。

VCL策略在启用前,会由management进程将其转换为C代码,而后再由gcc编译器将C代码编译成二进制程序。编译完成后,management负责将其连接至varnish实例,即child进程。正是由于编译工作在child进程之外完成,它避免了装载错误格式 VCL 的风险。因此,varnish修改配置的开销非常小,其可以同时保有几份尚在引用的旧版本配置,也能够让新的配置即刻生效。编译后的旧版本配置通常在 varnish重启时才会被丢弃,如果需要手动清理,则可以使用 varnishadm 的 vcl.discard 命令完成。

varnish缓存功能有如下优点

  1. 是基于内存缓存,重启后数据将消失;
  2. 利用虚拟内存方式,IO性能好。
  3. 支持设置0~60秒内的精确缓存时间。
  4. VCL配置管理比较灵活
  5. 32位机器上缓存文件大小最大为2G
  6. 具有强大的管理功能,例如top、stat、admin、list等。
  7. 状态机设计巧妙,结构清晰
  8. 利用二叉堆管理缓存文件,达到积极删除目的
  • Varnish工作原理

6.1 Varnish缓存_第6张图片

上图是 Varnish 官方站点提供的 varnish 工作流程图。大致总结一下可以理解为以下四种常见情况

6.1 Varnish缓存_第7张图片

还有两种引擎图中没有 vcl_init 与 vcl_finish 分别负责
    在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs
    所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs

  • varnish命令

varnishd

程序选项:
    -a address[:port][,address[:port][...],默认为6081端口; 
    -T address[:port],默认为6082端口;
    -s [name=]type[,options],定义缓存存储机制;
    -u user
    -g group
    -f config:VCL配置文件;
    -F:运行于前台

varnishadm

    语法:varnishadm -S 秘钥文件 -T IP地址:端口 [-t 超时时长] [-n 缓存名称]

配置文件相关:
    vcl.list  列出vcl配置列表
    vcl.load  装载,加载并编译
    vcl.use  激活
    vcl.discard  删除
    vcl.show [-v]   查看指定的配置文件的详细信息

运行时参数:
    param.show -l:显示列表;
    param.show
    param.set

缓存存储:
    storage.list

后端服务器:
    backend.list 

Varnish运行时参数

在线程池内部,其每一个请求由一个线程来处理; 其worker线程的最大数决定了varnish的并发响应能力

thread_pools:线程数,最好小于或等于CPU核心数量; 
thread_pool_max: 每线程池的最大线程数;
thread_pool_min:额外意义为“最大空闲线程数”;

设置方式:

    vcl.param 
    param.set

永久有效的方法:

保存在 varnish.params 中
    语法:DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE"

  • Varnish日志

varnishstat

varnishstat 工具用于显示 Varnish 缓存的状态信息

选项:

    -1  一次显示所有状态信息
    -f  查看指定字段名称列表

[root@CentOS74 ~]# varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss
MAIN.cache_hit              52         0.01 Cache hits
MAIN.cache_miss             75         0.01 Cache misses

varnishtop

varnishtop 工具用于显示 Varnish 的缓存使用排名

选项:

    -1   一次显示所有状态信息
    -i taglist  可以同时使用多个-i选项,也可以一个选项跟上多个标签;
    -I <[taglist:]regex>  对指定的标签的值基于regex进行过滤; 
    -x taglist  排除列表
    -X  <[taglist:]regex>  对指定的标签的值基于regex进行过滤,符合条件的予以排除;

varnishlog

varnishlog 工具用于显示 Varnish 的日志信息

varnishncsa

varnishncsa 工具用于显示 combined 格式的 Varnish 的日志信息

  • 日志的持久化

varnishlog 和 varnishncsa 都能够以守护进程的方式运行在后台

[root@CentOS74 ~]# cat /usr/lib/systemd/system/varnishncsa.service /usr/lib/systemd/system/varnishlog.service
[Unit]
Description=Varnish Cache HTTP accelerator NCSA logging daemon
After=varnish.service

[Service]
RuntimeDirectory=varnishncsa
Type=forking
PIDFile=/run/varnishncsa/varnishncsa.pid
User=varnish
Group=varnish
ExecStart=/usr/bin/varnishncsa -a -w /var/log/varnish/varnishncsa.log -D -P /run/varnishncsa/varnishncsa.pid  #可以修改日志保存的路径
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target
[Unit]
Description=Varnish Cache HTTP accelerator logging daemon
After=varnish.service

[Service]
RuntimeDirectory=varnishlog
Type=forking
PIDFile=/run/varnishlog/varnishlog.pid
User=varnish
Group=varnish
ExecStart=/usr/bin/varnishlog -a -w /var/log/varnish/varnish.log -D -P /run/varnishlog/varnishlog.pid   #可以定义日志保存的路径
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

 

 

你可能感兴趣的:(网站构架)