Monday, October 20th, 2008
本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/10/qclub-ruby-on-rails/
周日(2008-10-19)下午,去听了听QClub组织的Ruby网站架构案例分享──财帮子&FreeWheel,本意是冲着架构案例分享去的,对Ruby On Rails知之甚少,很久以前和BLUG的一位外国朋友聊天,他说是做Ruby的,我说Ruby是日本人开发的语言,还没等我说完,这位外国的朋友说:It's just a language,nothin to do with Japanese,其实我的本意是这是日本人开发的语言,国际化方面可能会差一些,比如最原始的文档应该是日文的吧。看来我们总是被人误会啊。
首先是财帮子的Robin Lu(陆亦斌)给我们分享了一下他们的建站经历,先介绍一下财帮子的基本情况:
财帮子目前大概是100万PV/天,注册用户大概十几万
人均访问PV大概在15~20个左右
网站访问的峰值大约在基金净值出来之后,最高大概是430 Rec/Sec
最开始只有一台1U的服务器,应用和数据库都在上面,现在两台1U的服务器,应用服务一台,数据库一台
系统构建在Ruby On Rails上
使用lighttpd做负载均衡,30个左右mongrel实例
使用Munin和monit做服务器监控,跑了一些的cron任务(如数据备份)
他们遇到的第一个问题是前端负载均衡效率不高,最开始用apache的mod_proxy_balancer,发现有阻塞的情况存在,现在用的是lighttpd做负载均衡,他们觉得效果不错,据说还毙掉了nginx的方案,由于久做PHP,印象中前端负载均衡应该是把请求均衡到多台服务器上,初一听他们的负载均衡是把请求均衡到多个实例上,觉得甚是费解,一打听才知道mongrel一次大概只能处理一个请求,不太了解,不好评论。
他们的第二个问题是发现Ruby On Rails里面的数据库操作有大的瓶颈,大概是对数据库的操作始终在一个事务中,不到最后不commit,所以导致死锁的情况屡有发生。这让我想起Rasmus Lerdorf老大对PHP Framework的批判Simple is Hard(用IE会被鄙视的),Framework大大提高了开发的效率,却捆住了我们的双手。如果想要高的效率,那么就让ORM见鬼去吧。
他们还有一个好的建议是把动态内容和静态文件分开处理(当然这个建议已经被无数人说过了),这个确实非常有必要。
听完报告,问了下财帮子目前的瓶颈在什么地方,答曰:内存缺乏,跑了30个mongrel直接就吃掉了2G多的内存,确实够凶猛。这方面PHP算是不错了。
另外报告中还提到他们每天需要2~3小时去处理用户的账单,比如基金净值出来了,然后他们会计算每个用户的账单情况,这种做法不太看好,想想现在十几万用户可以算出来,将来多了呢?多台服务器并行计算?可计算成本呢?提前计算网站的活跃用户足够了,那些几百年才来一次的用户或者注册了再也不上的用户大可不必,等他们访问的时候再实时计算吧。
后面分享的FreeWheel讲的大多是项目开发方面的经验,我倒是觉得FreeWheel的做法不错,各种Framewok适合快速开发网站,不见得适合开发快速的网站。
感谢财帮子和FreeWheel的分享,技术其实就那么点事,还是开放一点好。
对Ruby On Rails实在了解甚少,上述内容如有不到之处,请不吝赐教。
Posted in Arch | No Comments »
Wednesday, October 15th, 2008
本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/10/another-way-of-sync-distributed-data-center/
通过Google Reader好友共享看到这篇文章:横向扩展(Facebook),之前看过英文原文,不过仅粗读了一下未求甚解,感谢译者的辛勤劳动。
看完全文,大意是Facebook为了解决跨地域的网络延迟问题,在东海岸新建了一个数据中心,可新的问题随之而来,MySQL数据库复制延迟、memcache缓存不同步,Facebook的工程师通过改进MySQL复制机制,在传递binlog的同时传递memcache更新指令。这样数据库同步了,memcache也更新了。
我将我的名字从"Jason"改为"Monkey"。
我将"Monkey"写入加利福尼亚的主数据库并从加利福尼亚的memcache中删除我的名字,但不包括弗吉尼亚的memcache。
某个人在弗吉尼亚访问了我信息。在memcache中找到了我的名字,并返回"Jason"。(注意这里,其他用户看到了过时的信息)
同步复制到了之后,将从数据库中我的名字更新为"Monkey"。还需要从弗吉尼亚的memcache中删除我的名字因为缓存对象出现在同步复制流中了。
另一个人在弗吉尼亚访问了我的信息,没有在memcache中找到我的名字,所以从从数据库读出名字,得到了"Monkey"。
关键的地方就在这里,Facebook有能力对MySQL进行改造,相信一般的公司是不敢的。其实也还有另外一种方式来实现,MySQL引入了一种叫做MySQL UDF(user defined function)的机制,有人也写了个Memcached Functions for MySQL的东东(基于libmemcached,我想应该是稳定高效吧),我们大可以在从服务器上创建触发器,这样一旦有数据更新,调用Memcached Functions for MySQL更新memcached缓存(如果写操作频繁的话,估计触发器也是瓶颈)。
文章的另一个核心是“页面路径选择”,Facebook约定了更新只在主服务器上(西海岸数据中心),东海岸的数据中心数据库服务器全部以slave形式工作,Facebook在最前端有一组负载均衡服务器,更加用户访问的URL来判断是否有写操作,如果有的话直接连接到主服务器上,如果只是页面显示则导向到从服务器上(也许是西海岸服务器),为了解决数据延迟而造成混乱的问题,Facebook在有更新的用户cookie里面加入一个标记,该标记创建后20秒内,都连主服务器(20秒足够对付延迟了吧)。
这是很有意思的一个设计,利用cookie标记用户是否更新过。但问题就是只是自己看到自己最新的数据,其他人有个20秒看到的是过时的数据。
其实是不是可以试试把标记信息放服务器端(如DNS解析部分),比如A用户更新了某些数据,在服务器端做下标记,20秒内请求到这些资源的时候走主服务器。标记大可以用bdb存储,效率就不是问题了。下面是流程:
我将我的名字从"Jason"改为"Monkey"。
我将"Monkey"写入加利福尼亚的主数据库并从加利福尼亚的memcache中删除我的名字,但不包括弗吉尼亚的memcache。
在服务器端标记我的名字改变了。
某个人访问了我信息,查出我的信息更改过,走主服务器。
同步复制到了之后,将从数据库中我的名字更新为"Monkey",触发器工作,删除相应memcache缓存。
20秒后,负载均衡端标记失效,另一个人在弗吉尼亚访问了我的信息,没有在memcache中找到我的名字,所以从从数据库读出名字,得到了"Monkey"。
也是很折腾的一种方案,我这里没有那样的环境,所以也只是理论上的思考,有条件的可以试试看效果如何。
Posted in Arch, 默认分类 | 1 Comment »