WEB开发网
开发学院操作系统CentOS CentOS RoR应用性能优化的实战经验 阅读

CentOS RoR应用性能优化的实战经验

 2010-05-06 13:15:10 来源:WEB开发网   
核心提示:CentOS RoR对于电脑使用的玩家的常用软件,然后我就学习及深入的研究CentOS RoR,CentOS RoR应用性能优化的实战经验,在这里和大家一起探讨CentOS RoR的使用方法,希望对大家有用,例如拆分表等等, 最后针对MySQL数据库运行情况,JavaEye网站从2006年9月11日上线基于CentOS

CentOS RoR对于电脑使用的玩家的常用软件,然后我就学习及深入的研究CentOS RoR,在这里和大家一起探讨CentOS RoR的使用方法,希望对大家有用。JavaEye网站从2006年9月11日上线基于CentOS RoR的2.0版本开始,到现在已经运行了将近一年半了。在这一年半的时间里,JavaEye网 站的每 日PV从最开始的5万,缓慢增长到了现在的60万。

随着网站负载的不断增加,我们也在不断尝试和调整网站的性能,积累了不少第一手CentOS RoR应用性能优化的实战经验。虽然我们并不是CentOS RoR性能优化的权威专家,我们所积累的经验也许并不是最优实践,但是作为国内最早涉足CentOS RoR商业运营的互联网网站之一,我们非常 乐意分享和交流我们的实战经验,以帮助后来者节省必要的摸索时间。

CentOS RoR惊人的开发速度恐怕是每个互联网创业者都梦寐以求的,但是随着网站流量的不断增大,可能大多数采用CentOS RoR的网站或迟或早会遇到CentOS RoR的性能 瓶颈,我的一个朋友capitian说过一句很有意思的话:“CentOS RoR应用做到后来,总有自己修改底层的冲动”。就我所了解和掌握的情况来看,很多CentOS RoR网 站都过早的遇到了性能瓶颈,一个很普遍的现象就是:CentOS RoR应用的CPU负载要远远高于数据库的负载。

这是一个有点违背常理的现象,因为我们知道,硬盘IO 速度要比内存慢得多,所以一般Web应用的性能瓶颈往往会出现在数据库IO上,因此优化数据库访问,进行对象缓存是非常有效的性能优化手段。但是一旦应用 服务器负载比数据库还高的话,单纯的对象缓存就无用武之地了。下面我们从几个方面分别谈一谈如何进行CentOS RoR的性能优化:

应用的部署

CentOS RoR应用的部署包括操作系统,Web服务器,应用服务器和数据库四个方面:

一、操作系统

1、发行版本

CentOS RoR适合于部署在Unix类操作系统上面,通常比较多的人使用RHEL/CentOS/Ubuntu,我们比较偏爱SuSE Linux,对于我们服务器使用的AMD Opteron x86_64的CPU来说,SLES要比RHEL有更多的优化。另外应该尽量使用64位版本操作系统,以充分发挥x86_64 CPU的性能,并且x86_64的Linux很多Kernel参数也大很多,代价就是需要更多的物理内存。

2、文件系统

Linux最常用的文件系统是ext3,但我们使用的是Reiserfs文件系统。Reiserfs在读写大量小文件的目录性能非常高,即使处理 目录下面直接存放10万个文件,性能仍然不会下降。我们知道默认情况Rails会对每个浏览器会话在硬盘生成session文件,一个繁忙的网站,临时文 件目录下面有上万乃至几万个session文件是很常见的现象。对于这种目录下面几万个小文件的存取,reiserfs要比ext3性能高一个数量级。如 果希望对session文件有更好的存取性能,可以把临时目录链接到Linux的内存文件系统/dev/shm目录下面,这样实际上session文件的 存取都是直接内存操作了,这种方式唯一的问题在于不能支持群集部署。如果你已经升级到了Rails2.0,可以采取把session保存到Cookie里 面的方式,既可以避免服务器处理session的开销,而且还支持群集部署,是大规模网站部署的首选方式。

3、内核的网络参数调整

对于流量很大的网站来说,默认的Linux内核网络参数偏小,因此如果你的网站流量非常大,或者上传下载大文件比较多,可以针对性的调整内核网络参数,扩大内核的TCP接收数据和发送数据的Buffer缓冲区大小,比方说:

引用

net.core.rmem_default=262144

net.core.wmem_default=262144

net.core.rmem_max=262144

net.core.wmem_max=262144

net.ipv4.tcp_rmem=4096 65536 524288

net.ipv4.tcp_wmem=4096 65536 524288

参数具体调整,可以Google相关的Linux内核参数的文档,这里不展开详谈。


二、Web服务器

Web服务器首选Lighttpd,因为Lighttpd在和后端的应用服务器通讯方式上做了足够的优化:当POST大数据量的时 候,Lighttpd在完整的接收客户端浏览器的数据之后,才会一次性发送给应用服务器;同样的,Lighttpd也是一次性把应用服务器处理的页面数据 全部接收,不设置Buffer Size的限制。因此Lighttpd能够尽最大可能的减轻应用服务器的负担,减少应用服务器用于处理数据传输的延迟,更加有效的利用应用服务器资源。这 方面的详细的论述请看:CentOS RoR部署方案深度剖析。

关于Lighttpd的安装可以参考在Linux平台上安装和配置Ruby on Rails详解,这里仅谈Lighttpd的性能优化的几个要点:

1、网络IO调度方式

Linux Kernel 2.6支持sysepoll方式调度网络IO,能够处理极高的并发连接请求,Lighttpd可以通过配置文件打开sysepoll支持:

引用

server.event-handler = "linux-sysepoll"


2、网络IO传输方式

Linux Kernel 2.6支持sendfile方式传输数据,Lighttpd可以通过配置文件打开sendfile支持:

引用

server.network-backend = "linux-sendfile"

此外Lighttpd还支持应用服务器参与的文件下载控制X-sendfile,详细的论述请看:CentOS RoR网站如何利用lighttpd的X-sendfile功能提升文件下载性能

3、文件状态缓存

Lighttpd通过stat()调用获得文件被修改的信息,来决定当请求同一个静态文件资源的时候,是否需要再次读取硬盘文件。但是每次 stat()调用也有一定的开销,Lighttpd支持通过Fam Server来减少stat调用。即每次当文件被修改之后,Kernel会发送一个消息通知Fam Server,而Lighttpd会通过进程间通讯连接Fam Server,可以知道文件是否被修改的信息,不必再每次调用stat()。

引用

server.stat-cache-engine = "fam"


4、限定POST Size

为了避免黑客恶意的攻击服务器,伪造超大Post数据包轰炸Web服务器和应用服务器,可以限制Request请求的大小,例如限制为10MB:

引用

server.max-request-size = 10240


5、日志文件

Lighttpd是单进程单线程的服务器,调度网络IO性能是极高的,但是在某些极端情况下,单进程服务器也有风险,即一旦被某操作系统调用挂 住,整个服务器就没有办法响应请求了。比方说服务器其他进程导致的IO WAIT很高,操作系统的buffer又不够的时候,Lighttpd在大量的写access log就有被挂住的可能性。因此如果Lighttpd日志对你的参考价值不大,可以考虑关闭掉。像JavaEye网站每天Lighttpd产生430万条 log,对硬盘IO也是一个不小的负担,既然已经开着Rais的production.log,那么Lighttpd的access log没什么参考价值了,那就关掉它。

Lighttpd的性能优化请看其作者写的文章:

http://trac.lighttpd.net/trac/wiki/Docs%3APerformance


三、应用服务器

Ruby的应用服务器可以使用FastCGI,或者Mongrel,如果我们使用Lighttpd的话,FastCGI是最好的搭配。

1、FastCGI和Lighttpd的通讯方式

如果FastCGI和Lighttpd是在同一台服务器,那么建议采用Unix Socket通讯,这种通讯方式比TCP要快一些,FastCGI可以通过Lighttpd自带的spawn-fcgi命令行工具启动,创建socket 文件,而Lighttpd监听socket文件。如果两者不在同一台服务器,需要群集部署,那就必须采用TCP Socket通讯,方式是一样的。

2、FastCGI进程应该开多少个合适?

Rails是单进程方式运行的,理论上来说,开几个FastCGI进程,就只能并发响应几个请求。对于繁忙的网站来说,峰值期间每秒有几十个动态 请求是很正常的事情,但实际上FastCGI进程并不需要开那么多。这是因为前端的Web服务器在处理用户浏览器连接,发送Request请求需要相当长 的时间,在FastCGI处理完请求释放该连接以后,Web服务器还需要相当长的时间才能把页面数据完整的发送到客户端浏览器。用户在点击一个链接以后, 等待1-2秒,页面内容就显示出来,这对用户的感觉来说已经是非常快的了,而FastCGI用于处理该请求可能只需要0.1秒,那么一个FastCGI进 程虽然并不能够真正的并发运行,但实际上的效果是他可以在1秒之内处理10个请求,让10个用户在同时访问网站的过程当中感觉不到明显的延迟。

因此FastCGI需要开多少个,取决于你的网站峰值期间每秒有多少个用户请求过来,而你的FastCGI又能够以多快的速度处理请求。比方说你 的网站峰值期间每秒有50个动态请求,FastCGI在峰值期间处理每个请求需要0.2秒,那么实际上你只需要开10个FastCGI进程就足够了,为了 应付突发的峰值请求,你可以在这个计算量上面增加一些余量,比方说15-20个进程,肯定是绰绰有余了。

关于FastCGI的性能优化,可以参考Lighttpd作者的文章,虽然他是针对PHP跑FastCGI写的,但对CentOS RoR也有参考价值:

http://trac.lighttpd.net/trac/wiki/Docs%3APerformanceFastCGI


四、数据库

JavaEye网站使用MySQL5.0.XX版本,数据库引擎是InnoDB。关于MySQL数据库的调优,推荐大家看MySQL Performance Blog, 作者是一个MySQL性能调优方面的专家,并且提供MySQL咨询服务。他的博客上面有很丰富的关于MySQL调优的文章和演讲文稿,特别是关于 InnoDB方面,非常深入。JavaEye的数据库调优就是根据他的InnoDB演讲文稿来调整的,一般说来,有几个需要调整的参数:

innodb_buffer_pool_size

这个参数很重要,越大越好,对于专用的数据库服务器一般建议开服务器内存的50%以上。

query_cache_size

查询缓存,对于查询的性能提高有很大帮助,但不宜开得过大,查询缓存的过期可能很频繁,过大查询缓存反而降低性能,增加服务器开销

innodb_flush_method = O_DIRECT

针对InnoDB的数据文件,关闭操作系统的文件缓冲,由于InnoDB自己有巨大的Buffer Pool,操作系统对文件的读写缓冲功能反而会降低MySQL的InnoDB的IO性能。

最后针对数据库的SQL优化来说有两点原则:

1、对数据库表要适当的创建索引

特别是出现在where查询条件当中字段,和关联查询当中的外键,要高度注意。

2、尽量避免大表的全表扫描和数据库的硬盘IO

查询比较慢的SQL要explain一下,看看是否发生了全表扫描,采取各种措施减少或者避免大表的全表扫描问题,例如拆分表等等。

最后针对MySQL数据库运行情况,我们可以用show status; 和 show innodb status"G 来监测。

1 2  下一页

Tags:CentOS RoR 应用

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接