Nginx实践 使用memcached模块加速PHP应用程序
Memcached,就不多说了,地球人都知道.
Nginx有一个memcached_module,可以直接从后端的memached服务器中读取内容,
直接输出.
通过这个模块,可以极大的提升动态页面的访问速度.
我的实践中, 曾经用这个模块快速的解决了由于代码造成的一些瓶颈问题.
memcached可以通过upstream来从多台memcached服务器中读取,也可以支持热备份.
下面是我的完整例子
upstream memcached {
server 192.168.8.11:11211;
server 192.168.8.10:11211;
}
server {
listen 80;
server_name t.night9.cn;
limit_conn one 10;
charset utf-8;
access_log /logs/web/t.log main;
root /www/app/web;
default_type text/html;
index app;
location = / {
set $memcached_key $host$uri;
default_type text/html;
memcached_pass memcached;
error_page 404 = /missing;
}
location /missing {
internal;
rewrite ^/missing$ /app/site/blog last;
}
include php_app.conf;
}
在这个例子中, nginx首先从memcached中读取(缓存的key可以用memcached_key来设置.),
如果命中,则直接输出内容,注意,需要设置default_type ,否则可能不能正常显示.
如果没有命中,memcached_module会返回404,因此可以用 error_page 404来转发到后端的应用程序,
本例中是先转发到/missing ,而/missing则重写到实际的后端应用地址中.
Nginx只负责从memcached中读取内容,但不负责设置.因此,需要你的应用程序自行将相应的页面缓存
设置到memcached中.
在我的部署中, 我是通过设置一个PAGE_CACHE_ID给php的fastcgi:
(在fastcgi_params中加入):
fastcgi_param PAGE_CACHE_ID $memcached_key;
php程序一旦检测到这个环境变量,
那么会自动将当前页面的内容设置到memcached缓存中,由于是在php框架中自动作的,所以可以随时切换,不需要修改.
缺点:
很多事情都不是那么完美, 对于nginx的这个module,其最大的问题就是不支持压缩,
因此,在使用php的memcache函数设置缓存时,必须取消压缩,否则将无法正确输出.
这样带来的一个小问题就是:
由于一般页面至少数k以上,这样对于内存的消耗是比较大.
因此, 在这个module支持压缩之前, 可以考虑备选方案:
使用独立的FASTCGI服务器来替换memcache模块.
通过CPAN模块,实现起来非常简单!
Comments
18 Responses to “Nginx实践 使用memcached模块加速PHP应用程序”
Leave a Reply
博主你好
我在配置nginx的时候遇到了一个问题
如果请求是/cache/XXX,我想用XXX作为memcache的key,总是配不对
然后memcache不命中的时候,404我设置成/backend/,然后在 location的backend里要把/backend/ 改写成/backend/?url=XXX (和前面那个XXX一样)
我是这样写的:
rewrite ^/cache/?(.*)$ /$1;
set $memcached_key $1;
location = /backend {
internal;
rewrite ^/backend/?(.*)$ /backend/?url=$request_uri;
请问是哪里错了
搜了好多地方搜到这里来了
如果您能指教我不胜感谢
1.检查下你的error_page , 是否正确?
2.尝试把location=/backend 改为 location /backend
3.看看是否设置了memcached_pass 指令,如:
location /cache {
rewrite ^/cache/(.*)$ $1 last;
set $memcached_key $1;
memcached_pass 127.0.0.1:11211;
error_page 404 = /missing;
}
location /missing {
internal;
rewrite ^/missing/(.*)$ /backend/?url=$1 last;
}
谢谢
可是还是有问题
rewrite ^/cache/(.*)$ $1 last;
set $memcached_key $1;
log里讲the “$memcached_key” variable is not set
我的请求是HOST:PORT/cache/http://www.g.cn
如果php不用压缩,但nginx使用了gzip压缩行不?
@epaddy
可以的
可以留下msn吗 请教 这里说不清楚!
我的 fywz10629@hotmail.com
能否分享下php程序的关键代码…php_app.conf有什么特殊吗?
不知何故我反复尝试就是没试成功:(
不知道哪里问题,就是不得要领
@ahu
没什么关键代码,就是普通的memcached的操作而已,在php程序中需要set到cache中,关键一点就是cache的key要传递给PHP程序
在php的fastcgi配置中增加:
fastcgi_param PAGE_CACHE_ID $memcached_key;
上面是个例子,PAGE_CACHE_ID可以换成任意名称。
之后就可以通过_SERVER['PAGE_CACHE_ID']
来获得这个key了
将要缓存的页面用这个key存到memcached即可
为什么我的从memcached的读取速度还没有从硬盘读取速度快 才1000左右 好的时候 但从硬盘读取的时候有3000+ 是哪里的原因呢?可以解释一下吗?
@fywz10629
环境配置?使用什么api? 最好在你实际部署环境测试。另外,自己看下命中率,命中率过低也许是你memcached根本就没有缓存住。
怎么样把请求中的一个参数的值作为memcache key啊?
比如http://localhost/cache/jsp.do?arg1=wi708g7df66&arg2=xxxx
这里把arg1的值作为key 用来识别用户的session, 如何办?
@yjh2002
不明白你的具体要求. 要在Nginx级别实现?还是在后端实现?
jsp中可以获得arg1的key。
如果你是希望nginx中使用arg1的值作为key,似乎应用的场景有些问题,
也是可以有解决办法,你可以使用类似(未测试):
rewrite ^/jsp.do?arg1=(.*)&arg2.*$ $1 last;
set $memcached_key $1;
直接在Nginx级别实现, 不在后端设逻辑。
而且有的请求不一定参数arg1就在前面的, 有可能是这样的, http://localhost/cache/jsp.do?arg2=xxxx&arg1=wi708g7df66 所以我写了两个,
rewrite ^/jsp.do?(.*)(arg1=)(.*)&(.*)$ $3 last;
rewrite ^/jsp.do?(.*)(arg1=)(.*)$ $3 last;
set $memcached_key $3;
但是报错, the “$memcached_key” variable is not set。
[...] nginx是个好东西,一直还没有时间好好研究。还有一篇中文: 使用memcached模块加速PHP应用程序Nginx实践 使用memcached模块加速PHP应用程序 [...]
兄弟,nginx是可以做gzip的,这个我测试过,比如
location ~* ^/xxxxx {
set $memcached_key $host$uri;
memcached_pass all_memcachedb;
default_type text/html;
gzip on;
gzip_proxied any;
error_page 404 = /fallback;
}
抱歉,你说的是内存的压缩问题,理解错了
这个我也奇怪,php里set可以压缩,get是取出的是不压缩的数据,那nginx取出的时候居然不处理数据是否压缩的问题
抱歉,理解错了,存储时的确无法压缩
php里get方法取出的是正常数据的,而nginx居然不处理是否压缩的问题