论坛首页 编程语言技术论坛

关于rails大容量网站部署的性能讨论

浏览 174970 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-05-22  
这个帖子讨论到现在几乎是跟rails无关了,转贴一个email的案例,可以见到,在追求高性能目标下,设计出来的架构会是相当相似的,毕竟可以选择的途径并不算多:
http://www.huihoo.com/middleware/database/elong.html
0 请登录后投票
   发表时间:2006-05-22  
BerkeleyDB处理这种简单的内存数据库情况是绰绰有余了,而且也足够可靠。只要处理都是针对主键次键的(这里可以拿id作主键,时间作次键),没什么大问题.  就是比较起来有点烦. 但是如果需要象SQL那样的针对一般字段的条件的查询,那就死菜了,需要外面裹上一个架空层才行,即使这样,效率也会噼里啪啦往下掉。
0 请登录后投票
   发表时间:2006-05-22  
charon 写道
BerkeleyDB处理这种简单的内存数据库情况是绰绰有余了,而且也足够可靠。只要处理都是针对主键次键的(这里可以拿id作主键,时间作次键),没什么大问题.  就是比较起来有点烦. 但是如果需要象SQL那样的针对一般字段的条件的查询,那就死菜了,需要外面裹上一个架空层才行,即使这样,效率也会噼里啪啦往下掉。


主要是处理session也不应该用到很复杂的关系,不然的话,做下去会发现已经在实现数据库的部分功能了

关键的是,在这种做法中,session server只是提供了一个可以全局共享的内存存储空间,并通过自己定义对象在其中的存储来实现状态保持,说白了也就是个进行数据交换的临时变量作用。
0 请登录后投票
   发表时间:2006-05-23  
robbin 写道
测试了一下memcached的性能,从我的笔记本电脑连接到Linux Server上面的memcached,存取数据。结果相当满意,速度非常快,如果排除网络通讯的开销,存取cache时间不到1ms,Java已经测试不出来少于1ms的速度了。即使把网络通讯开销一起算上(100MB网卡),来回存取两次,速度也不到10ms。相信在良好的网络质量下(1G网络),速度应该更快。


但是我却不得不遗憾的说,memcached不适合Java应用程序!罪魁祸首就是Java序列化机制。


在我的笔记本电脑上Eclipse里面启动jetty5,如果不访问数据库,每次从响应HTTP Request到页面flush完毕,仅仅需要10-30ms的执行时间,即使访问数据库,在数据量很小的情况下,也仅仅需要100-200ms的时间。但是一次Java序列化操作就消耗掉30-50ms!如果每次请求都需要到memcached取得session信息,等于每个请求都要多执行40-60ms,这几乎是不可接受的。

memcached的其他客户端,例如PHP,Perl,Ruby的序列化的开销都不会像Java这样不可想像的昂贵,因此这些应用程序存取memcached完全没有问题,但是唯独Java序列化机制令人难以承受之重!我尝试用反射自己写了一下简单的序列化机制,开销也在15-30ms之间。因此只好放弃memcached。

从这里得到一个教训,凡是依赖Java序列化机制的性能都不会很好,例如很多应用服务器的Session复制就是这样。而我们的Java应用也好,部署方案设计也好,要极力避免操作Java对象序列化。另外值得一提的是,在测试过程中,无意中发现java.util.Calendar的getInstance()方法开销也极大,每次调用竟然需要40-50ms!因此请大家尽量避免使用Calendar,只是使用java.util.Date。


有没有测试过 java.io.Externalizable 的性能?
0 请登录后投票
   发表时间:2006-05-24  
引用
有没有测试过 java.io.Externalizable 的性能?


Externalizable自己不做序列化操作,要你自己写序列化代码。
0 请登录后投票
   发表时间:2006-05-24  
关于支持大容量网站的话题并没有结束,我最近正在做这方面的工作,等告一段落之后,再和大家分享我的经验。

先给出一组我刚刚做的web server处理静态资源的性能测试数据和结论,测试环境是2路Xeon2.8G,10KSCSI 73GB,RHEL4 SP3,Apache 2.2, Tomcat5.5.17(native IO)

ab -c 100 -n 100000 http://localhost/prototype.js

以上是用ab测试服务器处理静态资源的性能,从服务器本机发起请求,避免网络开销造成的测试误差。先看测试结果:

第一组对比测试:Apache的worker性能 vs prefork性能
apache(worker)   12% cpu load
引用

4112.33 [#/sec] (mean)
4073.56 [#/sec] (mean)
4121.81 [#/sec] (mean)


apache(prefork)  14% cpu load
引用

3928.06 [#/sec] (mean) 
3820.04 [#/sec] (mean)
3816.09 [#/sec] (mean)



结论:worker模式是进程加线程(我的测试中是默认的每进程25个线程),但是对于prefork这种纯进程模型来说,性能优势并不明显,仅仅有5%的性能优势,CPU负载差别很小,唯一的优势就是比较节省内存(节省多少内存无法精确测量)


第二组对比测试:apache处理静态资源 vs tomcat5.5 native io处理静态资源
tomcat 5.5.17 native io 30% cpu load
引用

3257.63 [#/sec] (mean)
3277.03 [#/sec] (mean)
3273.48 [#/sec] (mean)


结论:tomcat在使用native io以后网络并发性能得到了很大提高,比apache仅仅差了20%,不过cpu负载要高出两倍多。所以,静态资源请尽量交给apache处理。


第三组对比测试:apache vs apache mod_deflate
我们知道AJAX应用会附带庞大的JS文件,在第一次访问的时候,加载JS文件会
造成长久的等待,因此在服务器端压缩JS文件就显得非常必要,请看apache mod_deflate的压缩效果:
引用

压缩前
GET /scripts/prototype.js HTTP/1.0 200 55149
压缩后
GET /scripts/prototype.js HTTP/1.0 200 12467

这个是对prototype 1.5.0rc直接压缩的效果(未使用dojo compressor处理),还是相当明显的,从55KB压缩到12KB。我另外对prototype1.4.0进行压缩,效果也不错,prototype1.4.0原始文件47KB,使用dojo compressor压缩到了35KB,然后apache 再压缩,实际传输字节为8KB,相当不错。

但是apache进行压缩,显然会加重服务器端的负担,这种负担会否造成apache性能大幅度下降呢?
apache/mod_deflate 14% cpu load
引用

3679.65 [#/sec] (mean)
3705.49 [#/sec] (mean)
3637.96 [#/sec] (mean)


结论:有10%的性能下降,cpu负载变化很小,这说明apache端进行压缩的开销还是可以接受的,在损失了10%的并发性能同时,让用户下载JS的速度提高了3-4倍,其代价还是非常值得的


第四组对比测试:apache处理静态资源  vs apache proxy+tomcat处理静态资源
我最近上网看到很多人在配置apache proxy+tomcat的时候,都是一股脑把所有请求proxy给tomcat处理,apache退化为一个单纯的proxy。让我们看看这种方式下,静态资源的处理性能
apache proxy+tomcat  50% cpu load
引用

1752.05 [#/sec] (mean)
1765.82 [#/sec] (mean)
1759.72 [#/sec] (mean)


结论:有点惨不忍睹,tomcat自身处理静态资源的能力还是相当不俗的,瓶颈显然在于apache和tomcat之间的tcp端口通讯上面,我采用的方式是mod_proxy_ajp,性能已经比直接mod_proxy_http好很多了,但是仍然代价高昂,性能只有apache的40%,而且cpu负载非常高,这个教训告诉我们,多花点力气配置好apache,你会得到回报的。
0 请登录后投票
   发表时间:2006-06-02  
robbin的测试怎么没有动静了,偶还在等待结果ing
0 请登录后投票
   发表时间:2006-06-08  
yuxie 写道
robbin的测试怎么没有动静了,偶还在等待结果ing

快了。
赫赫
我们先一起做一个Ruby on Rails开源项目吧。

3五个人就行。

 
0 请登录后投票
   发表时间:2006-06-11  
同意楼主观点 其实在集群中所有共享的东西都应该放到集群外边 这包括 硬盘 内存 数据库 如果应将他们塞入集群内部 早晚会出麻烦.


也许解决性能最好的办法 就是分布式处理 让应用和数据都捆绑在一起

根本就不使用统一的数据库 让所有的数据都分散在系统里.
0 请登录后投票
   发表时间:2006-06-14  
charon 写道

没理解。
按照robbin的方案,浏览器端是不知道访问了clone1还是clone2的,而且部署在clone1/clone2上的程序也不知道自己是部属在哪个节点上的,而且,这个程序也不应该为了群集而作特别的处理。

为什么程序不应为群集做特别处理?可以配listen并在init参数里把节点名称配
进去.在cookie里设置上次节点,如果节点不一样,可以由数据库中读取数据,来
创建session,否则用原session.
charon 写道

第一次从clone1跳到clone2的时候,就会把cookie里面的jsessionid从clone1的换成clone2的。然后再跳回去的时候,因为不可能根据clone2的sessionid从clone1里面取出session来,所以只能新生成一个session,然后从cookie里面取出userid,从数据库里面取出userinfo.
这样,就不停的在两个clone之间跳舞了。还不如不把userinfo保存在session里面,每次直接在数据库中取好了。

负载均衡中有算法可以保证,同一ip对应一个节点,所以除非一个机器down了
一般不会跳舞的.
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics