Varnish 分析


通过学习varnish的代码,进行了总结,也组织了培训,

现在将相关的内容传到这里,与大家进行交流。

varnish的很多优秀的思想值得深究和讨论啊

全文参考 http://ncache.googlecode.com/files/varnish.pdf

Varnish介绍

1 Varnish is HTTPaccelerator.

2 Varnish stores data invirtual memoryand leaves the task of deciding what is stored in memory and what gets paged out to disk to theoperating system

3 The Varnish web site claims that Varnish is ten to twenty times faster than the popularSquid cacheon the same hardware.

4 Varnish is heavilythreaded


varnish总体架构

2.1总体流程

主进程fork子进程,主进程等待子进程的信号,子进程退出后,主进程重新启动子进程

子进程生成若干线程。

Accept线程:接受请求,将请求挂在overflow对列上

Work线程:多个,从对列上摘除请求,对请求进行处理,直到完成,然后处理下一个请求

Epoll线程:一个请求处理称作一个sesion,在sesion周期内,处理完请求后,会交给Epoll处理,监听是否还有事件发生。

Expire线程:对于缓存的对象,根据过期时间,组织成二叉堆,该线程周期检查该堆的根,处理过期的文件。

线程之间的关系:

2.1.1 accept线程

监听端口,接受连接。

接受后

组织成struct ses(session结构),看是否有空闲的工作线程,如果有,将请求给它,pthread_cond_signal信号通知它

没有空闲线程,如果overflow过大,则放弃该请求。

否则,将其挂在overflow上(需要更多工作线程,发通知)。

继续监听

2.1.2 work线程

从overflow队列上摘取请求(struct ses),进入状态机处理,处理结束后,通过pipe通信,将struct ses发送给epoll线程。

2.1.3 Epoll线程,得到传过来的struct ses,若还没有过期,将socket放入epoll的事件中,事件发生时,也会将其放入到overflow中进行。

关于Expire thread,比较独立,下面专门介绍。

2.2 work线程的处理过程

2.2.1请求的处理过程称为session,主要是由work线程处理的。

请求的是通过进入状态转换机进行分步处理,通过Varnish Configuration Language(VCL)进行定制。

request进入状态机后的状态变化

对于每种状态,都可以通过VCL进行配置,丰富功能。

Work线程处理请求的过程是根据VCL的配置而定制的状态机,典型的处理流程如下

1.Receive,请求处理的入口状态(之前还有first等状态),根据VCL判断该请求是Pass(跳过)还是进行Lookup(本地查询)

2.Lookup,在hash表中查找数据,若找到则进入hit状态,否则进入fetch状态。

3.Pass,选择后台,进入fetch状态

4.Fetch,对请求进行后端的获取,发送请求,获得数据,并进行本地的存储

5.Deliver,,将数据发送给客户端,然后进入done

6.Done,处理结束事宜,对于一些请求需要做重新处理则可能重新进行状态转换或交给epoll

2.2.2 Work线程总体工作如下:

接受到请求,按状态机处理,请求结束后,关闭连接或交给Epoll

重新取请求,若没有请求,挂入空闲队列,等待信号唤醒(pthread_cond)

唤醒它有两个途径,除了前面说的accept线程外,还有就是herdtimer线程

如果是accept唤醒的,则继续按照状态机的方式处理请求,如果是herdtimer唤醒的,则自杀

2.3 工作线程的管理


2.3.1 Herd线程

–根据配置生成指定数目的线程(min)

–动态检查线程数目,生成需要的线程

2.3.2 Herdtimer线程

定期检查空闲的线程,对于空闲超过指定时间的线程,通知它可以自杀

工作线程管理的目的是根据请求的数量动态的调整工作线程的数目

2.4 expire线程

对缓存的数据采用二叉堆的方式进行组织,线程检测堆的root,判断是否过期,对过期的数据进行删除或重取,由VCL设置。

对于过期的数据,如果需要重新取,则会调用状态机中的fetch去后台获取,然后更新

Cache 详解

3.1 Hash方式

3.1.1简单hash方式

–单一链表,按key大小排序,通过memcmp比较查找和添加

–缺点:查询效率低

3.1.2 Hash classic

–第一层hash backet(较大的素数)包含锁

–采用CRC32方法,key可配,一般是url + host

–通过链表解决冲突

–优点:查询较快

–值得参考的地方:采用查找和添加分两遍进行

3.2 Storage方式

3.2.1 Malloc

–通过malloc获取内存

–通过free释放

–特点:简单

–有什么不好呢?

3.2.2 Mmap file

创建大文件,通过二分法分段映射成1G以内的大块

数据的初始化

A 初始化时,将大文件分段进行mmap,每段大小在1G以内,映射好的段分配到free block数组链表中,数组下标便是页的倍数向下取整,如果块大于数组倒数第二个元素与页的乘积,则将该块连接到数组的最后一个元素的链表中。

B 分配,遍历数组,找到满足要求的空闲块,若是前B-2个没有,则从最后一个中满足要求的大块中切出一块。如果找出的块大于需要的容量,则就对其进行拆分,然后将剩下的插入到空闲块中。

C 回收,对于释放的块,看能否和相邻的块进行合并,如果可以,则合并后再重新插入到合适位置。

3.3数据输出

Object结构表示一个请求对象(文件),通过其store链表指出数据块信息

3.3.1采用writev

–将store链表上的数据组成iov,通过writev输出

3.3.2采用sendfile

–通过循环使用sendfile,将store链表中的数据输出

VCL配置

通过vcl脚本对程序进行定制,主要是对请求的定制处理,如过滤某些请求等,脚本配置生成的函数是嵌套在状态机中的。

默认的配置如下

http://varnish.projects.linpro.no/browser/trunk/varnish-cache/bin/varnishd/default.vcl

purge删除配置如下

http://varnish.projects.linpro.no/wiki/VCLExamplePurging

分析与总结

varnish比较轻便,总共的代码量不大,功能上有待丰富和加强。

1. •利用虚拟内存方式,io性能好

2. •状态机设计巧妙,结构清晰

3. •利用二叉堆管理缓存文件,达到积极删除目的

4. •VCL比较灵活

5. •强大的管理功能,top,stat,admin,list等

6. •是内存缓存,重启数据消失

7. •32位机器上文件大小为2G

讨论

1. 二叉堆方式的插入和删除对于缓存文件较多时,性能是不是影响较大

2. 这么多的线程,分工清晰,如epoll,expire,herd,herdtimer等对性能的影响?

3. Hash中的key保存完整的url和host,信息量是不是太大?优点是:信息全,可重新组成请求用于过期的重取

参考

1http://varnish.projects.linpro.no/

2http://en.wikipedia.org/wiki/Varnish_cache

3http://en.wikipedia.org/wiki/Virtual_memory

4http://en.wikipedia.org/wiki/Squid_cache


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值