nginx+NFS vs nginx+memcached

前面我写了SuperCache的介绍之后,两位朋友都表示他们在生产环境中使用了NFS,我直觉是NFS性能并不如memcached好,因为NFS牵扯了一个文件系统,但是NFS可以很好利用nginx的gzip_static。于是我做了这个评测。

我准备了三台服务器,一台服务器A用于提供memcached和NFS服务,B服务器上有nginx,挂载了A服务器上的NFS,最后通过C服务器对B服务器进行压力测试。三台服务器都是某云服务上的三台VPS,4核8G内存。

为了模拟真实环境,我首先给NFS和memcached准备了200,000条4000字节的html文件,路径格式为/articles/.html,内容是一些随机字符。

首先单纯就写入的速度来看:

写入速度明显是memcached占优,这是很容易理解的。因为NFS走了文件系统,而memcached减少了文件系统所需的诸如磁盘操作以及索引等等额外的东西。

然后我使用了siege对其进行测试

NFS

NFS服务器端/etc/exports配置

使用NFS的nginx配置:

NFS后端的结果如下:

我还额外对所有文件进行了gzip压缩(过程非常缓慢),然后启用了gzip_static:

结果效率并没有提升,原因不明。

memcached

使用memcached的nginx配置:

memcached后结果如下:

访问速度上基本没有太大差异,memcached略胜一筹

结论

NFS基于文件系统,Memcached完全存与内存。

所以,在需要频繁更新缓存的场景中,NFS受限于IO和网络条件,更新的效率较低。
由于NFS不具备memcached这种自动过期的功能,必须额外写脚本进行Sweep,可能不够方便
同时局限于文件系统的结构,清理过程中需要遍历文件也是十分消耗时间和磁盘IO的。

但如果不需频繁更新,NFS基于文件系统的特性更能节省内存。

另外我对NFS配置不够了解,对于NFS如何做高可用性不太清楚,但如果是memcached的话,则相对比较方便,可以在upstream中添加多个节点,并配置memcached_next_upstream等选项。

还有本文没有测试的:

  • 如果AB机器是同一台服务器,那么结果如何
  • NFS有一些配置选项,比如async选项,我在这里配置的是sync选项,是否对性能有所影响

Linux 上配置 Nginx + Mongrel cluster

Nginx不仅是一个小巧且高效的HTTP服务器,也可以做一个高效的负载均衡反向代理,通过它接受用户的请求并分发到多个Mongrel进程可以极大提高Rails应用的并发能力。下面介绍一下如何在一台服务器上配置Nginx + Mongrel cluster。

获得Nginx方法可以参考前一篇配置Nginx+PHP5 FastCGI的文章,这里我们假设大家是通过自己编译,并配置了默认的编译的参数,此处使用的是Nginx 0.5.x版。

配置Mongrel cluster

我们还需要获得Mongrel和其Cluster插件(用来方便得启动多个Mongrel进程),如下通过gem进行安装:

然后建立mongrel_cluster的配置文件。进入Rails应用即你的程序的根部目录(以下假设/usr/rails),运行:

然后mongrel_cluster便会在config目录下生成一个mongrel_cluster.yml,内容如下:

我们可以通过修改其中的设置来更改mongrel_cluster的运行,这个范例配置省略了一些其他参数,具体的参数的含义如下:

  • address: 指定绑定的地址
  • port: 指定mongrel_cluster所运行的mongrel进程从哪个端口开始绑定
  • servers: 指定同时运行多少个mongrel进程,结合port参数,就是表示port到port+servers-1(含)的端口将被使用
  • environment: 指定Rails运行的配置环境
  • user: 指定mongrel进程以什么用户的身份运行
  • group: 指定mongrel进程以什么组的身份运行
  • cwd: 指定mongrel运行的根目录
  • log_file: 各个mongrel进程的输出日志的位置,相对于cwd的目录,会在文件的扩展名之前加上各进程对应的端口号
  • pid_file: 各个mongrel进程的pid文件的位置,相对于cwd的目录,会在文件的扩展名之前加上各进程对应的端口号

大家可以根据自己的具体情况进行修改。以下是一个完整的mongrel_cluster.yml配置文件:

接下来便可以启动mongrel_cluster了,以下是控制mongrel_cluster的命令:

配置Nginx负载均衡反向代理

利用nginx的upstream指令配置哪些服务器需要进行负载均衡。在这里也可以说直接说告诉nginx mongrel_cluster在哪些地址和端口上,按照上面的mongrel_cluster的配置,在nginx中应该这样写:

upstream指令后面的mongrel指定了这批上游服务器的的名称,大家可以使用别的名字。每个server指令指定了一个服务器,server指令还支持别的参数可以设置重试次数和超时时间以及不同服务器的权重。

接下来配置nginx在接受哪些http请求时转发到mongrel cluster,因为nginx处理静态文件的速度远远高于mongrel,所以一般当请求的路径不存在的时候才将请求转发到mongrel cluster:

整个Nginx的配置文件的范例请参考:http://wiki.codemongers.com/NginxConfiguration

然后重启Nginx,配置便成功了.

Nginx的WordPress配置

WordPress是一个非常流行的Blog系统,它可以利用Apache的mod_rewrite来实现URL的静态化。安装好的WordPress在配置了持久链接之后,会在网站的根目录下(如果可写)生成一个.htaccess文件,这个文件可以指示Apache如何进行URL重写(如果服务器配置为允许使用htaccess的指令的话),它的内容如下:

这个文件的意思就是,如果当请求的文件不存在,那么把请求内部重定向到/index.php。WordPress会自己分析请求的URL,来判断显示哪个页面。

在上次配置了Nginx+PHP之后,由于Nginx不支持Apache的.htaccess文件,要实现持久连接静态化,我们必须手工配置Nginx的文件。首先找到Nginx的配置文件,默认编译后的配置文件在/usr/local/nginx/conf/nginx.conf;Ubuntu通过包安装的配置文件位于/etc/nginx/nginx.conf,也可以编辑vhost的配置文件,放在了/etc/nginx/sites-available下。

以下是基本的配置(Ubuntu下的范例):

还可以有很多种不同配置方式,例如不改写所有包含wp-的url等。此配置考虑了目录下的索引文件index.html和index.php。-f指令表示测试文件是否存在(不考虑文件和目录的区别),!-f则表示不存在。注意在重写url到index.html后面有个break,而重写到index.php后没有break。因为html文件不需要任何额外工作可以直接发送到客户端,所以重写规则在这里终止,下面就直接让nginx发送文件。而.php文件需要进一步发送到fastcgi进程来运行,Nginx会继续判断该文件符合第二个部分location ~ .*\.php$的规则,并进行FastCGI的转发。

大家可以将以上内容保存为wordpress.conf,然后在自己的vhost配置,即server节中应用该配置文件,例如(以下为Ubuntu进行的配置):

接下来让Nginx重新载入配置文件,便可使用WordPress的持久链接了。

Linux 上配置 Nginx + PHP5 FastCGI

Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配Lighttpd的性能,同时还没有Lighttpd的内存泄漏问题,而且Lighttpd的mod_proxy也有一些问题并且很久没有更新。

因此我打算用其替代Apache应用于Linux服务器上。但是Nginx并不支持cgi方式运行,原因是可以减少因此带来的一些程序上的漏洞。那么我们必须使用FastCGI方式来执行PHP程序。

下面是我成功地配置Nginx + PHP5 FastCGI的过程

继续阅读“Linux 上配置 Nginx + PHP5 FastCGI”