分享

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

 漂在北方的狼 2009-08-04

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

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

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

第三篇 新年了

随着圣诞和新年的来临,我们准备从另外一个方面来改变和优化系统以提高网站的性能和响应速度。(从以往看来节日期间是我们流量比较小的时候,人们更愿意花时间跟家人团聚而非泡在社区里)

×××,再次回到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发现 侦听虽被指定去处理连接,但是它坐在那里一动不动。当有一般的请求焊死在那里,这再明显不过是说它不能响应所有的请求。

(对于这些似乎你很眼熟,我以前在写过一篇文章叫“温柔地杀死我”)

使 用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。虽然对于业务来说不能持续的来监控它们了。
这个方法虽然看上去不漂亮,但它工作的很好,并且让我们熬过了一月来到了二月,配置如下:
February

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

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

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多