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

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

浏览 174985 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-05-11  
robbin 写道
呵呵,我现在设计的网站部署方案几乎就是照抄rails的群集部署方案:

lighthttpd作为web proxy,兼有处理静态资源(js,css,images),页面cache,和loadbalance/failover的功能(如果不是为了failover,我直接用iptables进行端口转发是速度最快的loadbalance);

后面n个tomcat clone来处理业务,不使用Hibernat二级缓存,用户ID使用cookie,不在session里面保存和标示状态,因此tomcat clone的数量可以近乎无限扩展。

memcached用来作为全局共享变量的holder,在spring里面配置一个bean去封装对memcached的访问,这样访问memcached的全局共享变量和过去访问JVM内部的全局共享变量的方式从编程接口上来说就根本没有任何区别了,桀桀。

好完美的一个群集部署方案啊,谁来挑挑刺?


如果不使用session,影响最大的可能就是身份验证部分。而这里还是缺乏一个好的开源的的单点登陆框架。我们现在用hession来远程调用身份验证服务器的信息,导致这台服务器压力很大。CAS简单看了一下,太复杂,好多功能用不到。~robbin能不能介绍一下这方面的经验。

如果不考虑失败恢复的话实现集群都是很简单的,还是用session,前端加四层交换机根据客户信息的hash分发,保证同一的客户请求分发到同一个server/domain。

另外对于这个  “memcached是自己开了一个服务,监听一个端口,对外提供服务,本质上就是一个大HashMap,但是可以对外提供服务。” 现实意义很大吗?如果cache里边的数据要通过远程访问才能得到,那cache不cache感觉意义已经不很大了。不过这的确是这种无限扩展集群不可避免的。
0 请登录后投票
   发表时间:2006-05-11  
Readonly 写道
robbin 写道
好完美的一个群集部署方案啊,谁来挑挑刺?

文件共享系统和数据库集群没有谈到怎么做...


文件共享其实没有什么好说的呀,nfs就可以,虽然性能不算高,硬件投入足够话,多华丽的方案都可以做。先暂时用nfs了。

数据库群集是Oracle自己的功能,也没有什么好说的。
0 请登录后投票
   发表时间:2006-05-11  
yuxie 写道
robbin 写道
呵呵,我现在设计的网站部署方案几乎就是照抄rails的群集部署方案:

lighthttpd作为web proxy,兼有处理静态资源(js,css,images),页面cache,和loadbalance/failover的功能(如果不是为了failover,我直接用iptables进行端口转发是速度最快的loadbalance);

后面n个tomcat clone来处理业务,不使用Hibernat二级缓存,用户ID使用cookie,不在session里面保存和标示状态,因此tomcat clone的数量可以近乎无限扩展。

memcached用来作为全局共享变量的holder,在spring里面配置一个bean去封装对memcached的访问,这样访问memcached的全局共享变量和过去访问JVM内部的全局共享变量的方式从编程接口上来说就根本没有任何区别了,桀桀。

好完美的一个群集部署方案啊,谁来挑挑刺?


如果不使用session,影响最大的可能就是身份验证部分。而这里还是缺乏一个好的开源的的单点登陆框架。我们现在用hession来远程调用身份验证服务器的信息,导致这台服务器压力很大。CAS简单看了一下,太复杂,好多功能用不到。~robbin能不能介绍一下这方面的经验。

如果不考虑失败恢复的话实现集群都是很简单的,还是用session,前端加四层交换机根据客户信息的hash分发,保证同一的客户请求分发到同一个server/domain。

另外对于这个  “memcached是自己开了一个服务,监听一个端口,对外提供服务,本质上就是一个大HashMap,但是可以对外提供服务。” 现实意义很大吗?如果cache里边的数据要通过远程访问才能得到,那cache不cache感觉意义已经不很大了。不过这的确是这种无限扩展集群不可避免的。


用cookie就可以实现单点登陆,这没有什么好说的(只要根域相同)。对于web节点群集来说,有很多办法,最简单的DNS轮询就可以搞定,这个方面资料可以自己Google。

要强调的是,我的群集方案里面并不需要对web节点做群集,如果lighthttpd顶不住,用硬件就好。前端使用lighthttpd做为web proxy,这个lighthttpd是单点的,没有多个节点,不存在需要单点登陆的问题。我的方案是对应用服务器层做水平群集和全局状态的单点管理的。

Cache是干吗的?Cache就是避免访问数据库的昂贵开销的,不管Cache 是不是分布式,只要Cache比数据库快一个数量级,并且可以有效降低数据库负载,这个Cache就是有效的。

当然分布式Cache一定比JVM进程内部Cache访问速度慢,但是只要比数据库快很多就足够了。更何况在群集环境下,JVM内部Cache的同步复制的开销随着节点的增加而激增,最终你一定会发现memcached这种分布式Cache是最有效的解决方法。

而为了保证应用服务器群集节点的无状态幂等性,我必须保证JVM进程内部不保持全局状态变量,那么这些信息放在哪里?放在数据库或者共享文件存储系统性能都不够好?而memcached就是答案!

另外在复杂的web应用中也会大量出现需要异步消息操作的情况,我需要一个queue来保持异步消息。JMS是一个解决方案,但是常见的OpenSource JMS的性能都不会有memcached这么高,我宁愿使用memcached,别忘了,memcached本身也可以群集,而且memcached是使用Unix C编写的,使用了libevent库,性能不知道比纯Java的OpenSource JMS好多少。

BTW:其实JMS并不是一个高效的异步消息服务器,JMS的优点在于功能非常丰富,特别是在CMT的配合下,可以实现异步消息的事务机制。而凡是追求高性能的消息服务,都往往会抛弃JMS,特别是SP行业。
0 请登录后投票
   发表时间:2006-05-11  
多说一句cookie和session的群集解决方案。我现在是这样做的:

用户登陆的时候给他一个cookie,存放userId,使用32位uuid(Hibernate生成),不使用int,是为了避免被hack。此外同时给这个用户分配一个Session,存放user对象。

然后我再写一个webwork Interceptor,拦截所有的动态访问请求,如果他有cookie,但是没有session,就根据cookie里面的userId查数据库,给他session里面放入user。

这样就很完美了,例如用户在clone1上面登陆,然后用户请求被分发到clone2,这个时候clone2上面有cookie无session,但是我的拦截器会用cookie查数据库给他session。这样每个节点只需要访问一次数据库设置session而已。而应用程序里面照常使用session,从session里面拿user对象,不需要改一行代码。只要该节点有session,就直接使用session,如果该节点无session,就从cookie里面去userId访问数据库设置一次session。兼顾了性能和群集部署的无状态,哈哈,完美吧。
0 请登录后投票
   发表时间:2006-05-11  
就是说
现在
使用memcached集群 处理全局变量

一般web server(或者app server)集群在session中 处理 处理全局变量

要快?

不过servlet specific没规定session怎么实现,那么web server(或app server)之间共享的session的效率能够改进到超过memcached吗?

毕竟采用上面的方法有点限制(使用cookei)
0 请登录后投票
   发表时间:2006-05-12  
robbin 写道
多说一句cookie和session的群集解决方案。我现在是这样做的:

用户登陆的时候给他一个cookie,存放userId,使用32位uuid(Hibernate生成),不使用int,是为了避免被hack。此外同时给这个用户分配一个Session,存放user对象。

然后我再写一个webwork Interceptor,拦截所有的动态访问请求,如果他有cookie,但是没有session,就根据cookie里面的userId查数据库,给他session里面放入user。



虽然没有做cluster,但现在我大概也是这么用cookie的,不过我还往cooki里放了多一点的信息,希望减少一些数据库的查询.不过我没有用webwork,而是用了servlet filiter来拦截,因为用的是spring的mvc

看来robbin也还没在开发应用ruby啊

p.s:问个题外话,在jsp和freemark中,哪个处理页面的速度最快?和PHP相比呢?
0 请登录后投票
   发表时间:2006-05-12  
robbin 写道


memcached用来作为全局共享变量的holder,在spring里面配置一个bean去封装对memcached的访问,这样访问memcached的全局共享变量和过去访问JVM内部的全局共享变量的方式从编程接口上来说就根本没有任何区别了,桀桀。

好完美的一个群集部署方案啊,谁来挑挑刺?


Here is some opinions from Wikipedia developer in 2004 (see http://www.linuxjournal.com/article/7451 ) , since then memcached had some improvements (see http://cvs.danga.com/browse.cgi/wcmtools/memcached/ChangeLog?rev=HEAD&content-type=text/plain ) :

引用

Submitted by timstarling (not verified) on Wed, 2004-07-14 01:00.

Memcached's big claim is that it's faster than a database, which may well be true. But with no local caching, it certainly can't compete with a true distributed memory system like those commonly used in supercomputers. With memcached, if you have a data item which is needed on every web request, then that data item will be sent across the network from the same server on every request.

Memcached also has a lingering problem with slabs reassignment. If your application uses one particular size class heavily, and doesn't use another size class, then writes to the unused size class (when they eventually occur) will fail. The daemon can't automatically recover memory from the other slabs for use in an empty slab. Similarly, it's not a true LRU cache, the item dropped will always be an item from the same slab. The lifetime of an item in the cache is skewed due to differing amounts of memory allocated to each slab after a restart.

At Wikipedia, we've also had perennial problems with writes failing, probably due to high load from other processes on the server leading to a connection timeout. This is unfortunate when the write is an important cache invalidation operation.

Tim Starling (Wikipedia developer)
0 请登录后投票
   发表时间:2006-05-12  
robbin 写道
呵呵,我现在设计的网站部署方案几乎就是照抄rails的群集部署方案:

lighthttpd作为web proxy,兼有处理静态资源(js,css,images),页面cache,和loadbalance/failover的功能(如果不是为了failover,我直接用iptables进行端口转发是速度最快的loadbalance);

后面n个tomcat clone来处理业务,不使用Hibernat二级缓存,用户ID使用cookie,不在session里面保存和标示状态,因此tomcat clone的数量可以近乎无限扩展。

memcached用来作为全局共享变量的holder,在spring里面配置一个bean去封装对memcached的访问,这样访问memcached的全局共享变量和过去访问JVM内部的全局共享变量的方式从编程接口上来说就根本没有任何区别了,桀桀。

好完美的一个群集部署方案啊,谁来挑挑刺?


感觉robbin 似乎遗漏了很重要的一点。 PersistenceContext在你说的水平扩展方案中不能选择extended scope 的,而是使用transaction scope的。

二级缓存的话,一个办法就是干脆不用,这样一来,ejb在二级缓存优化那一块都白做了。
另外一种选择,提供一种共享/集群的二级缓存策略。 不过性能我就那不准了。
0 请登录后投票
   发表时间:2006-05-12  
firebody 写道
robbin 写道
呵呵,我现在设计的网站部署方案几乎就是照抄rails的群集部署方案:

lighthttpd作为web proxy,兼有处理静态资源(js,css,images),页面cache,和loadbalance/failover的功能(如果不是为了failover,我直接用iptables进行端口转发是速度最快的loadbalance);

后面n个tomcat clone来处理业务,不使用Hibernat二级缓存,用户ID使用cookie,不在session里面保存和标示状态,因此tomcat clone的数量可以近乎无限扩展。

memcached用来作为全局共享变量的holder,在spring里面配置一个bean去封装对memcached的访问,这样访问memcached的全局共享变量和过去访问JVM内部的全局共享变量的方式从编程接口上来说就根本没有任何区别了,桀桀。

好完美的一个群集部署方案啊,谁来挑挑刺?


感觉robbin 似乎遗漏了很重要的一点。 PersistenceContext在你说的水平扩展方案中不能选择extended scope 的,而是使用transaction scope的。

二级缓存的话,一个办法就是干脆不用,这样一来,ejb在二级缓存优化那一块都白做了。
另外一种选择,提供一种共享/集群的二级缓存策略。 不过性能我就那不准了。


PersistenceContext我认为transaction scope是最合理的。我看Hibernate也是这么推荐的。而且PersistenceContext要跨进程的话,还有意义吗?

JVM级别的支持群集的二级缓存要看用什么了,据说像Tangosol Coherence性能就非常好。只要能够接受群集Cache的同步开销(想像一下10个节点的Cache同步),也可以用二级缓存。而且我觉得很重要的一点是,我们也完全可以用memcached来做EJB3的二级缓存。
0 请登录后投票
   发表时间:2006-05-12  
jpenguin 写道
robbin 写道


memcached用来作为全局共享变量的holder,在spring里面配置一个bean去封装对memcached的访问,这样访问memcached的全局共享变量和过去访问JVM内部的全局共享变量的方式从编程接口上来说就根本没有任何区别了,桀桀。

好完美的一个群集部署方案啊,谁来挑挑刺?


Here is some opinions from Wikipedia developer in 2004 (see http://www.linuxjournal.com/article/7451 ) , since then memcached had some improvements (see http://cvs.danga.com/browse.cgi/wcmtools/memcached/ChangeLog?rev=HEAD&content-type=text/plain ) :

引用

Submitted by timstarling (not verified) on Wed, 2004-07-14 01:00.

Memcached's big claim is that it's faster than a database, which may well be true. But with no local caching, it certainly can't compete with a true distributed memory system like those commonly used in supercomputers. With memcached, if you have a data item which is needed on every web request, then that data item will be sent across the network from the same server on every request.

Memcached also has a lingering problem with slabs reassignment. If your application uses one particular size class heavily, and doesn't use another size class, then writes to the unused size class (when they eventually occur) will fail. The daemon can't automatically recover memory from the other slabs for use in an empty slab. Similarly, it's not a true LRU cache, the item dropped will always be an item from the same slab. The lifetime of an item in the cache is skewed due to differing amounts of memory allocated to each slab after a restart.

At Wikipedia, we've also had perennial problems with writes failing, probably due to high load from other processes on the server leading to a connection timeout. This is unfortunate when the write is an important cache invalidation operation.

Tim Starling (Wikipedia developer)


memcached肯定不完美,不过是值得我们考虑的合理的方案之一。对于每个请求都需要的全局共享变量,确实没有必要往memcached里面塞,请参考我上面cookie和session的解决方案。
0 请登录后投票
论坛首页 编程语言技术版

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