第一百二十一天 : varnish

Varnish

缓存基本知识

程序的运行具有局部性特征

  • 时间局部性 : 访问过的数据, 在很短的时间内能被再次访问
  • 空间局部性 : 数据被访问到, 数据周边的其他数据也有可能被访问到

衡量缓存有效与否, 取决于缓存的命中率
缓存 : 解决传输速度不对等的问题, 将访问过的数据, 放置在更加高速的设备上进行访问.

热区数据 : 局部性的一个表现

  • 时效性 : 缓存过期(原数据更新)—-] 缓存清理

缓存命中率 : hit/(hit + miss) 0-100%

  • 页面命中率 : 基于页面数量进行衡量
  • 字节命中率 : 基于页面体积进行衡量
缓存与否 :
  • 私有数据 : private, private cache
  • 公共数据 : public, public or private cache
HTTP报文中与Cache相关的参数 :
响应报文内容 :

  • no-store : 缓存内容不能保存到本地
  • no-cache : 请求最新内容, 不请求缓存内容
  • max-age : 缓存有效的最大时长
请求报文内容 :
  • public : 允许所有内容被缓存

Varnish 组织架构

  • Manager 进程
  • Cacher 进程 : 包含多种类型的线程
    • accept, worker, expiry…
  • share memory log :
    • 统计数据 : 计数器
    • 日志区域 : 日志记录
  • 配置接口 : VCL
    • Varnish Configuration Language
      1
      vcl complier --] c complier --] shared object
  • jamallog : 为了实现高效缓存的系统调用

Varnish 的程序环境 :

  • /etc/varnish/varnish.params : 配置varnish 服务进程的工作特性, 监听地址和端口 缓存机制…
  • /etc/varnish/default/.vcl : 配置各Child/Cache线程的工作属性:
  • 主程序 : /usr/sbin/varnishd
  • CLI Interface : /usr/bin/varnishadm
  • Shared Memory Log 交互工具
    • /usr/bin/varnishhist : 查看日志区域的历史数据
    • /usr/bin/varnishlog : 对日志进行获取和管理
    • /usr/bin/varnishncsa : 对NCSA 格式的日志进行获取和管理
    • /usr/bin/varnishstat : 对程序统计的数据进行分析
    • /usr/bin/varnishtop : 对数据进行排序
  • 测试工具程序 : /usr/bin/varnishtest
  • VCL 配置文件重载程序 : /usr/sbin/varnish_reload_vcl
  • Systemd Unit File :
    • /usr/lib/systemd/system/varnish.service : 主服务
    • /usr/lib/systemd/system/varnishlog.service : 日志记录服务
    • /usr/lib/systemd/system/varnishncsa.service : NCSA格式的日志服务

Varnish 的缓存存储机制 :

  1. malloc [size] : 定义可用空间的上限, 重启后所有缓存项失效
  2. file [path,[size,[granularity]]] : 文件存储, 黑盒, 重启后所有缓存项失效
  3. persistent ,path,size 试验阶段 .

Varnish 配置 :

选项 : 配置选项放置在/etc/varnish/varnish.params, 是Unit File 的EnvironmentFile
默认监听在6081端口上, 避免和当前所代理的服务冲突.


1
2
3
4
5
6
7
8
9
10
-a address[:port][,adress[:port]][...] 指明监听的地址和端口
-b host[:port] 指明后端的主机和端口
-C 测试, 输出C语言代码并且退出
-p param=value 设定参数的值[可指定多次]
-r param[,param ...] 设定指定参数为不可修改
-u user 指定运行的用户
-s [name=]type[,options] 定义缓存存储机制
-F : 运行于前台
-f config_file : 指定配置文件
-T [address[:port]] 指定管理地址和接口, 管理端的监听的地址和端口为127.0.0.1:6082

密钥文件安装后自动生成
重载VCL配置文件 : varnish_vcl_reload

使用varnishadm 配置varnish运行时参数

1
varnishadm -S /etc/varnish/secret -T :6082


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
help [[command]] : 获取帮助
ping [[timestamp]] : 查看缓存服务器的状态
auth [response] : 认证
quit : 退出CLI模式
banner : 显示
status : 显示Child进程的状态
start : 运行varnish
stop : 停止varnish
vcl.load [configname] [filename] : 载入新的VCL文件
vcl.inline [configname] [quoted_VCLstring] : 载入新的VCL文件并附加参数
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] : 显示具体VCL文件中的内容
backend.list [[backend_expression]] : 显示后端主机列表
backend.set_health [backend_expression] [state] : 设定后端主机的健康状态
ban [field] [operator] [arg] [&& [field] [oper] [arg]]... : 清理缓存
ban.list : 定义如何手动清理缓存
修改特定的配置项 :

1
varnish> param.set Param_Name Value

  • 示例
    1
    param.set thread_pool_max 1000

VCL (varnish configuration language)

state engine : 状态引擎切换

  • request : vcl_recv
  • response : vcl_deliver
  1. vcl_hash -(hit)-; vcl_hit —; vcl_deliver
  2. vcl_hast -(miss)-; vcl_miss —; vcl_backend_fecth —; vcl_backend_response —; vcl_deliver
  3. vcl_hash -(purge)-; vcl_purge —; vcl_synth
  4. vcl_hash -(pipe)->; vcl_pipe

两个特殊引擎 :

  • vcl_init : 在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs;
  • vcl_fini : 所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs;

vcl 的语法格式 :

  1. vcl version 说明vcl的版本
  2. //, #, / / 作为注释
  3. 子例程使用sub vcl_hit { } 进行声明
  4. 没有循环, 内建变量的使用首先于引擎
  5. 结束一个状态引擎使用一个keyword来结束, 使用return来决定如何结束状态引擎 return(vcl_miss)
  6. 一个状态引擎上的配置只对一个状态引擎起作用

VCL状态引擎

  • 每一个请求都是被独立处理的
  • 每一个请求与其他请求隔离
  • 各个状态引擎相互隔离
  • return(action) 指示退出一个状态进入下一个状态
  • 内建VCL码, 一直生效并且附加在自定义的代码后面

三类主要语法


1
2
3
4
5
6
7
8
sub subroutine {
    ...
}
if CONDITION {
    ...
} else {
    ...
}

内建的函数和关键词

函数
  • regsub(str, regex, sub) : 基于正则表达式进行查找, 查找到的第一个值进行替换
  • regsuball(str, regex, sub) : 基于正则表达式进行查找, 查找到的所有值进行替换
  • ban(boolean expression) : 基于判断条件对缓存空间进行缓存清理
  • hash_data(input) : 对指定的数据进行hash计算
  • synthetic(str) : 用于响应报文中的页面错误信息, 可用于客户端请求的重定向
关键字
  • call subroutine : 调用一个子例程(sub XXXX)
  • return(action) : 指明下一次的动作
  • new :
  • set : 设定一个变量的值
  • unset : 取消一个变量的值
操作符

==, !=, ~, >, >=, <, <=

示例:


1
2
3
4
5
if (obj.hits&gt;0){
    set resp.http.X-Cache = &quot;HIT via&quot; + server.ip;
} else {
    set resp.http.X-Cache = &quot;MISS via&quot; + server.ip;&#39;
}

报文处理流程和对应处理函数的变量

201611240922001201611240922002201611240922003


处理函数 能使用的变量
vcl_hash{ } req.*
vcl_pipe{ } req.*
bereq.*
vcl_hit{ } req.*
obj.*
vcl_miss{ } req.*
vcl_purge{ } req.*
vcl_pass{ } req.*
vcl_deliver { } req.*
resp.*
vcl.synth{ } req.*
resq.*

常用变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bereq.*, req.*:
    bereq.http.HEADERS
    bereq.request:请求方法;
    bereq.url:请求的url;
    bereq.proto:请求的协议版本;
    bereq.backend:指明要调用的后端主机;
    req.http.Cookie:客户端的请求报文中Cookie首部的值;
    req.http.User-Agent ~ &quot;chrome&quot;
beresp.*, resp.*:
    beresp.http.HEADERS
    beresp.status:响应的状态码;
    reresp.proto:协议版本;
    beresp.backend.name:BE主机的主机名;
    beresp.ttl:BE主机响应的内容的余下的可缓存时长;
obj.*
    obj.hits:此对象从缓存中命中的次数;
    obj.ttl:对象的ttl值
server.*
    server.ip
    server.hostname
client.*
    client.ip
  • bereq.* varnish服务器向后端传递的请求
  • server.* 与varnish服务器相关的变量
  • client.* 与client端相关的变量

示例 : 强制对某类资源的请求不检查缓存

1
2
3
4
5
vcl_recv {
    if(req.url ~ &quot;(?i)^/(login|admin)&quot;) {
        return(pass);
    }
}

第一百一十四天 : MySQL进阶管理

MySQL

内部数据集在磁盘上, 某一次读取操作, 消耗的代价是巨大的.
所以要使用索引

  • 连接管理器
  • 线程管理器
  • 用户管理器 : 用户的访问还受访问控制器的限制

约束

主键约束 : 唯一非空,一张表只能有一个
外键约束 : 参考性约束, 引用性约束
唯一键约束 : 唯一, 可存在多个
检查性约束 : 对值进行检查

三层模型 :

物理层 => 系统管理员SA
逻辑层 => 数据库管理员DBA
视图层 => 程序员Coder

实现 : 各种数据库产品

服务端程序 :