Category: Top Stories

FeedBurner:基于MySQL和JAVA的可扩展Web应用

于敦德 2006-6-27 FeedBurner(以下简称FB,呵呵)我想应该是大家耳熟能详的一个名字,在国内我们有一个同样的服务商,叫做FeedSky。在2004年7月份,FB的流量是300kbps,托管是5600个源,到2005年4月份,流量已经增长到5Mbps,托管了47700个源;到2005年9月份流量增长到20M,托管了109200个源,而到2006年4月份,流量已经到了115Mbps,270000个源,每天点击量一亿次。 FB的服务使用Java实现,使用了Mysql数据库。我们下面来看一下FB在发展的过程中碰到的问题,以及解决的方案。 在2004年8月份,FB的硬件设备包括3台Web服务器,3台应用服务器和两台数据库服务器,使用DNS轮循分布服务负载,将前端请求分布到三台Web服务器上。说实话,如果不考虑稳定性,给5600个源提供服务应该用不了这么多服务器。现在的问题是即使用了这么多服务器他们还是无法避免单点问题,单点问题将至少影响到1/3的用户。FB采用了监控的办法来解决,当监控到有问题出现时及时重启来避免更多用户受到影响。FB采用了Cacti(http://www.cacti.net)和Nagios(http://www.nagios.org)来做监控。 FB碰到的第二个问题是访问统计和管理。可以想象,每当我们在RSS阅读器里点击FB发布的内容,都需要做实时的统计,这个工作量是多么的巨大。大量写操作将导致系统的效率急剧下降,如果是Myisam表的话还会导致表的死锁。FB一方面采用异步写入机制,通过创建执行池来缓冲写操作;只对本日的数据进行实时统计,而以前的数据以统计结果形式存储,进而避免每次查看访问统计时的重复计算。所以每一天第一次访问统计信息时速度可能会慢,这个时候应该是FB在分析整理前一天的数据,而接下来的访问由于只针对当日数据进行分析,数据量小很多,当然也会快很多。FB的Presentation是这样写,但我发现好像我的FB里并没有今天实时的统计,也许是我观察的不够仔细-_-! 现在第三个问题出现了,由于大多数的操作都集中在主数据库上,数据库服务器的读写出现了冲突,前面提到过Myiasm类型的数据库在写入的时候会锁表,这样就导致了读写的冲突。在开始的时候由于读写操作比较少这个问题可能并不明显,但现在已经到了不能忽视的程度。解决方案是平衡读写的负载,以及扩展HibernateDaoSupport,区分只读与读写操作,以实现针对读写操作的不同处理。 现在是第四个问题:数据库全面负载过高。由于使用数据库做为缓存,同时数据库被所有的应用服务器共享,速度越来越慢,而这时数据库大小也到了Myisam的上限-4GB,FB的同学们自己都觉得自己有点懒。解决方案是使用内存做缓存,而非数据库,他们同样使用了我们前面推荐的memcached,同时他们还使用了Ehcache(http://ehcache.sourceforge.net/),一款基于Java的分布式缓存工具。 第五个问题:流行rss源带来大量重复请求,导致系统待处理请求的堆积。同时我们注意到在RSS源小图标有时候会显示有多少用户订阅了这一RSS源,这同样需要服务器去处理,而目前所有的订阅数都在同一时间进行计算,导致对系统资源的大量占用。解决方案,把计算时间错开,同时在晚间处理堆积下来的请求,但这仍然不够。 问题六:状态统计写入数据库又一次出问题了。越来越多的辅助数据(包括广告统计,文章点击统计,订阅统计)需要写入数据库,导致太多的写操作。解决方案:每天晚上处理完堆积下来的请求后对子表进行截断操作: – FLUSH TABLES; TRUNCATE TABLE ad_stats0; 这样的操作对Master数据库是成功的,但对Slave会失败,正确的截断子表方法是: – ALTER TABLE…

使用Red5和FFMpeg搭建在线Flash流媒体分享平台

最近视频的东西比较火,前些天我也稍微了解了一下使用开源软件建在线Flash流媒体播放平台的解决方案,还是有一些收获。 Red5是一款基于java的开源的Flash流媒体Server软件,可以作为取代Macromedia提供的商业版本FMS。Red5使用RSTP作为流媒体传输协议,内置了一些示例,这些示例实现了在线录制,flash流媒体播放,在线聊天,视频会议等一些基本的功能。由于系统本身是开源的,在碰到问题的时候也比较容易解决,大不了直接改代码,在成本方面也可以省下一笔不小的开销,为未来的功能扩展也提供了充分的空间。 如果仅仅是实现在线录制,在线播放,那么Red5也就差不多够了,但可能我们有时候还需要用户上传自己拍摄的视频文件,而要把这些视频文件转成可播放的flv文件就需要视频编码软件了。FFMpeg提供了录制,播放,视频流处理的完整解决方案。它自身也带了一个基于HTTP的流媒体广播程序以及其它几个实用的程序,但我们的重点还是它的视频转换程序,似乎Google Video也是用的它的程序作为视频转换工具。 我用FFMpeg转了几个视频,效果还可以,在声音上碰到了一些问题,在不添加参数的情况下,有一部分视频的声音会有问题,有的视频无论怎么添加参数,都出不来声音,报错提示的是不支持所带的声音采样格式,只支持几种固定的格式,我看了一下代码,确实是这样子,但理论上应该是能够解决的。FFMpeg自带的libavcodec是一套很牛的编码库,为了保证质量和性能,里面的很多codec都是从头开发的。 这两个加起来,实现一些简单的在线视频功能就差不多了。 PS:今天刚看到古永锵也开始做小视频分享网站:优酷。

使用开源软件,设计高性能可扩展网站

2006-6-17 于敦德 上次我们以LiveJournal为例详细分析了一个小网站在一步一步的发展成为大规模的网站中性能优化的方案,以解决在发展中由于负载增长而引起的性能问题,同时在设计网站架构的时候就从根本上避免或者解决这些问题。 今天我们来看一下在网站的设计上一些通常使用的解决大规模访问,高负载的方法。我们将主要涉及到以下几方面: 1、 前端负载 2、 业务逻辑层 3、 数据层 在LJ性能优化文章中我们提到对服务器分组是解决负载问题,实现无限扩展的解决方案。通常中我们会采用类似LDAP的方案来解决,这在邮件的服务器以及个人网站,博客的应用中都有使用,在Windows下面有类似的Active Directory解决方案。有的应用(例如博客或者个人网页)会要求在二级域名解析的时候就将用户定位到所属的服务器群组,这个时候请求还没到应用上面,我们需要在DNS里解决这个问题。这个时候可以用到一款软件bind dlz,这是bind的一个插件,用于取代bind的文本解析配置文件。它支持包括LDAP,BDB在内的多种数据存储方式,可以比较好的解决这个问题。 另外一种涉及到DNS的问题就是目前普遍存在的南北互联互通的问题,通过bind9内置的视图功能可以根据不同的IP来源解析出不同的结果,从而将南方的用户解析到南方的服务器,北方的用户解析到北方的服务器。这个过程中会碰到两个问题,一是取得南北IP的分布列表,二是保证南北服务器之间的通讯顺畅。第一个问题有个笨办法解决,从日志里取出所有的访问者IP,写一个脚本,从南北的服务器分别ping回去,然后分析结果,可以得到一个大致准确的列表,当然最好的办法还是直到从运营商那里拿到这份列表(update:参见这篇文章)。后一个问题解决办法比较多,最好的办法就是租用双线机房,同一台机器,双IP,南北同时接入,差一些的办法就是南北各自找机房,通过大量的测试找出中间通讯顺畅的两个机房,后一种通常来说成本较低,但效果较差,维护不便。 另外DNS负载均衡也是广泛使用的一种负载均衡方法,通过并列的多条A记录将访问随即的分布到多台前端服务器上,这种通常使用在静态页面居多的应用上,几大门户内容部分的前端很多都是用的这种方法。 用户被定位到正确的服务器群组后,应用程序就接手用户的请求,并开始沿着定义好的业务逻辑进行处理。这些请求主要包括两类静态文件(图片,js脚本,css等),动态请求。 静态请求一般使用squid进行缓存处理,可以根据应用的规模采用不同的缓存配置方案,可以是一级缓存,也可以是多级缓存,一般情况下cache的命中率可以达到70%左右,能够比较有效的提升服务器处理能力。Apache的deflate模块可以压缩传输数据,提高速度,2.0版本以后的cache模块也内置实现磁盘和内存的缓存,而不必要一定做反向代理。 动态请求目前一般有两种处理方式,一种是静态化,在页面发生变化时重新静态页面,现在大量的CMS,BBS都采用这种方案,加上cache,可以提供较快的访问速度。这种通常是写操作较少的应用比较适合的解决方案。 另一种解决办法是动态缓存,所有的访问都仍然通过应用处理,只是应用处理的时候会更多的使用内存,而不是数据库。通常访问数据库的操作是极慢的,而访问内存的操作很快,至少是一个数量级的差距,使用memcached可以实现这一解决方案,做的好的memcache甚至可以达到90%以上的缓存命中率。10年前我用的还是2M的内存,那时的一本杂事上曾经风趣的描述一对父子的对话: 儿子:爸爸,我想要1G的内存。…

从LiveJournal后台发展看大规模网站性能优化方法

于敦德 2006-3-16 一、LiveJournal发展历程 LiveJournal是99年始于校园中的项目,几个人出于爱好做了这样一个应用,以实现以下功能: 博客,论坛 社会性网络,找到朋友 聚合,把朋友的文章聚合在一起 LiveJournal采用了大量的开源软件,甚至它本身也是一个开源软件。 在上线后,LiveJournal实现了非常快速的增长: 2004年4月份:280万注册用户。 2005年4月份:680万注册用户。 2005年8月份:790万注册用户。 达到了每秒钟上千次的页面请求及处理。 使用了大量MySQL服务器。 使用了大量通用组件。 二、LiveJournal架构现状概况 三、从LiveJournal发展中学习 LiveJournal从1台服务器发展到100台服务器,这其中经历了无数的伤痛,但同时也摸索出了解决这些问题的方法,通过对LiveJournal的学习,可以让我们避免LJ曾经犯过的错误,并且从一开始就对系统进行良好的设计,以避免后期的痛苦。 下面我们一步一步看LJ发展的脚步。

imageMagick图片处理工具

ImageMagick是一套Linux下的开源图形处理工具,针对几乎所有的图片格式提供比较全面的图片处理功能。不像windows下的photoshop,先要双击运行,然后打开图片,然后才能对图片进行处理,ImageMagick可以直接在命令行下运行,加上几个参数,就可以得到想要的图片了,而大批量的处理图片也比photoshop简单的多,写个shell多循环几次就可以了。 假如我想给图片加个框,转一下,再加个阴影,输入以下的命令就可以了: convert -size 400x180 hatching.jpg -thumbnail '200x90>' -bordercolor white -border 6 -bordercolor grey60 -border 1 -background none -rotate 6…

bind dlz – 分布式系统的请求分发工具

bind dlz全称是bind dynamic loadable zones,是基于bind的提供的一个组件,作用看名字就知道了,支持动态域加载支持。 bind已经有很久的历史,目前是搭建DNS服务器的首选。对于一般网站来说,一个标准的bind已经完全可以完成所有dns解决的工作,但在海量域名数量的情况下,bind也确实存在着一些问题: 1、域名解析信息全部存储在文本文件中,这非常容易导致由于编辑出错导致的域名解析出错。 2、bind运行时将全部的解析信息放在内存里,如果数量巨大将可能出现内存不足的情况,同时解析信息重新加载时所耗费的时间也非常值得考虑,由于加载时间较长,所以基本可以不考虑动态的进行域名的调整。 dlz就是为了解决这个问题而针对bind开发的组件,可以将域名解析信息放在数据库中,从而避免域名信息变动时重新加载的时间,在变动后马上生效。 dlz支持多种数据存储形式,包括文件系统,Berkeley-DB,Postgre-SQL,MySQL,ODBC,LDAP等等。性能的比较在这里。 bind dlz这种提供动态的域名调整,并且仍然可以提供高性能的dns解析服务的特点可以应用于提供二级或三级域名服务的分布式系统的前端,对不同的域名解析到所在服务器组上,从而实现可扩展的系统架构。

使用memcached进行内存缓存

旧文重发 2005.8.9 通常的网页缓存方式有动态缓存和静态缓存等几种,在ASP.NET中已经可以实现对页面局部进行缓存,而使用memcached的缓存比ASP.NET的局部缓存更加灵活,可以缓存任意的对象,不管是否在页面上输出。而memcached最大的优点是可以分布式的部署,这对于大规模应用来说也是必不可少的要求。 LiveJournal.com使用了memcached在前端进行缓存,取得了良好的效果,而像wikipedia,sourceforge等也采用了或即将采用memcached作为缓存工具。memcached可以大规模网站应用发挥巨大的作用。