这几年的工作,很大一部分内容都在跟图片应用打交道,一小部分时间也涉及到网络音频应用,在这部分应用中,缓存功能起着很重要的作用。下面就之前工作时用到的几款缓存:squid、nginx-cache、traffic server、varnish等做一个简单的比较。
1、squid
squid应该属于缓存里的常青树了,许多教程或者资料在介绍缓存的时候,都多多少少会把squid拿出来写一笔,所以这也是squid的优势,因为有很多资料可查,所以适合新人上手,配置起来后,一般都能有一个比较让人满意的工作状态,除非是配置出现重大错误。此外,squid除了能担负缓存工作以外,还能作为反向代理工作,可以算是一个多面手,但随后涌现出来的几个小弟(比如nginx、traffic server等),都能胜任同样的多面工作,因此squid在这块反而显得特点不明显;
就缓存方面而言,由于自己在代码方面道行太浅,所以从来没有看过相关的源代码(汗……),对squid的缓存处理工作方式,主要来源于实际工作的感觉。
squid大致工作流程如下:当被缓存的内容第一次从源被读到squid中时,squid会认为它是“新鲜”的,于是将它放到内存中,当内存中的数据达到了设定的阈值时,squid会根据一个最早最久未使用算法(这个名称其实是我自己定义的),将过了“新鲜期”的内容写到磁盘上,以便将来的一段时间,当又有请求过来读取这类“不新鲜”的数据时,squid就会从磁盘上将数据重新载入内存,从而减少读取后端的次数,达到减轻后端源压力的目的。
squid的内存调度算法或许存在某些无法跨越的限制,有不少文档都提到squid配置内存分配时,不应超过系统内存的1/2,否则可能出错,我在实际工作中也确实遇到过,当时尝试把squid可支配内存改到超过了系统内存的1/2,没几天系统就莫名其妙崩溃了,还没有任何相关出错日志,后来将对应选项改回来后,这类错误再没出现过。但正因为这个原因,使得squid实际使用到的内存量偏小,请求命中的数据中,有一部分是在磁盘上的(根据实际查看,磁盘数据命中率占整个缓存命中率的10%~30%左右),所以还是对工作效率有一定影响的,毕竟磁盘的读取速度远远比不上内存的速度。
squid支持将缓存内容存放在不同的目录乃至分区上,这本来是个不错的设计点,但前面提到,工作一段时间后,squid对磁盘的读写还是相对比较频繁的,而squid似乎在这方面也没有做容错机制,好几次我遇到过,某块存放squid的数据盘出错后,squid服务会挂起乃至引起系统崩溃,因此可以说这个功能是个败笔。
squid的缓存失效算法似乎也存在一些不尽人意的地方,在实际工作过程中,几乎所有的squid都会在工作一段时间后,后端源和请求没有什么大的变化的情况下,squid命中率会莫名其妙出现一个下降,下降幅度在5%~10%之间,这个数字看起来不大,但相当于对后端源的负载压力增加一倍不止。而且在有些应用场合的架构中,squid前端已经有nginx做了url hash,确保到squid的请求都是唯一的,即便这样也阻止不了命中率的下降,让人百思不得其解。
其他方面,squid服务器的资源消耗主要在内存和磁盘io这两块,其他系统负载,比如cpu等,基本都很低;squid包含了一个比较完整的查询模块,能够查询到比较丰富的状态信息。
squid特点简要总结:
老牌软件,上手相对容易,参考文档较多,功能中规中矩;
支持多磁盘数据存放,但也容易因磁盘失效导致崩溃;
缓存调度算法似乎还未达到最优化。
2、nginx
nginx这几年称得上风头很盛,无论是作为web server还是反向代理,都表现出很强劲的处理能力。但nginx其实一开始是没有cache功能的,于是新浪技术团队早前重写了nginx的部分内核,给nginx加上了缓存功能,当时命名为ncache,然后将其开源化并发布到网上,随后不久,nginx公布了官方proxy-cache模块,同时新浪ncache wiki也不再更新,最新更新指向了nginx官网的proxy-cache说明页,个人猜测是nginx开发小组完整接收了ncache代码,并整合到了官方正式版中。
从ncache出现的时候,我就在相册架构中试用过,当时ncache表现出来的性能确实很惊艳,个人判断是nginx的内存调度算法优于squid,因此从ncache里读取图片的速度总体上要高于squid。但当时ncache也没做到完美,工作一段时间后,ncache的处理速度会急剧下降,通过httpwatch抓取请求过程,会发现请求会长时间卡在连接建立等待这段过程中,而此时ncache负载也就刚刚过半,后端源也未发现任何异常,服务日志也未发现任何相关记录,最后只能重启服务解决;此外,ncache提供的查询功能很简陋,仅能提供寥寥两三行查询信息,基于以上两点,我放弃了ncache,重新让squid取代了他的位置。
nginx的正式proxy-cache模块推出后,我又一次在相册缓存中将其加入进行测试,应该说,proxy-cache的性能表现跟之前ncache一样强大,同时应该是修正了之前ncache的bug,服务的稳定性更好了,再没出现过类似以前那样的奇怪问题,再加上nginx本身具备的代理功能,在一些小型应用场合,用少数几台nginx就能轻松实现静态文件缓存+动态请求转发,应对一般的访问量基本没有问题。
但整合后的nginx也有不尽如人意的地方,最大的一个缺点状态查询的功能缺失。之前ncache好歹还能查到个命中率,nginx整合后,连命中率都不给了,实时状态只能查询到总连接数和总的处理数,这个数据几乎就是毫无用处。要想获得真实的命中率,还得需要开启nginx的日志功能,通过对日志的分析统计才能得出。但当访问量较大的时候,日志也会相应变得庞大不堪,如果不及时处理,必然会对系统稳定造成影响,同时,通过日志来统计分析命中率,实用性和时效性也大大打了折扣。
(留坑待填)
阅读(1415) | 评论(0) | 转发(0) |