分享

一个RoR的站点性能优化的故事(2) | ityum.net

 漂在北方的狼 2009-08-04

一个RoR的站点性能优化的故事(2)

原文链接: http:///articles/2006/03/20/the-adventures-of-scaling-stage-2

中文链接: http:///2009/08/01/00/12/一个ror的站点性能优化的故事2.html

圣诞节前

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。

整个系统配置如下:

dcfq8s4f_10g6dt93fw

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多