使用memc-nginx和srcache-nginx模块构建高效透明的缓存机制

为了提高性能,几乎所有互联网应用都有缓存机制,其中Memcache是使用非常广泛的一个分布式缓存系统。众所周知,LAMP是非常经典的Web架构方式,但是随着Nginx的成熟,越来越多的系统开始转型为LNMP(Linux+Nginx+MySQL+PHP with fpm),这是因为Nginx采用基于事件机制的I/O多路复用思想设计,在高并发情况下其性能远远优于默认采用prefork模式的Apache,另外,相对于Apache,Nginx更轻量,同时拥有大量优秀的扩展模块,使得在Nginx上可以实现一些美妙的功能。

传统上,PHP中使用memcache的方法是使用php-memcachephp-memached扩展操作memcache,然而在Nginx上有构建更高效缓存机制的方法,本文将首先介绍这种机制,然后介绍具体的操作步骤方法,最后将对这种机制和传统的PHP操作memcache的性能进行一个benchmark。

Nginx的Memc和SR Cache模块

缓存策略的改进

我们知道,Nginx的核心设计思想是事件驱动的非阻塞I/O。Nginx被设计为可以配置I/O多路复用策略,在Unix系统中传统的多路复用是采用select或poll,但是这两个方法的问题是随着监听socket的增加,性能会下降,因为在linux内核中是采用轮询的方式判断是否可以触发事件,换句话说算法的复杂度为O(N),而在较新的linux内核中引入了复杂度为O(1)的epoll,因此Nginx在Linux下默认采用epoll,而在FreeBSD下默认采用kqueue作为I/O策略。

即便是这样,传统的缓存策略仍可能造成效率低下,因为传统上是通过PHP操作memcache的,要执行PHP代码,Nginx就必然要和FastCGI通信,同时也要进入PHP的生命周期,因此SAPI、PHP Core和Zend Engine的一系列逻辑会被执行。更糟糕的是,fpm和PHP可能会阻塞,因此破坏了Nginx的非阻塞性。下图展示了在memcache命中时整个处理过程。image

可以看到,即使memcache命中,还是要进入PHP的生命周期。我们知道,目前很多互联网应用都使用RESTful规范进行设计,在RESTful应用下,普遍使用uri和查询参数作为缓存的key,因此一种更高效的缓存策略是Nginx直接访问memcache,并用$uri和$args等Nginx内置变量设定缓存key规则,这样,当缓存命中时,Nginx可以跳过通过fastcgi和PHP通信的过程,直接从memcache中获取数据并返回。memc-nginx和srcache-nginx正是利用这种策略提高了缓存的效率。下图是这种高效缓存策略的示意图(当memcache命中时)。

image

猜你喜欢

转载自blog.csdn.net/jiangbb8686/article/details/89221998