免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3963 | 回复: 7
打印 上一主题 下一主题

[Web] 一个RoR的站点性能优化的故事 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-28 21:52 |只看该作者 |倒序浏览
原文地址: http://enissue.com/archive/128



译者:
终于翻译完了这四篇文章,这次翻译的初衷是为网站架构华人社区弄一篇有一定意义的技术文章,用来庆祝其网站开张。这篇文章的意义不在于阐述了多少高深的技术,而是告诉我们“高手”是如何一步步逼近问题的本质的,国内还没有出现类似的文章,非常值得一看。现在翻译完了,赠与网站架构华人社区,对于转载该文请联系khan.chan[at]enissue.com,对于内容本身的问题可联系shiweitao[at]gmail.com
The original address of these Articles :
The adventures of scaling, Stage 1
The adventures of scaling, Stage 2
The adventures of scaling, Stage 3
The adventures of scaling, Stage 4

Author: Patrick Lenz (patrick[at]limited-overload.de)
一次网站升级的“冒险”
关于这一系列文章
许多大流量的网站都是由Rails支撑的,《WEB开发之道——应用RAILS进行敏捷WEB开发》(第二版) 这本书对于扩展你的应用是非常有帮助的.这个系列的文章是一个实际的例子,例子说明了“如何扩展你的Rail应用?”我会讲述一下我们在提高应用性能时所作的事情。
我们的整个性能调优过程,将分四篇文章来讲述,每一篇都是在我们扩展我们eins.de网站的一个里程碑。文章计划在一周内全部发表出来。

实际情况
我们的任务是重写全部代码,这个在线社区网络eins.de以前是用php写的,原来是一个代码膨胀而且架构的非常糟糕!作为一个在线社区,正如你知道的一样,网站包含如下功能:论坛、评论、个人主页、个人站内消息、编辑内容等等。另外,eins.de在德国的几个大城市都有当地的合作伙伴,他们是各个子版块的重要驱动力。各地的用户是在一个统一的单个数据集中。

原有代码大概由5万行php代码和另外一个闭源的CMS组成(CMS不计入代码行数统计中)组成。这次重写大概只用了5千行Rails代码,就实现原来的大部分功能(原来的一些个功能按计划在这此重写中被剔除了)。

eins.de 每天包含大概120万个动态页面,服务于25个子社区,每个社区是用不同的域名,但所有这些都在一个Rails应用中。然而,还没有到今年的二月,我们对系统配置和代码都做了优化,这样在才能处理如此巨大的流量。

这个网站存在许多动态页面和信息,动态信息是基于用户设置或像在线状态和相互关系状态。这些都是阻碍我们使用Rails本身提供的非常简单的页面缓存或局部缓存。
该应用服务器配置是dual Xeon 3.06GHz, 2GB RAM, SCSI U320 HDDs RAID-1.数据库服务器dual Xeon 3.06GHz, 4GB RAM, SCSI U320 HDDs RAID-1. 代理服务器是单台 P4 3.0GHz, 2GB RAM, SCSI U320 HDDs RAID-1.
在不改变硬件条件的前提下,我想准备通过配置优化和修改代码来提高性能,与此同时还要加上一些新功能。
在11月,我们最高每天能够支撑75w的PV(大约有60G的流量),到了来年的3月份,我们很轻松的能够支撑120w的PV(大约有100G的流量),最终性能提升了1.6倍。(译者评:技术真的都变成钱了啊!)

高峰时期通大概20M/每秒的数据通过代理服务器的网卡。(译者评:饿滴神)


well,任何人都不能改变历史,以下是我们以前的系统配置,也就是上面这个图中所示的软件的详细信息。
> Debian 3.1
> Kernal 2.4.27
> lighttpd 1.4.6
> Ruby 1.83 from Debian packages
> Mysql 5.0 from debian packages
> Ruby-Mysql 2.7 from RubyGems
> Ruby-MemCache 0.0.4

我们使用Rails中的 ActiveRecodStore来管理session,用 在数据库服务器上的token based single-signon 机制和 memcached来在内存中存储大数据量的计算。
两台数据库服务器通过master-master的方式相互复制,他们的自增ID是相互间隔的。(译者评:比如,一台的ID增长是1、3、5,另一台是2、4、6).具体实现参看《mysql手册的auto_increment_increment 和 auto_increment_offset.
haproxy 被用于外部的FastCGI 侦听的负载均衡,以及应用服务器的数据库链接通过它分发到两台数据库服务器上。
以上基本上是一个总体的介绍,性能的优化是非常难的一件事情。基于PHP的老系统处理到90万PV时就会崩溃(这就是说,只要以前一半的应用服务器就行了),而新的架构在巨大的150万PV的时候才会崩溃。这里面不存在突然会变成你所想像的那样好,所有这些变化都在此以前用了无数的日日夜夜coding才达到的。
紧急情况设计
是的,我们曾经正在缴费准备飞到巴哈马群岛,并呆在那。
FastCGI监听数目作为首要的方法从20下降到了10.说实话,原来系统的设置根本没法用.页面每次从开始load都有延迟,与此同时,对于系统做大可支持的负载的失望和一些没有耐心的用户还会重复load让事情变得更糟。用新的设置,这些事情会减少一些,而且快了许多。
过了几天,在新系统上线后,我们又采用了其它几个方法来提高性能,并且修复了一些在测试中没找到的bug.睡觉是多么美好和奢侈的啊。
我们做的几件重要的事情,使得这次升级更加成功:
>强烈指出haproxy,它仍有另外的变量能更调整,直接使用它并不会有明显的效果。所有应用服务器对于Mysql的链接都可以在文件中配置成像连接单个Mysql主机。
FastCGI 连接的分发由lighttpd返回。提示:我们发现要想请求真正均匀的分配到多台应用服务器上,你应该定制fastcgi。服务器的端口和IP的配置应该如下:
"http-1-01" => ( "host" => "10.10.1.10", "port" => 7000 ),

"http-2-01" => ( "host" => "10.10.1.11", "port" => 7000 ),

"http-3-01" => ( "host" => "10.10.1.12", "port" => 7000 ),

"http-4-01" => ( "host" => "10.10.1.13", "port" => 7000 ),

"http-1-02" => ( "host" => "10.10.1.10", "port" => 7001 ),

"http-2-02" => ( "host" => "10.10.1.11", "port" => 7001 ),

"http-3-02" => ( "host" => "10.10.1.12", "port" => 7001 ),

"http-4-02" => ( "host" => "10.10.1.13", "port" => 7001 ),>虽然局部缓存被认为对于用户是不灵活的(数据延迟,不再个性化),并且没有改进,但是还是要使用它。毕竟稍后问题都有反馈。
>停止同时使用两个memcached主机的想法,由于Ruby-MemCache库显然不能很好地处理。实现分布式的方式不是基于一个key,而是随机。让我们最头疼的就是分布式垃圾数据的到期问题。
>重构了工具条的代码,原来这段代码是用Rails中的component,有显示它是性能杀手。一般可以为每一个sidebar的显示设置完整的controller环境。(具体参见 RailsExpress)
>添加gzip的压缩作为after_filter(参见Rails 书中的例子)
>用Mysql slow query log参数来找出速度慢的sql语句,减少表的joins,优化索引。(呵呵,这个显然不是Rails的范围)
这时候已经到了11月,这个时候我们每天可以处理85万PV,似乎没做什么事情,你可以说“太简单了!”
我们新的简化过的设计如下:

第二部分将会着重讲述性能调优,包括mysql调优小技巧,FastGCI 请求分派调优,和更多的系统优化技术。


第二篇


圣诞节前
11月份,仍然还在旧系统的框架下,一些新的想法还是出的比较慢。
这并不能说是一次失败,我们尝试将一些可能的影响性能的因素都做了调整。


首先,我们用源码重新编译了Ruby,而不是使用Debian系统提供的二进制包。Debian有些时候基于某种考虑打了一些不太正规的补丁。在某些情况下,这样不失为一种好办法,然而为了性能,我们还是从源码重新安装了Ruby,甚至安装了专为i686优化过的libc6包。

与此同时,我们还将Debian提供的Mysql二进制包,改成了Mysql官方提供的安装包,并且将版本从5.0.16升级到5.0.17。
(译者评:Debian/Ubuntu这类linux发行版中,还是自己编译吧)

一般说来,Mysql5已经被证明是非常稳定的产品。我们曾经碰到过一点点数据同步复制的问题(master-master中有出现重复自增ID的情况,这个在5.0.19中已经修复了这个bug),但有时候Mysql数据库每秒中查询达到2000-3000次的时候,后台守护进程经常会在几个月内崩溃一两次。

让我们具体谈谈Mysql吧

如果针对数据库的配置错误或者优化不好的话,它很容易拖慢整个系统。有许多书都是专门讲数据库优化的比如whole bookswebinars 。我在这里就简单的介绍一下。

eins.de利用了Mysql的 全文检索 Full TEXT来做搜索功能。MyISAM存储引擎不能支持事务。你可以用InnoDB和MyISAM两种引擎结合起来用。
解决问题有一下几个办法:
1.另买一台数据库服务器,用MySIAM类型的表,然后从类型是InnoDB的Master数据库表中(我听说Flickr是这么做的)。然而这样就需要仔细的设计程序,得以突破Rails的局限性,Rails不能很好的区分读数据库和写数据库。即便能这么弄,我们也不会走这条技术路线,因为我们没有预算来买第三台数据库服务器。

2.不去使用全文检索, 可以使用类似Ruby-Odeum 这样的搜索引擎。这里面比较头疼的是,如何让数据库地更新时,同时搜索引擎索引也重建索引保持数据同步。这条路我们也不选择。

这样我们最终使用了一种混合的方式。
当前,可用的内存有4G,将它分成InnoDB和MyISAM两部份。2/3的内存给InnoDB用(因为这系统主要的表用的是InnDB,还用于缓存MyISM表的索引数据)
剩下的1/3是给MyISAM的。另外,我们使用了查询SQL结果的大缓存,也就是Mysql中的query cache。(这个参数是否被用起来了可以通过Mysql的show status命令来看)

我们数据库参数设置如下:
key_buffer=700M
myisam_sort_buffer_size=128M
query_cache_size=64M
innodb_buffer_pool_size=1600M
如果前端的分发器是单个服务器,并且是持久连接,数据库连接数的参数设置就没有什么必要了。
继续进行应用服务器的优化
对于系统进行反复的研究找出一共有多少请求是非常有用的。这个是没有“一劳永逸”的解决办法。一般说来,你需要包含系统高峰时期并且不能当机,如此大量的线程并行运行以至于机器变慢,这是因为对于CPU来说线程相互之间是阻塞的。

以前我们在每台服务器上设置20个并发时,系统的负载一般都是在30或30以上。事情进展的非常顺利,我们降低了并发数量。这样的效果非常明显。
通过简单的计算,我们从一天PV数量计算出整个的监听数量。eins.de那时大概每天100万PV,所有的用户都在同一个时区,访问遍布在一天的14个小时中(从早上9点到晚上11点)。我们再做一个简单的计算:
1M page requrest / 14 hours = 20 requests per second

假设系统平均处理每个页面请求都会少于1秒中,那么我们需要20个并发进程来监听请求。以上计算是根据平均值进行的,为了能够处理高峰时的峰值,我们将每台应用服务器的监听数目从10减小到7,这样四台应用服务器加起来一共有28个监听,应该能满足当前压力的要求。

(译者评:一般峰值是平均值的5-10倍,根据各自的网站特点来确定)

另外,每台机器上安装的Rails从0.14.4逐步升级到了1.0.虽然这对性能不一定有帮助,但是说不定是有用的。
到了11月中旬,据报道Linux 内核2.6对于性能、内存管理和进程管理等等都是非常好的,因此我们将所有的系统的内核从2.4.27升级到了2.6.14。
大家对这个内核升级对性能的提升将信将疑,后来根据监控软件Cacti的显示,系统升级后确实提高了不少。数据库服务器虽然提高不少,但应用服务器的负载却
下降得非常明显。记录显示内核的升级使得系统在高峰时期的负载从8降到了5。

升级内核所取得的效果让我们有了些兴奋,我们继续所做的事情是将应用服务器的压力再次给到两台数据库服务器上。在此以前,所有的压力都是由一台机器支撑的,另外一台只是安静的呆在那儿复制主力数据库的数据,仅仅是主力坏了它来顶上的灾难恢复而存在的。

我们没有去考虑haproxy的灾难恢复,只是简单的将请求按照2:1的比率分配到两台数据库服务器上。

在写的压力很大的时候,偶尔会出现两台数据库同步不能跟上的问题,直到一台的写处理完才能恢复。如果碰上几秒钟这种倒霉的事情,一个用户可能一次请求在一台数据库服务器上,而另外一次则在另一台上,这样就比较尴尬。举一个最糟糕的例子,AJAX开始的时候请求了一台机器,而后AJAX执行的操作却从另外一台获得,数据是不同步的造成了混乱。

为了减少写操作,我们经用户证明发现在用户没有获取任何有用数据的时候,系统不仅通过ActiveRecordStore更新了session,而且更新了用户的在线状态表和token数据。事实是,虽然多个MySQL线程能够更新多张表(甚至能通过InnoDB的行级锁来一次更新一张表里面的多行),但是你只能有一个线程来处理将所有的写操作写到另外一台服务器上。这个问题困扰了我们不止一次。


另外,我们将缓存memcached在两个数据库上移来移去以更好的分摊机器的压力,让另外一台机器来处理广告信息phpAdsNew (译者评:一个广告投放系统)

在11月底,我们完成了以上这些事情,到目前为止我们已经多次达到了百万PV的情况,流量每天已经达到了85G。

整个系统配置如下:


到此系统调优的文章已经写了2/3,后续文章将会包括memcached的最佳实践,session的优化以及更多系统优化技术。

论坛徽章:
0
2 [报告]
发表于 2007-12-28 21:53 |只看该作者
第三篇 新年了
随着圣诞和新年的来临,我们准备从另外一个方面来改变和优化系统以提高网站的性能和响应速度。(从以往看来节日期间是我们流量比较小的时候,人们更愿意花时间跟家人团聚而非泡在社区里)

×××,再次回到memcaced的优化上来了。通过debug发现了我们memcache封装的问题(它是负责通过key来自动查找社区名和用户名,或者社区名或用户名),许多在memcached的查找都失败了。查找本身并没有失败,而是从memcached中返回的对象实例有部分“失败”了。

这句话什么意思?也就是说花费时间很长的计算结果被放到了缓存中,但是重新从缓存中获得它们的时候失败了。结果再次从新计算(这时memcache封装里面的一个回退机制)。因此没有达到我们认为的节省时间、降低负载的效果。

然而,这个跟先于对象定义的Ruby声明的类没有关系,显然和返回的marshalled数据有关。在Google上面搜索了这个错误信息没发现任何明显犯同样错误的人,也没有任何解决办法。
(译者评:看看别人解决问题的过程比知道优化技巧这样的结果更加重要,比如作者也走过很多盲目的弯路,但这些弯路也是思考问题的方式

通过查看Debian的更新日志提到了一些 Ruby 1.8.4关于marshalling,并一次同时在Rubyonrails.org’s download page 看到了如下信息:

We recommend Ruby 1.8.4 for use with Rails. Ruby 1.8.2 is fine too, but version 1.8.3 is not.
因此升级了Ruby,我们从升级到了1.8.4,重新编译了所有C扩展的的包,比如Ruby-MySQL和RMagick,然后上线看看。
结果是没有变化!

接着在一月的第三个星期,Robot Coop 发布了他们的memcache-client 库,作为Ruby-Memcache的替代,现在后者的开发停止多时了。
使用新的memcache-client库系统运行得非常流畅。它甚至做了我们自己封装的memcached包装器的大部分工作,请大家为Robot Coop的工作欢呼三次,太伟大了!

由于有了如此好性能的memcahced我们冒险向前走了另外一步。我们将session的存储从ActiveRecordStore(读Mysql表的存储)移到了memcached中。我们希望通过这样做也是为了减少前面所述的Master-Master模式中只有一个线程往另一个Master中写的压力。同时,这样也能将每次请求页面而需要到数据库的比例比11月份上线时减少了1/3。
另外通过Robot Coop memcache 客户端我们可以有理由去跨多台机器做分布式缓存。memcached对于我们大部分的机器无论是在内存消耗上,还是CPU使用上都是非常不错的。
我们临时将所有机器都配置上memcache来应对它的连接数问题。为什么说是临时的?因为我们有个登录问题需要debug出来。有时侯我们不能去再次使用我们自己的机器。用户像是坐在一个很大的公司中,有太过敏感的防火墙和内容过滤器,以至于其它人不能再登录进来。
许多问题随之被发现了,他们甚至没有看见我们种的且将过期时间设置为2010年的cookies。为了让他们看见,我们甚至尝试换个cookie名字(这样做是为了想避免一个自己的胡乱猜测,什么以session命名的cookies会在浏览器关闭的时候就自动过期)
(译者评:笑可笑之人,有时候找不到问题,不就是根据自己一点点经验去胡乱尝试么?这也是技术的一部分)
多台机器分布式的memcached的配置和session的存储有过什么联系么?哦,天知道?最后没有人清楚的记得当用户登录正常时,是不是我们只是做了将用memcached做session存储这一件事让它的好的。(这一个改变对于我们系统减轻了许多压力)

为了简化调试(也为了减少潜在的隐患)我们又返回去用单台机器配置一个memcached和一个MySQL的做法。memcached放在一台(只做数据同步和广告服务)比较空闲的数据库服务器上。顺便提一下memcached的配置非常简单。经常需要去变的参数是分配的内存大小,需要记住的是分配的内存可以很大,但memcached也必须去调度这么大的内存空间。到了一定时候它将会到达它的极限。我们当前给memcache了1024M的内存空间,这个对于文本信息绰绰有余。
这是基于我们系统7周时间的memcached的统计数据。(不要问过关于二进制字节的读写比率,我认为这是颠倒的???)
get_misses: 59,571,775

get_hits: 235,552,563

total_connections: 2,002,697

bytes_read: 79,799,051,834

bytes_written: 734,299,301,670

curr_items: 1,421,982

total_items: 76,452,455

cmd_set: 76,453,343

cmd_get: 295,124,338

bytes: 717,612,826登录的错误也在不久以后解决了,原因是当关闭浏览器的时候cookie就过期了。无论什么原因?这个问题的解决没有太多的逻辑推理。仅仅是找一种便于管理的

折中办法才行。

(译者评:对称是种美,与其将cache散落到各处,不如简单点让一台没有压力的机器单独来承担。不对称也是一种美,两台数据库服务器,只在一台上装了

memcached)


出现新的访问速度变慢的问题

在一月份的前半个月我们一天就可以支撑110万的流量,此时的流量达到了95G。接着到了一月份的后半个月系统出现问题,几乎不能工作了。虽然以前我们所做的所有修改和调优(原本这些都非常好),但我们碰到了新问题,发现系统在变慢。
是正常的变慢,还是糟糕的变慢?实际上是不好的变慢。到了一月份的最后一周变得跟去年11月份一样慢了。为什么会这样?哦,这是一个好问题。我们已经优化了系统的每一个部分(如果你读完了这一系列文章,你也应该清楚)。在过去的几周内,事情看上去都不错,但现在我们又回到了开始时那样。
先还是把系统结构图图画出来吧,这样清楚些,不如从图中找问题。(译者评:我就是在机器上傻看数据,退一步看看整个架构更容易发现问题)
我们首先发现是整个系统全部变慢,甚至有时候不能访问,但所有的机器压力还是很小,应该说是太小了。调整lighttpd的fastcig。debug发现侦听虽被指定去处理连接,但是它坐在那里一动不动。当有一般的请求焊死在那里,这再明显不过是说它不能响应所有的请求。
(对于这些似乎你很眼熟,我以前在poocs.net写过一篇文章叫“温柔地杀死我”)
使用tpcdump来监控侦听端口的流量,什么也没有,没有一个字节通过管道。使用strace来看看那些忙一些的侦听在干什么,它们在wait,也没有做任何事情。郁闷的是,如果你重启lighttpd或者×××,最终和开始看到的一样。我的同事对防火墙做了各种配置,我开始调整应用服务器和lighttpd代理服务器的/proc的参数,我猜测是到了某个参数的上限。用netstat也发现有几百个连接在那些管道中,状态都是TIME_WAIT和CLOSE_WAIT,很像遭受了synflooed攻击。但这是我们内部机器,不会被外面看到。下一步,根据公共可利用的资源来调整/proc中的参数,具体如下:


echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range

echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

echo 1800000 > /proc/sys/net/ipv4/tcp_max_tw_buckets

echo 256000 > /proc/sys/net/ipv4/tcp_max_syn_backlog

echo 1024 > /proc/sys/net/core/somaxconn

echo "128000 200000 262144" > /proc/sys/net/ipv4/tcp_mem

echo 2097152 > /proc/sys/fs/file-max

echo 0 > /proc/sys/net/ipv4/tcp_timestamps

echo 0 > /proc/sys/net/ipv4/tcp_window_scaling不要在家使用这些命令,因为它一点都没有帮到我们。请求始终停在那,网站的性能让人看上去恶心。另外一个人企图在每个应用服务器上都启动一个lighttp

(这样来代替远程的fastcgi侦听),然后放一个lighttp的负载均衡的方向代理在前面。事实证明系统还是慢。

剩下比较“土”的办法,我写了一个脚本来搜索所有的可用侦听,如果它们在一定周期内没有响应,就kill它。被kill的请求会有Rails的spinner/spawner很快的重新

启动,lighttpd只是多花几秒钟来重新连接socket。虽然对于业务来说不能持续的来监控它们了。

这个方法虽然看上去不漂亮,但它工作的很好,并且让我们熬过了一月来到了二月,配置如下:


剩下最后一篇是关于系统扩展性的问题,也总结一下,哪些有帮助,哪些没有,同时展望一下将来系统调优的计划。

第四篇 速度快和稳定

在2005年的11月至2006年的3月,许多优化的工作都在这期间完成。这里面不少工作都不得不变成了配置的一部分(比如第三篇提到的请求分发的监控脚本)。最终经过了几周的运行,这个网站被证明是稳定且速度快的。另外,我们也已经能完成一点从用户和社区运营人员那里的需求。

完成过程中的闪光点

二月份,一些小的调整让系统性能变得更好。
第一,当用户编写个人消息和在论坛发帖时,我们利用AJAX来对其内容进行预览。虽然这不是性能的杀手,但把这因素剔除来减轻压力是有意思的。呃,在AOL浏览器中prototype会崩溃。
另外,将作为lighttpd守护进程对待。这样崩溃的现象在1.4.8及以后的版本就很少出现了,但仍然需要监控进程的情况。要知道如果lighttpd down了整个网站就down了。所以得看好它。(译者评:这里可能会出现单点失败的情况,clear & dirty)
将lighttpd作为daemontools 来跑是非常简单的。简单配置以后(具体配置这些写得很清楚 http://www.thedjbway.org/daemontools.html)你在ROR的service树下面用一行脚本来用damontools 配置lighttpd服务。你会知道并且爱上Rails最初的script/server。

#!/bin/sh
/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf

这样就启动好就运行了。你可以通过lighttpd的配置来简单的设置一下,发送lighttpd的进程ID或这信号SIGINT到你后台的监控中。然后需要注意的是如果你的网站流量非常大就需要把那些不能再完成了服务请求通过SIGKILL杀死。新发布的lighttpd1.4.11分发请求时候的僵死越来越少了,似乎这种情况完全没了。但我们将继续通过脚本监控它。

到此是这一些列文章的结束了。现在服务器每天支撑1.2M的PV(100GB的流量)。

总结以及以后的计划

以下是这四个月被证明是非常有用的优化手段:

系统优化:
>使用Linux 2.6代替2.4
>使用自己编译的Ruby 1.8.4
>使用Mysql官方的二进制版本
>使用lighttpd 1.4.11代替以前的
>使用memcache-client代替Ruby-MemCache
>使用了更少数量的dispatchers
>并且监控你的dispathchers

代码优化:
>避免使用ROR的组建 components
>用memcached储存费时的计算
>用memcached来存储session
>如果你的站点很受欢迎就不要使用live-previews
>使用异常通知exception notification来捕捉可能的异常

另外不要完全相信这些总结。优化是一个发展中的东西。

你需要一直对网站进行监控,包括你的服务器和所有相关的软件。
强烈建议不仅仅只监控服务是否起来了,还好监控服务器的压力,响应时间等等。用Nagios和Cacti结合起来做这些工作被我们证明是很有用的。
提醒注意的是,需要读读所有你使用的软件包的改变日志,看看新的版本中解决了什么已经存在的问题,可能产生哪些新问题。不需要强制升级所有的更新,但对你正困扰的问题在新版本中别解决了,你就一定要升了。你可以在测试环境中进行测试,减少当机时间,避免升级带来的潜在问题。

请留心你网站代码的变化。一般来说,应该多想想我要做什么。一个像Rails这样聪明的框架会让你有机会去思考,而不是每天写些重复性的代码。要聪明的使用时间。
一条SQL语句或单个循环可能在你开发用的笔记本上跑的很快,但是在产品环境中同时并发执行成百上千次或产品中数据量比较大都有可能导致网站变慢。
性能调优准则
总的来说,不太容易把网站的性能调节好。
一种方式是让网站处于非生产状态,也就是测试状态,自己产生一些流量来测试,这样的流量不同于真实的用户产生的流量。这样模拟的网站数据集也不同于线上的正式产品。这种情况下所有的调优结果都要根据线上真实网站的情况进行一下转换。
另一种方式是对线上实际网站逐步地进行性能调优。这样有许多好处,你有真实的用户在使用你的功能,使用你的系统,正如数据一样所有这些都是真实的,比测试环境有价值的多。但这种方式主要问题是,如果你的网站访问量特别大,系统的日志production.log将会大量快速的被写到硬盘上,这样你就很难找到问题。如果做日志的分离,将实际的日志相互关联起来也不太容易。那么将日志重定向成系统日志Syslog(通过 SysLogger,在RailsAnalyzer Tools包里面),它能将每个日志同一个线程ID关系,这样就非常方便了。
写大文件的日志意味这你整个系统的IO补偿糟糕,如果你在产品环境中不要写太多太详细的日志,系统将会比你测试的结果跑得好得多。
哦,当网站调优时,拆分用户将会有比较好的效果,但更重要是的要不断听声网站的使用体验。
使用过的工具:
将前面提到的Rails Analyzer Tools包放在手边,这些工具在类UNIX系统里面非常管用。你还需要会几个命令,cat,tail,grep,awk,ps,netstat。另外,安装一下ngrep和tcpdump来debug网络流量,还可以用mytop来查看Mysql线程列表。
把这些都准备好需要一些时间、耐心和知识,也偶尔需要Google搜索一下。
将来还要处理的事情
随着memcache-client库的发布,Robot Coop公司又发布了另一个小的库,名字叫做cached_model,这是基于memcached用于减轻数据库重复查询,原理就是在查询之前通过子类Active::Base来检查memcached中的内容。
我在1.0版本它出现的时候,看过一下,觉得还是很有发展的。那个时候它不能很好的集成,经常胡乱抛错。由于当时我们忙于调试其它的问题,就没有仔细地去解决这些问题。在此期间,cached_model版本升级到了1.1.0,也修复了多个bug。这个东西也将包括与我们将来优化的路线图当中了。
在第三篇的时候我们碰到了一个“分发请求僵住”的问题,我们将回来再看看FastCGI ,更通常的办法是用lighttpd也支持的SCGI。
有Zed Shaw发布了新的软件Mongrel 已经开始出售了。它作为“比WEBrick”更好的应用服务器,将纯HTTP放到FastCGI中,非常值得多看看。在读者评论中
有人说早期Dan Kubb提到用Canditional GET ,它的潜在好处是在缓存页面不变时它可以用浏览器来缓存页面。我只是简单地看了一下它的标题,Rails插件看上去还不错,很容易集成进来。
有个比较大的变化,尽管我曾经提倡使用Mysql的全文检索,但现在我正在基于Rails的一个搜索插件工作,它很容易无缝滴集成到HyperEstraier搜索引擎中。如果它跑的很好(性能好和数据保护),我们将丢掉全文检索,弄一个纯InnoDB的数据库配置,并且向锁表和非事务的测试说再见了,同时这样也不能使用ROR的schema.rb了。
说道这里,我们升级到了了最近的Rails1.1。尽管这次升级对于性能并没有太大的必要,但是它有另外受欢迎的地方,它使得我们代码变得漂亮简介了。
谢谢看过这一系列文章的人们。我真诚的希望我对我们案例的详细描述能够避免再去做我们已经做好了的一些研究和调试工作。如果你需要任何帮助,只要记下我的email,通过联系limited overload我可以作为咨询顾问来帮助你。

论坛徽章:
0
3 [报告]
发表于 2007-12-29 00:46 |只看该作者
不错的文章  我更在乎mysql的优化

论坛徽章:
0
4 [报告]
发表于 2007-12-29 17:19 |只看该作者
好难得的一篇文章!!!

论坛徽章:
0
5 [报告]
发表于 2007-12-29 23:50 |只看该作者
MySQL的优化 需要联系实际数据, 而且确实蛮复杂的


国内RoR的站点比较大的应该也就只有财帮子吧 ?

有谁讨论下?

论坛徽章:
0
6 [报告]
发表于 2008-01-10 13:37 |只看该作者
很不错的文章,细细拜读!

论坛徽章:
0
7 [报告]
发表于 2008-01-25 15:30 |只看该作者
好文,多谢分享...

论坛徽章:
0
8 [报告]
发表于 2008-03-04 13:12 |只看该作者
支持一下。受益匪浅!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP