缓存服务器之memcached和varnish
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存服务器之memcached和varnish相关的知识,希望对你有一定的参考价值。
两类缓存服务器:
1.代理式缓存服务器;proxy-like cache server;
2.旁挂式缓存服务器;bypass cache server;
缓存服务器也可以根据缓存数据内容分类:
1.数据缓存;data cache
2.页面缓存;page cache
数据存在访问热区,指被经常访问的数据。
缓存的实质是:用空间换时间;
缓存的局部性特征:空间局部性和时间局部性:
缓存的时效性:
过期清理:PURGE,修剪;
未过期但溢出清理:LRU(最少使用原则);
未过期但被修改:PURGE,修剪;
缓存命中率:Hits/(Hits + Miss) ,取值范围区间是(0,1),通常也会用百分数进行表示;
页面命中率:基于命中的页面数量进行统计衡量的一种标准;
字节命中率:基于命中的页面的体积进行统计衡量的一种标准;(更为精确)
数据缓存与否:
1.私有数据:private data,放置于私有缓存中;
http/1.1版本后的首部中,提供了一个Cach-Control的首部;Cache-Control首部的值中包含有private字样,或者提供了Cookie或者Cookie2的首部;此类数据大多数都是由浏览器完成缓存;
2.公共数据:public data,可以放置于公共缓存,也可以放置于私有缓存中;
此类数据大多数缓存在反代服务器上或者专用的Cache Server上;
小部分也可以缓存在浏览器上;
注意:
浏览器的缓存(一般是私有缓存):
仅针对于单独的用户生效,使用户重复访问某资源时能够加速访问;
缓存服务器的缓存(一般是公共缓存):
为前端调度器或反代服务器加速资源访问,降低后端资源服务器的访问压力;
对于缓存服务器来说,缓存的处理步骤(大致成功的处理步骤):
接收请求 --> 解析请求(从请求报文的http协议首部中提取URL及其他相关的首部信息) --> 查询缓存 --> 缓存数据的新鲜度检测 --> 构建响应报文 --> 发送响应报文--> 记录日志
缓存数据的有效性判断机制:
1.过期时间:
HTTP/1.0:
Expires,绝对时间;
HTTP/1.1:
1.Expires
2.Cache-Control(首部):max-age=86400
3.Cache-Control:s-maxage=10000 (s代表公共缓存)
2.条件式请求:
Last-Modified/If-Modified-Since :响应报文/请求报文的条件请求
Etag/If-None-Match :扩展标签,对标签进行哈希计算;If-None-Match:如果不匹配,返回200代表不匹配
示例:查看百度的logo资源:
Cache-Control max-age=2592000 //缓存资源的最大有效时间
ETag "593645fd-664" //得到的16进制的哈希值
Expires Wed, 11 Jul 2018 03:43:28 GMT //过期时间
Last-Modified Tue, 06 Jun 2017 06:04:45 GMT //自 06 Jun 2017 06:04:45 GMT这个时间点开始资源无变化(GMT:格林尼治时间)
一、memcached缓存服务器:
属于旁挂式缓存服务器,也属于数据缓存;
memcached存储形式:
1.将所有数据采用键值对儿的形式存储于内存当中;
2.无持久存储功能;
3.通常用于缓存小文件,小数据,单项缓存数据内容上限是1MB;
memcached由LiveJournal公司旗下的子公司Danga Interactive研发者Brad Fitzpatrick研发;
memcached特性:
1.k/v cache;可序列化数据,扁平化数据; //常见的还有JSON,也是序列化数据
2.存储项:key(键), value(值), flag(16位二进制数字,0-65535), expire_time(超时时间), length(保存数据的长度)等简单部分组成;
3.旁挂式缓存,功能实现一半依赖于客户端,另一半靠memcached server;
4.O(1)的查找和执行效率;
5.可以构建分布式缓存系统,各服务器之间互不通信的分布式集群系统;
6.缓存数据的处理方式(较为特殊):
1)缓存空间耗尽:根据LRU(最近最少使用算法)完成清理过期数据;
2)缓存项过期:惰性清理机制---用来尽可能减少内存碎片
7.内存分配方式:
slab allocation:按照页面进行打散,将打散的页面分成若干个更小的页面,最大1M
facter:增长因子;默认1.25倍递增;小页面根据增长因子来分配空间大小,最后会留下一个最大不超过1M的空间。
安装配置memcached:
1.base源中有对应的rpm包;可以直接使用yum方式安装内容;
~]# yum install memcached -y
2.从memcached.org官方站点下载源代码包,编译安装;
memcached缓存服务监听的端口:
11211/TCP, 11211/UDP;
memcached缓存服务程序安装后的默认环境:
主程序:/usr/bin/memcached
环境配置文件:/etc/sysconfig/memcached
~]# cat /etc/sysconfig/memcached
PORT="11211" //监听的端口号
USER="memcached" //程序属于哪个用户
MAXCONN="1024" //服务的最大连接数
CACHESIZE="64" //缓存大小默认为64
OPTIONS="" //其他选项默认为空
memcached缓存服务使用的协议是memcached协议,memcached协议支持的数据传输格式是:
1.文件格式
2.二进制格式
交互式操作(~]# telnet+载有memcached服务主机的IP地址+端口号(默认是11211),使用telnet命令进入交互式操作模式):
命令:
1.统计类:stats, stats items(缓存项查看), stats slabs(内存空间的查看), stats sizes
2.管理类:set(修改特定键的值), add(添加一个新的键), replace(替换原有键的值), append(在原有键值后附加一个值), prepend(在原有键值前附加一个值), delete(删除键), incr(给键添加值), decr(给键删除值), flush_all(清空所有键)
3.查看类:get
memcached交互式命令的一般格式:
<command> key_name [flags] [expire_time] [length_bytes]
key_name:键名
[flags]:标志位,范围是0-65535
[expire_time]:键最大缓存时间(秒)
[length_bytes]:字符长度
例:
添加一个新键:
add testkey 0 300 11
hello world
STORED
查看新键:
get testkey
VALUE testkey 0 11
hello world
END
在新键后添加字符并查看:
添加:
append testkey 0 300 2
hi
STORED
查看:
get testkey
VALUE testkey 0 13
hello worldhi
END
在新键前添加字符并查看:
添加:
prepend testkey 0 300 3
hi
STORED
查看:
get testkey
VALUE testkey 0 14
hi hello world
END
memcached命令选项:
-c num :指名并发连接数量,默认是1024
-m num :分配多大的内存空间,默认是64M
-u username :指定哪个用户启动memcached服务进程
-p port :指定端口号,默认是11211
-U port :指定UDP协议的端口号,默认是11211,0是关闭
-l ipaddress :监听哪一个地址,默认是所有
-f facter :指明增长因子,默认是1.25倍
-t thread_num :设置线程数,默认是4个线程
-v,-vv,-vvv :显示的详细信息程度
二、VARNISH缓存服务器:
varnish缓存服务器是属于页面缓存服务器的一种,用来为客户端请求提供查询结果,也属于代理式缓存服务器。
varnish缓存服务器特点:
varnish缓存服务器可以实现的功能:反向代理 + 缓存服务器
varnish缓存服务器默认在内存中占用128M内存空间去进行缓存服务
缓存服务器的实现:
开源解决方案:
squid:上世纪90年代中期出现;使用率较低
varnish:反向代理式缓存:使用率较高的缓存服务器实现方案;
https://www.varnish-software.com/ //商业版本服务站点
http://varnish-cache.org/ //开源站点
varnish程序的组织结构:
1.Management进程:
1)varnish的主进程;
2)提供命令行工具的访问接口,用来管理子进程,初始化缓存;
2.Child/Cache进程:拥有多种线程模型,如下:
command line
storage/hashing
log/stats
accept
worker threads
object expiry
backend communication
...
3.VCL compiler:C compiler(gcc)
varnish的线程池作用:
统计数据:数据统计和计数器;
日志区域:日志数据;
VCL文件的处理方式:
vcl compiler (vcl编译器编译完成)--> C compiler (再到C的编译器中编译处理)--> shared object
vcl配置文件的重载工具:
/usr/sbin/varnish_reload_vcl
VCL:Varnish Configuration Language,varnish配置语言;
统一存放于后缀名为".vcl"的文件中,在初次安装了varnish之后,在配置主目录中会自动创建出一个名为"default.vcl"的文件,但其内容几乎为空;
varnish的安装:
在EPEL源中直接提供了varnish的稳定版本;
安装命令:yum install -y varnish (需先配置EPEL源)
varnish的程序环境:
1.配置文件:
/etc/varnish/default.vcl
定义缓存策略的默认配置文件,主要用于配置各Child/Cache线程的工作属性;
/etc/varnish/varnish.params
定义varnish缓存服务的运行时参数以及工作特性;
/etc/varnish/secret
在使用varnishadm命令行管理工具时,为了安全起见使用的预共享密钥;
2.主程序: /usr/sbin/varnishd
1)CLI(简单的命令行接口管理工具):
/usr/bin/varnishadm
2)Share Memory Log交互工具:
/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishncsa
/usr/bin/varnishstat
/usr/bin/varnishtop
开启varnish日志记录(默认没有开启):
1./usr/bin/varnishlog
2./usr/bin/varnishncsa(建议在需要开启日志记录的时候开启,因为其更接近于Apache的command的命令形式)
3)缓存测试工具:
/usr/bin/varnishtest
4)varnish的Unit FIle:
/usr/lib/systemd/system/varnish.service:管理varnish的Management进程;
实现日志持久化存储的服务文件;
/usr/lib/systemd/system/varnishlog.service
/usr/lib/systemd/system/varnishncsa.service
主程序:/usr/sbin/varnishd
varnishd - HTTP accelerator daemon --http加速器守护进程
常用选项:
-a address[:port][,address[:port][...]
指定用于接收客户端请求所监听的地址和服务端口,默认值为127.0.0.1:6081
-b host[:port]:添加一个backend sever的主机和端口号
-T address[:port]:实现管理的时候需要用到的地址和端口号;
-f config:
指明此次需要编译并装载的VCL配置文件,默认为/etc/varnish/default.vcl;
-p param=value
设置varnish线程模型的运行时参数和参数值;
大多数的运行时参数都有默认值,不要轻易尝试调整运行时参数的值;
在命令行工具中使用此选项调整的运行时参数的值,仅当次生效;
-r param[,param...]
将运行时参数设置为只读属性;意味着当再次运行时,其值无法被修改;
-s [name=]type[,options]:指定缓存的存储机制
定义缓存数据的存储方式,目前有三种存储机制:
1.malloc[,size]:性能最好,但是所有的数据保存在内存中;
2.file[,path[,size[,granularity]]]:只是一种黑盒文件,内容无法观察;键值对儿存放于内存当中,哈希值存放于磁盘中,保证快速检索,不会占用内存太多空间
3.persistent,path,size (experimental,体验测试版):持久存储(机制不成熟)
-T address[:port]
在指定的IP地址和端口号上提供管理接口;默认为127.0.0.1:6082;
-u user、-g group
指定允许varnish服务进程的系统用户和系统组,默认均为varnish;
运行时参数的配置文件:/etc/varnish/varnish.params
DAEMON_OPTS="-p param1=value1 -p param2=value2 ..."
thread_pool_min=5
thread_pool_max=500
thread_pool_timeout=300
命令行管理工具:varnishadm (交互式模式)
varnishadm - Control a running Varnish instance
常用选项:
-S secret_file
指定通过命令行工具实现验证时的预共享密钥文件;
-T address:port
指定管理地址和端口;
交互式模式的命令:
help [<command>] :varnishadm命令帮助
ping [<timestamp>] :做连通测试
auth <response> :做认证
quit :退出交互式模式
banner :做条幅
status :状态输出
start :启动varnish服务(不建议使用) //重启、关闭、开启都会把缓存清空,这是致命的
stop :关闭varnish服务(不建议使用)
管理vcl:
vcl.load <configname> <filename>:装载并且编译vcl文件
vcl.inline <configname> <quoted_VCLstring>:
vcl.use <configname>:激活已经编译好的vcl文件;
vcl.discard <configname>:删除已经编译好的非激活状态下的vcl配置文件;
vcl.list:vcl配置文件一共有哪些;
param.show [-l] [<param>]:列举所有运行时参数并且输出详细参数;
param.set <param> <value>:临时修改某个运行时参数的值,一次性修改,重启后恢复默认
panic.show:显示运行时参数列表或显示指定的运行时参数的详细信息;
panic.clear:清空运行时参数列表;
storage.list:显示缓存存储相关信息;
vcl.show [-v] <configname> :显示default.vcl所有配置历史更改列表,包括正在使用和使用过的;
backend.list [<backend_expression>] :后端服务器列表显示;
backend.set_health <backend_expression> <state> :设置后端服务器将康状态码;
常用的命令:
VCL配置文件管理相关:
vcl.load:装载并编译VCL配置文件;
vcl.use:激活已经编译完成的VCL配置文件;
vcl.discard:删除非激活状态下的VCL配置文件;
运行时参数相关:
param.show:显示运行时参数列表或显示指定的运行时参数的详细信息;
param.set:实时设置或修改运行时参数的值;(不要轻易尝试修改,一定要清楚操作的目的)
缓存存储相关:
storage.list:显示缓存存储相关信息;
后端服务器相关:
backend.list:显示可以直接访问的后端服务器列表;
backend.set_health:指明后端服务器的健康状态检测方式;
VCL:Varnish Configuration Language;
"域"专有类型的配置语言;
VCL中定义了多个状态引擎,各状态引擎之间存在相关性,同时又彼此隔离;每个状态引擎内都可以使用return()关键字指明各状态引擎之间的关联关系;在VCL文件中,状态引擎使用如下的方式进行定义:
sub STATE_ENGINE_NAME { ...; }
sub+状态引擎的名字+{ 配置指令1;配置指令2;... }
三个varnish状态引擎版本对比以及数据处理流程:
1.varnish 2.0-状态引擎包括:
vcl_recv:接收请求,并且判断是否可以使用缓存数据;
vcl_hash:对于从backend端取回的数据,如果可被缓存,则进行哈希计算;
vcl_hit:对于请求的资源可以在缓存对象中直接获取;
vcl_miss:对于请求的资源无法在缓存对象中直接获取;
vcl_deliver:构建响应报文;
vcl_fetch:从backend端取回数据;
varnish2.0的处理流程:
1.vcl_recv --> vcl_hash --> vcl_hit --> vcl_deliver
2.vcl_recv --> vcl_hash --> vcl_miss --> vcl_fetch --> vcl_deliver
3.vcl_recv --> vcl_fetch --> vcl_deliver (不走缓存)
2.varnish 3.0状态引擎包括:
vcl_recv:接收请求,并且判断是否可以使用缓存数据;
vcl_hash:对于从backend端取回的数据,如果可被缓存,则进行哈希计算;
vcl_hit:对于请求的资源可以在缓存对象中直接获取;
vcl_miss:对于请求的资源无法在缓存对象中直接获取;
vcl_deliver:构建响应报文;
vcl_fetch:从backend端取回数据;
较varnish2.0新增:
vcl_pass:对于本来可以从缓存中查找到资源明确的设置不使用缓存;多数用于私有缓存的查找策略;
vcl_pipe:对于无法理解的请求,直接按照原样的封装直接代理至backend端;
vcl_error:本地发生错误时,构建错误响应报文;
varnish的处理流程:
1.vcl_recv --> vcl_hash --> vcl_hit --> vcl_deliver
2.vcl_recv --> vcl_hash --> vcl_hit --> vcl_pass --> vcl_fetch -->vcl_deliver
3.vcl_recv --> vcl_hash --> vcl_miss --> vcl_fetch --> vcl_deliver
4.vcl_recv --> vcl_hash --> vcl_miss --> vcl_pass --> vcl_fetch --> vcl_deliver
5.vcl_recv --> vcl_pass --> vcl_fetch --> vcl_deliver
6.vcl_recv --> vcl_pipe
3.varnish 4.0+状态引擎包括:
vcl_recv:接收请求,并且判断是否可以使用缓存数据;
vcl_hash:对于从backend端取回的数据,如果可被缓存,则进行哈希计算;
vcl_hit:对于请求的资源可以在缓存对象中直接获取;
vcl_miss:对于请求的资源无法在缓存对象中直接获取;
vcl_deliver:构建响应报文;
vcl_pass:对于本来可以从缓存中查找到资源明确的设置不使用缓存;多数用于私有缓存的查找策略;
vcl_pipe:对于无法理解的请求,直接按照原样的封装直接代理至backend端;
较于varnish3.0新增:
vcl_backend_fetch:从backend端取回数据;
vcl_backend_response:处理从backend取回的数据;
vcl_backend_error:本地发生错误时,构建错误响应报文;
vcl_synth:主要用于缓存修剪及信息发送;(由varnish3.0中的error变化而来)
vcl_purge:修剪缓存;
varnish的处理流程:
1.vcl_recv --> vcl_hash --> vcl_hit --> vcl_deliver
2.vcl_recv --> vcl_hash --> vcl_hit --> vcl_pass --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
3.vcl_recv --> vcl_hash --> vcl_pass --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
4.vcl_recv --> vcl_hash --> vcl_miss[ --> vcl_pass ] --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
5.vcl_recv --> vcl_hash --> vcl_purge --> vcl_synth
6.vcl_recv --> vcl_hash --> vcl_pipe
7.vcl_recv --> vcl_hash --> waiting
↑ ↓
←←←←←
varnish中还有两个特殊的状态引擎:
vcl_init:
在处理任何请求之前要调用此引擎,主要用于初始化VMODs;
vcl_fini:
在所有的请求都已经处理结束,在VCL的配置被丢弃时调用此引擎,主要用于清理VMODs;
VCL的语法格式:
1.与C、C++语言的语法非常相似,可以支持C、C++或perl风格的注释方式:
//, #, / ... /
2.VCL不支持循环和跳转语句;但可以是if条件分支(单分支、双分支及多分支);
if的单分支格式:
if (condition) {
...;
}
if的双分支格式:
if (condition) {
...;
} else {
...;
}
if的多分支格式:
if (condition1) {
...;
} elseif (condition2) {
...;
} else {
...;
}
3.所有的字符串内容应该放置于""之内,且不能使用换行符;
4.支持内建和自定义的ACL;
5.支持丰富的操作符:=(赋值符号), ==(等值比较), >, >=, <, <=, !, &&(与运算), ||(或运算), ~
6.使用return()关键字来决定下一个处理流程使用哪个引擎,且return()关键字无返回值;
7.支持内建变量及自定义变量,并且内建变量之间存在依赖关系,只能在特定的引擎中调用特定的内建变量;
set var_name = value
unset var_name
VCL中的内建变量:
req.:request,表示客户端发送来的请求报文相关的变量;
bereq.:backend request,由varnish向backend端主机发送请求的相关变量;
resp.:response,由varnish响应给前端设备或客户端的响应报文的相关变量;
beresp.:backend response,由backend主机响应给varnish的响应报文的相关变量;
obj.*:存在在缓存空间中的缓存对象相关的变量,只读;
常用的内建变量:
req类:
req.http.HTTP_HEADER_NAME:
req.http.Cache-Control
req.http.User-Agent
req.http.Host:
...
req.url:客户端发送来的请求报文中的URL相关信息;
if (req.url ~ (?i).php$) {
return(pass);
}
req.method:客户端发送来的请求报文中的请求资源的方法;
req.proto:客户端发送来的请求报文中使用的http协议版本;
bereq类:
bereq.http.HTTP_HEADER_NAME:
bereq.http.Cache-Control
bereq.http.User-Agent
bereq.http.Host:
bereq.url:varnish向backend端发送的请求报文中的URL相关信息;
bereq.method:varnish向backend端发送的请求报文中的请求资源的方法;
bereq.proto:varnish向backend端发送的请求报文中使用的http协议版本;
bereq.backend:指明要调度的后端主机;
resp类:
resp.http.HTTP_HEADER_NAME:
resp.status:varnish自身向客户端发送的响应报文中的响应状态码;
resp.proto:varnish自身向客户端发送的响应报文中的http协议版本号;
beresp类:
beresp.http.HTTP_HEADER_NAME:
beresp.status:backend端主机向varnish发送的响应报文中的响应状态码;
beresp.proto:backend端主机向varnish发送的响应报文中的http协议版本号;
beresp.backend.name:backend端主机型varnish发送的响应报文中的主机名;
beresp.ttl:backend端主机响应的内容剩余的可缓存时长;
obj类:
obj.hits:指定的对象从缓存中命中的次数;(实时数值)
obj.miss:指定的对象从缓存中未命中的次数;(实时数值)
obj.ttl:指定的对象在缓存中剩余有效缓存时长;
VCL的自定义变量:
定义变量:
set VAR_NAME = VALUE;
取消定义的变量:
unset VAR_NAME;
为了方便展示下面的配置示例,说一下环境:
1.在安装好的varnish缓存服务器主机上,/etc/varnish/varnish.params中修改监听的后端服务器端口号为80而不是默认的6081,其他默认就可以,方便显示;
2.在/etc/varnish/varnish.params中VARNISH_LISTEN_PORT=80,然后保存退出重启服务(重启命令:systemctl reload varnish.service)
3.iptables -F关闭防火墙;
4.setenforce 0 更改SELinux的状态,防止访问受影响;
以上是关于缓存服务器之memcached和varnish的主要内容,如果未能解决你的问题,请参考以下文章
linux自学笔记--memcache和varnish缓存服务器
Memcache(d) vs. Varnish 用于加速 3 层 Web 架构
您如何在 Memcached、Redis 和 Varnish 之间进行选择?