锁定老帖子 主题:关于rails大容量网站部署的性能讨论
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-06-14
robbin 写道 但是我却不得不遗憾的说,memcached不适合Java应用程序!罪魁祸首就是Java序列化机制。 请问以前提到的session server保存session里的信息不用java序列化吗? 那session server不是也会因为java序列化影响效率吗? 所以最后结论就变成不用session了.我觉得,应该在负载均衡层保证同一client 不会再不同的节点件切换,这样完全可以使用session,毕竟节点down掉,才会客户才会切换到另外一个节点,而且这是个小概率事件,大不了session丢掉,用户重新登录.重新做以前的事情. |
|
返回顶楼 | |
发表时间:2006-06-14
makefile 写道 robbin 写道 但是我却不得不遗憾的说,memcached不适合Java应用程序!罪魁祸首就是Java序列化机制。 请问以前提到的session server保存session里的信息不用java序列化吗? 那session server不是也会因为java序列化影响效率吗? 所以最后结论就变成不用session了.我觉得,应该在负载均衡层保证同一client 不会再不同的节点件切换,这样完全可以使用session,毕竟节点down掉,才会客户才会切换到另外一个节点,而且这是个小概率事件,大不了session丢掉,用户重新登录.重新做以前的事情. 会啊,只要用了序列化机制,一般你选择了用session server方式,那都是为了应付相当极端的性能要求,这时往往只有自己去实现特定的序列化了,比如,直接对字节流操作。 如果只是使用原始数据类型,避免java序列化机制的递归操作,性能应该要好一点。 |
|
返回顶楼 | |
发表时间:2006-06-14
无明 写道 makefile 写道 robbin 写道 但是我却不得不遗憾的说,memcached不适合Java应用程序!罪魁祸首就是Java序列化机制。 请问以前提到的session server保存session里的信息不用java序列化吗? 那session server不是也会因为java序列化影响效率吗? 所以最后结论就变成不用session了.我觉得,应该在负载均衡层保证同一client 不会再不同的节点件切换,这样完全可以使用session,毕竟节点down掉,才会客户才会切换到另外一个节点,而且这是个小概率事件,大不了session丢掉,用户重新登录.重新做以前的事情. 会啊,只要用了序列化机制,一般你选择了用session server方式,那都是为了应付相当极端的性能要求,这时往往只有自己去实现特定的序列化了,比如,直接对字节流操作。 如果只是使用原始数据类型,避免java序列化机制的递归操作,性能应该要好一点。 直接对字节流操作转换java vo,其实效率同C区别不太大 |
|
返回顶楼 | |
发表时间:2006-06-15
flyingbug 写道 无明 写道 如果只是使用原始数据类型,避免java序列化机制的递归操作,性能应该要好一点。 直接对字节流操作转换java vo,其实效率同C区别不太大 有点误解,我没说清楚,我想说的是使用java的序列化机制时,只是使用基本的数据类型和简单的String,避免使用多层引用的对象,那么就可以避免使用java序列化机制时的递归操作,这样应该会带来一点性能提高,但这个提高放在整个应用中,会提高多少?因为没做过测试,也不好说。 |
|
返回顶楼 | |
发表时间:2006-06-15
瞧你们纸上谈兵说的那么轻松,谁写个高效的对象序列化机制给我看看?
|
|
返回顶楼 | |
发表时间:2006-06-15
robbin 写道 瞧你们纸上谈兵说的那么轻松,谁写个高效的对象序列化机制给我看看? 谁说轻松了?轻松的话还讨论啥啊?
现在我们这边就是直接对字节流操作了,简单的存储倒也罢了,复杂一点的写起来相当累人,而且谈不上什么可复用性,要增加新的对象了,就得重新写起,都已经在考虑代码生成了,这也是没有办法的事情。 |
|
返回顶楼 | |
发表时间:2006-06-15
无明 写道 现在我们这边就是直接对字节流操作了,简单的存储倒也罢了,复杂一点的写起来相当累人,而且谈不上什么可复用性,要增加新的对象了,就得重新写起,都已经在考虑代码生成了,这也是没有办法的事情。 是可以采用代码生成,这条路可行,而且也很简单 或者采用配置的方式,那样就不需要vo了 不过一般一个协议族设计的好的话只要重写其中一小部分就可以了,工作量也不大 |
|
返回顶楼 | |
发表时间:2006-06-17
memcache监听连接,即缓存服务器是一个体系,前台业务系统是一个体系,业务体系到缓存体系取内
容,如果从缓存体系中还取不得所需要的内容,转而进行数据库查询. oscache是与业务体系结合的(跑于同一jvm中),这样缓存命中时是从本地取得的,缓存失效了,取不到了,同样查询数据库 jbosscache可以配置成是先从本地取缓存,如果没有则到集群环境中取,如果还没有,则到数据存储中查询. 由此可见,memcache在各方案中将使用到的存储空间是最节省的,因为各集群服务器共享存储. 但是每次命中 缓存都需要网络访问. oscache,jbosscache由于必须在本地存储中保存缓存,所以在空间的使用上比较大,本地与集群中其他服务器 储存的内容有交集. 所以最终的问题实际上是,空间和时间上的取舍. 假设数据库访问查询的时间是x,命中网络缓存时间是y,命中本地缓存时间是Z. (x>>y>Z x远大于y,y大于Z) 对于每一请求,n表示缓存服务器数(对于memcache则是memcache本身的集群): 在一次命中的情况下,时间消耗: memcache: y oscache: Z jbosscache:Z 在一次未命中,查询集群中其他服务器缓存命中的情况下: memcache: y*n oscache: Z jbosscache: Z+ y*(n-1) 在一次未命中,集群环境也未命中,继而查询数据库: memcache: y*n +x (+x表示在集群环境下仍然未命中缓存,继而查询数据库的消耗) oscache:Z+x jbosscache: Z+y*(n-1) +x 咋一看,似乎oscache在各种情况下的性能是最好的,但是实际上oscache处于最后一种情况的几率会是最大的 ! 如果把oscache配置成支持集群的,那么和jbosscache当前配置的情况下,是一样的. 所以我们的问题在于合理的选择 n,而对于memcache,N我们可以取到最小.而保持最好的稳定性,(而对于 jboss的解决方案,n总是要比memcache的n大,否则就不用集群了,呵呵)而且可以节省存储(内存),使业务集群 环境专注使用内存处理业务请求. 既然robin举例出千万级的解决方案已经是采用牺牲网络时间来获得其他方面的空间和时间的优势, 我们根据上述公式,仔细思考一下是有他的道理的. 实际上由于缓存大小和命中率的原因总是避免不了需要通过网络查询集群中的其他服务器,在这种情况下,能 迅速做出发应的就是在N比较小的情况下的memcache的解决方案. 综上:采用何种解决方案,需要由你项目的规模,空间和时间性来决定的. 但是我觉得项目级别到了一定的程 度后的解决方案还是要采用 集中式的共享管理 的方案 比较合适! 正如前面兄弟说的: 无明 写道 这个帖子讨论到现在几乎是跟rails无关了,转贴一个email的案例,可以见到,在追求高性能目标下,设计出来的架构会是相当相似的,毕竟可以选择的途径并不算多:
http://www.huihoo.com/middleware/database/elong.html |
|
返回顶楼 | |
发表时间:2006-06-17
另外看了memcache也是可以配置在本机的.
What about shared memory? The first thing people generally do is cache things within their web processes. But this means your cache is duplicated multiple times, once for each mod_perl/PHP/etc thread. This is a waste of memory and you'll get low cache hit rates. If you're using a multi-threaded language or a shared memory API (IPC::Shareable, etc), you can have a global cache for all threads, but it's per-machine. It doesn't scale to multiple machines. Once you have 20 webservers, those 20 independent caches start to look just as silly as when you had 20 threads with their own caches on a single box. (plus, shared memory is typically laden with limitations) The memcached server and clients work together to implement one global cache across as many machines as you have. In fact, it's recommended you run both web nodes (which are typically memory-lite and CPU-hungry) and memcached processes (which are memory-hungry and CPU-lite) on the same machines. This way you'll save network ports 对于集群中的每个服务器,都监听一个memcache,由于与web服务器是不冲突的,可以更加充分的利用资源. 那么本机的web process 会优先从本机memcache中查询缓存吗? 如果是这样,那确实非常好,进一步看文档中.. 对于我上述理解有误的地方,还望指出,如果有新的收获我会回来编辑的:) 另外期待高手能解决memcache的java序列化问题,我想既然jboss已经有解决方案了,memcache的解决只是迟早的问题.(robin研究的如何啦,呵呵,期待中) |
|
返回顶楼 | |
发表时间:2006-06-17
ytfei 写道 另外看了memcache也是可以配置在本机的.
What about shared memory? The first thing people generally do is cache things within their web processes. But this means your cache is duplicated multiple times, once for each mod_perl/PHP/etc thread. This is a waste of memory and you'll get low cache hit rates. If you're using a multi-threaded language or a shared memory API (IPC::Shareable, etc), you can have a global cache for all threads, but it's per-machine. It doesn't scale to multiple machines. Once you have 20 webservers, those 20 independent caches start to look just as silly as when you had 20 threads with their own caches on a single box. (plus, shared memory is typically laden with limitations) The memcached server and clients work together to implement one global cache across as many machines as you have. In fact, it's recommended you run both web nodes (which are typically memory-lite and CPU-hungry) and memcached processes (which are memory-hungry and CPU-lite) on the same machines. This way you'll save network ports 对于集群中的每个服务器,都监听一个memcache,由于与web服务器是不冲突的,可以更加充分的利用资源. 那么本机的web process 会优先从本机memcache中查询缓存吗? 如果是这样,那确实非常好,进一步看文档中.. 对于我上述理解有误的地方,还望指出,如果有新的收获我会回来编辑的:) 另外期待高手能解决memcache的java序列化问题,我想既然jboss已经有解决方案了,memcache的解决只是迟早的问题.(robin研究的如何啦,呵呵,期待中) jboss是去读bytecode,我可没有那么高的水平 |
|
返回顶楼 | |