说说JavaEye网站架构

说说JavaEye网站架构 偶然看到了Robbin的一则胶片《JavaEye网站架构解密》,说到了一些JavaEye的一些实现,那就来看看有哪些有意思的东西。

我正在参与做的一个项目,在某某地方上线,需要几十块单板集群;在某某地方上线,又需要怎样的一个集群组网。咋听起来兴许觉得能有怎样的业务逻辑处理和怎样的用户量呢?可是JavaEye让我很吃惊,我先前只知道与CSDN比起来,JavaEye确实是一个小规模一些的网站,专业一些的网站,可是服务器呢?只有两台!

这是那台Web Server:

• AMD Opteron 2.4GHz单核 * 2 颗
• 8G内存
• 146G SCSI硬盘

这是那台DBServer:

• AMD Opteron 2.0GHz单核 * 2 颗
• 4G内存
• 73G SCSI硬盘

实在不能说有多么优秀的硬件配置,JavaEye又得面对怎样的访问量呢?

150万动态请求/天

说说JavaEye网站架构

这个是JavaEye封杀网络爬虫的简单匹配表达式:

说说JavaEye网站架构

 

JavaEye采用Ruby作为实现语言,看来Ruby很慢是没有说头的,看看Google Adplanner Data:

说说JavaEye网站架构

这张图表就很有意思了:

说说JavaEye网站架构

CSDN拥有JavaEye的3.5倍访问量,但使用了三十多台服务器集群,中国最大的几个IT站点,使用ASP.NET、Ruby、PHP的都有,但看起来JavaEye的性能或许是最佳的。

—————————————————————————————————————-

JavaEye网站架构进化:

(1)2006年9月

• lighttpd
• ruby 1.8.4, rails 1.1.2, 以fastcgi方式运行
• mysql5.0

FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)。因为是多进程,所以比CGI多线程消耗更多的服务器内存,举例来说,PHP-CGI解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数。

其实小网站来说,使用FastCGI+Lighttpd是一个非常优秀的组合。

(2)2007年1月

• 添加了第2台服务器
• 把web和DB分开
• 系统瓶颈在数据库IO端

系统瓶颈出现在DB IO上面是符合预期的(虽然我自己这边的项目经常遇到在Java侧锁瓶颈,一方面是性能测试的用例未必能反映现网真实情况导致,另一方面我还是觉得当整个架构过于复杂,远程方法过多,就会导致这样的问题)。

(3)2007年2月

• 把posts表的大字段剥离出来
• posts表的select count操作从30秒减少到
0.1秒

把大表的大字段剥离出来,这是一种基于性能考虑的常用的DB重构方法。

剥离前:

• posts(id, …, body)
• 磁盘存储空间2GB

剥离后:

• posts(id, post_text_id,…) 50MB
• post_texts(id, body) 2GB

(4)2007年3月

• 数据库瓶颈仍然存在
• 引入memcached和CachedModel
• 自己编写了简单的查询缓存
• 240 sql query/s 下降到 140 sql query/s
• memcached缓存命中率在75%

这一次的改进主要在缓存上面,其实在做性能优化的时候,需要经常关注的一个东西就是缓存命中率。

(5)2007年9月

• 引入全文检索
• 使用ruby的ferret
• 中文分词使用单字拆分法

主要是对搜索引擎的优化。

(6)2008年1月

• JavaEye网站代码重写
• 缓存框架改用cache_fu
• 缓存命中率上升到84%
• sql query下降到 50条/s

回去打算去了解一下cache_fu,这里有两篇文章可以参考:

http://weekface.javaeye.com/blog/133797

http://iceskysl.1sters.com/?tag=cache_fu

• cache_fu不对AR对象进行任何拦截,全部交给用户编程
• 用户有完全的控制权,但所有的缓存代码要自己手工编写

(7)2008年5月

• 中文分词算法改用rmmseg-cpp

(8)2008年10月

• 自制山寨cache plugin
• 缓存命中率上升到96%以上

• 抛弃ferret,自己编写全文检索服务器
• 使用Java的lucene作为全文检索引擎
• 自己实现C/S架构的内部调用

(8)2008年11月

• 实现博客,新闻制作PDF功能

(9)2009年3月

• SNS feed功能
• twitter绑定功能
• 开放API

• 废弃Google Analytics
• 自己编写简单的网站流量分析系统

说说JavaEye网站架构

(10)2009年12月

• 添加Web IM
• 添加一台服务器
• 合理规划服务器

说说JavaEye网站架构

一个生命周期较长的WEB应用每发展到一定阶段一定要面对的是架构上的重组,有时哪怕牺牲一些性能的代价,有时则是牺牲可维护性的代价,带来的是结构层次清晰,便于短期内扩展等好处。这个过程每次都可能是痛苦的,但又是不可避免的。同时,我认为,在项目初期不应当也不可能把架构的融合性和扩展性考虑得太远,那样反而作茧自缚。而在应用发展过程中不断地重构却是更有价值的。

—————————————————————————————————————-

进化总结:

(1)对象缓存原则:

• 数据库表的设计要细颗粒度
• 把有冗余字段的大表拆分为n个互相外键关联的小表
• ORM的性能瓶颈不在于表关联,而在于大表的全表扫描
• 尽量避免join查询,多制造n+1条SQL

上面第一条我觉得还是要看表容量而定,第四条我深有体会,记得在iBatis的使用中还有这样一个专题。

(2)对象缓存的意义:

• Web应用很容易通过集群方式实现横向扩展,系统的瓶颈往往出现在数据库
• 数据库的瓶颈往往出现在磁盘IO读写
• 因此要避免数据库的全表扫描和大表的数据扫描操作
• 如何避免:拆表和臭名昭著的n+1条SQL

……

说说JavaEye网站架构

• memcached缓存命中率96%
• cache get : sql query = 4 : 1

另外,Robbin还提到,Ruby的字符串处理,尤其是正则表达式处理性能不好,解决方法也是使用缓存。

cache_money:

• 出自twitter开发团队之手
• 可能是目前最强大的ruby cache框架
• 支持分页查询缓存,支持条件查询缓存

全文检索:

说说JavaEye网站架构

—————————————————————————————————————-

后附,关于JavaEye后来的衰落:

其实严格说用“衰落”这个词语是不很恰当的,但是于我看来,就如同“校内网”变成“人人网”一样,很多网站在发展的过程中,都把自己能应付的战线拉长,让那些原来看起来不属于自己的用户收纳进来,JavaEye也一样,更名为ITEye(当然,其直接原因还是来自于Oracle的压力,你不能免费用着Java的名号啊),但是这样带来副作用,尤其对一个技术社区来说,就是良莠不齐、鱼龙混杂。

如今的,实际人气已经没有那么高了,但是却成为了很多程序员小白的乐园,也就是说,已经丢失了帖子文章的质量,丢失了网站原本的生命,还有一票牛人。Robbin自己也提到了一些客观原因:

JavaEye在04年05年确实有一些比较火爆的帖子,但是要看到当时的时代背景:EJB2逐渐被人唾弃,Hibernate/Spring强势崛起,CMM开始被骂,敏捷开发在国内悄悄普及,AJAX技术也在Google推动下一夜成名。从整个Java行业来说,那几年可以炒作的体裁很多,可以争论的话题很多,观点的冲突很多。这在客观上造就了论坛的火爆。

在ITEye被CSDN收购以后,再加上那次著名的密码泄露的拖库事件,事件以后Robbin跳出来解释问题和撇清责任,我已经彻底对ITEye失去了信心。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接《四火的唠叨》

分享到:

发表评论

电子邮件地址不会被公开。

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


Preview on Feedage: