??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲av永久中文无码精品综合,亚洲综合偷自成人网第页色,亚洲 无码 在线 专区http://www.tkk7.com/jinfeng_wang/category/44697.htmlG-G-S,D-D-U!zh-cnFri, 16 Apr 2010 07:16:22 GMTFri, 16 Apr 2010 07:16:22 GMT60谈谈|站静态化 zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318519.htmljinfeng_wangjinfeng_wangFri, 16 Apr 2010 06:34:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318519.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318519.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318519.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318519.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318519.html写在前头

静态化是解军_ȝ站压?/span>,提高|站讉K速度的常用方?/span>,但在交互?/span>We2.0 时代,寚w态化提出了更高的要求,静态不仅要能静,q要能动,下面我通过一个项?/span>,谈谈|站静态化后的架构设计Ҏ(gu),同时和大家探讨一?/span>,在开源品大行其?/span>,a架构必称MemberCache, Nginx,的时?/span>,微Y技术在|站架构设计中的q用.

静态化的设计原则和步骤

静态化是解军_ȝ站压?/span>,但是静态化也会带来一pd的问?/span>,包括开发上复杂度的增加,l护隑ֺ的增?/span>,q用不的?/span>,更可能适得其反,而许多替代方?/span>,比如面~存,如果q用得当,也能起到很好的效?/span>,所以在开始之?/span>,必须q行详细的考察,定是否适合静态化,q制定适合的静态化方式,下面先介l一?/span>

l         考查d?/font>:

d?/span>,准确的说是读写负h,是否值得静态化的最l考虑,׃一般写入的压力明显大于d的压?/span>,如果写入太频J?/span>,或者每ơ写入消耗的资源太多,都不能达到效?/span>,我觉得读写比?/span>10:1应该是个上限.具体情况需要根据自q业务逻辑判断

 

l         定面呈现的内Ҏ(gu)否适合静态化:

在设计方案时,必须详细考虑每个原型面,扑ֈ面上展C的信息,和他的更新方?/span>,更新时机,更新频率,一定要注意那些不v眼的信息,他们可能左右你的设计,

比如:我们?/span>CSDN的论坛的L一帖子ؓ?/span>,q行分析

上面的帖子中呈现的内容主要是q样几块,帖子内容,回复内容,发帖人回复h的用户信?/span>

n         帖子内容和回复内容在发帖时更?/font>,发帖后用户可以修改其内容,更新频率?/font>

n         用户信息,用户修改个h信息时可能会发生更改,用户{增加时也可能发生更改,比如加星,更新频率?/font>

n         回复数将每次回复后都要更?/font>,更新频率?/font>

n         设计时要注意l节,如上图中圈出来的部分,q些部分是怎么修改?/font>,频率有多?/font>,一个都不能放过.

l         定生成方式:

在上面帖子一例中.每次更改都重新生成页面是不可取的,一比回复数多的帖?/span>,需要的数据量是巨大?/span>(每层楼的用户信息,回复内容),M修改,都需要重新取出数据进行生成是不能允许?/span>.一般除非你的页面基本不用更?/span>,或者更新开销极小,(比如一D嵌入的q告代码)才能采用整体更新的方?/span>,不然需要我们找到合适的更新面局部区域的Ҏ(gu):

一般有下面两个Ҏ(gu):

1)      正则修改?/span>:

        比如,如果帖子中的回复?html代码是这?/font>
        <label>回复?lt;var id="replyCount">34</var></label>
        我们可以通过用下面正则来查找q替换计?/font>
         (?<=id="replyCount">)"d{1,}

2)      面区域分块:

把页面分成很多小?/span>,在显C时l装h,比如DotText采用这个方?/span>

q是一典型的Dottext blog,其中U色标定部分是一个独立的文g,而黄色框内的是脚本动态加?/span>,q些部分在最l显C的时候组合v?/span>,最l构成了一?/span>Blog,具体的组合方法也有多U?/span>,可以使用Include,也可以自己来实现.DotTextp己实C一套加载机?/span>

 

上面的两U方法ƈ不孤?/span>,q可以根据需?/span>,配合使用

 

l         定需要动态加载的信息:

面上L一些内容看h不太适合静态化,最典型的是一些统计结?/span>,比如如果你在做一个图书介l页?/span>,可能׃需要展C图书的当天l合评分,或者书c排?/span>,q些内容需要用脚本q行动态加?/span>

既然做了静态化,是希望减少服务器负?/span>,动态加载的数据L不得已而ؓ?/span>,有的时候在需求允许的情况?/span>,我们在数据在实时性和性能斚w做一些妥?/span>,比如上面帖子中的用户星和昵U?/span>,从数据实时性上?/span>,当用L星增长,他发a的所有帖子都应该发生变化,所以应该用动态加?/span>.然而其实上q些信息如果不发生变?/span>,也无伤大?/span>,用户反而能够看到自己在多年前发帖时的别和늧.

现实中的目

X|站是大型的?sh)媄资?/span>,?sh)媄C֌,向外提供?sh)媄相关信息服?/span>,以及用户C֌,其中信息服务部分, 其中大部分页面属于信息呈现页,d量比较大,百万U别pv,信息主要q辑在后台发布,更新较少,但其面上有大量的交互性的内容,比如评论,收藏列表,同时许多内容允许用户创?/span>,比如上传囄,d注释.交互内容的数量和交互的频J程?/span>,都超q了普通的咨询面,q次调整,准备其中访问量最大的几块:?sh)媄资料?/span>,׃h资料?/span>,q行静态化,如果成功,q将q用到更多的频道,基本实现全站静态化

 

通过寚w面设计和前一版本的分?/span>,下面是具有挑战性的地方.q些特点基本使用于大多数web2.0的站?/span>,很具有典型意?/span>

 

l         面生成的触发条件复?/span>

一般论坛中的帖子或?/span>blog,更新方式比较单一:主要是由回复q行触发q有数的修改动?/span>,然而该|站一个页面上需要根据不同触发条件就?/span>20多个, 比如光二U菜?/span>:用户发布囄,删除囄,发布或者删除媄片信?/span>,发布或者修改视?/span>,后台修改?sh)媄信?/span>,都有可能触发

 

l         一个动作触发生成的面可能很多而且怺交叠

每一个动作都会触发一pd的生?/span>,q且不同动作可能都会涉及同一个页面或者区域的生成.

比如:用户l一步电(sh)p?/span>,需要生成评分更多页,评分l计更多?/span>,首页右侧谁还x此媄片小区域,{等.用户收藏一个媄?/span>,也需要更新首右侧谁q关注此q区?/span>

 

l         触发频繁:

虽然不及某些更大规模的网?/span>,但是׃涉及众多用户参与的内?/span>,评论,收藏{等,触发点多,发生频度相当频繁

 

l         面?/span>,l构复杂,I间占用?/span>:

通常,需要生成的面规模是这L略估的,Rn*P,Rn源数,P为每个资源的面?/span>,所谓资?/span>,可以看做一个生成单?/span>,光面数可以单看做发布一个资?/span>,需要生成其所有相关页面数?/span>,比如:发布一?/span>blog,需要生成一?/span>Blog?/span>,同时q需要生成或者更CZ늚blog列表,上个h主页右侧的分cL章数的小?/span>,也就是最?/span>10来个面或者区?/span>,但是发布一个电(sh)?/span>,其相关的面臛_?/span>50个以?/span>,而且有的面q带有分?/span>,一个信息比较丰富的?sh)?/span>,光面竟可以辑ֈ千个以上,I间10~20M,而且资源L也不?/span>,?sh)?/span>80000左右,?sh)媄?/span>PD?yu)?/span>,但是总量有几十万之?/span>,估计静态页面磁盘占用量几百?/span>G

 

l         向下兼容

q是一个已有系l?/span>,旧系l的框框需要突?/span>,但又没有旉,或者不能完全突?/span>,比如Url,已经被收录到搜烦引擎,׃能随便调?/span>,q有一些地?/span>,原本没有为静态生成考虑,另一些地方又需要兼Ҏ(gu)的设?/span>.

 

l         多台前端Web

q种l构要求生成的文件可能需要分布到多个服务?/span>(另一个方案是攑֜几台专用的机器上,{前端来?/span>)

 

l         d紧迫

架构讨论l束仪式六月?/span>,dq开q上U只有两?/span>,也就是说所有底层框架实?/span>,面模板开?/span>,调试试,动作的整?/span>,必须?/span>7月底全部完成,按我原来估计,光实现这几块的上百个面模板和填充方?/span>,也需要那么长的时?/span>

 

l合考虑上述因素,架构必须要有以下几个斚w的特?/span>

l         动作可以灉|扩展配置,某个动作对应哪些生成,应该可以配置,q且可以分组

l         文g必须有分发机?/font>

l         分发和生成必ȝ立出?/font>,q且支持分布?/font>

l         各种的动?/font>,必须转化为消?/font>,发送到生成和分发服务器q行处理

l         针对同意资源频繁动作,在变量相同的情况下能够具有合q的能力

l         动作必须有记?/font>

l         量考虑使用已有成熟技?/font>,节省开发时?/font>

下面是设计的W一个架?/font>

用户的动作经q?/font>MSMQ[1]传入到生成分发中?/span>(途中l色头)q行处理,,处理中心接受到消息后,负责生成对应的页面或者页面区?/span>,q将面分发到各个服务器,负蝲均衡沿用以前的架?/span>,采用微Y?/span>NLB[2]

 

之所以用MSMQ,是看上了他提供的完整的消息存储恢复机制,q样我们能确保即使服务器down掉重启后,消息依然能正常处?/span>,y我们cmsl的同事MSMQ非常熟?zhn)?/span>,q且真准备在另外一个项目中使用cM的架?/span>?span style="font-family: 宋体">于是一拍即?/span>

 

面采用分块存储,q样能保证生成时目标?/span>,开销?/span>,也能重用?/span>,然后再藉?/span>SSI[3](shtml include)q行整合,之所以采取这LҎ(gu),而不采用Dottext的整合方?/span>,是因为如果采?/span>Dottext的方?/span>,必走IIS?/span>.Net的管?/span>[4],而据试,l过道和直接返?/span>html性能有非常大的差?/span>,而?/span>ssi,在性能上是一个折?/span>,q且可以Light HTTPd{高性能web服务?/span>

 

模板生成方式,采用?/span>XSLT和另外一U自定义的模?/span>(我的同事开发的机制,很有?/span>, 理论上能把传l模板替换的性能开销全部消除),生成的最l物是shtml,之所以生?/span>shtml是ؓ了用其ssi(Server Side Include)的特?/span>,保证一定的灉|?/span>,q实现热Ҏ(gu)据的分离:某些面上的部分可能会频J更新和生成,而其它地方不?/span>,或者某个部分是所有页面通用?/span>(比如头和页?/span>),较之php下常怋?/span>smarty,生成php文g,虽然灉|性不?/span>php,但是性能上不怸?/span>,q略?/span>.

 

但是q个设计的问题是动态内容和静态内Ҏ(gu)有分开,生成?/span>html,和动态页面都攑֜前端服务器上,通过负蝲均衡讉K,也造成了分发服务器需要分发到多台服务?/span>,|络IO效率较低,而且静态内定w要的盘I间很大,且小文g非常?/span>,和动态页面؜在一起不便于优化,所以第二个Ҏ(gu)对生成的静态内容与动态内容用不同的服务?/span>

 

Ҏ(gu)?/span>:

我们把生成的静态文件单独放|?/span>,可以看到,前端增加Nginx,作ؓ跌{,把电(sh)?/span>,׃h资料库的面转向静态服务器,其他的调用{向动态服务器,q样我们可以单独ؓ静态服务器q行优化,比如采用更高效的服务器等{?/span>.

 

同时减少了文件分发的ơ数(甚至可以只分发到本机),提高生成分发的处理能?/span>

 

更进一?/span>,可以把图片服务分到另外一l机器上,使用独立的域?/span>,比如img.xxx.com,q样可以有效的减带?/span>

 

最l完整架?/span>:

 

 

文g生成分发中心

下图是文件生成分发中心的工作程?/font>


生成服务对外只有一个输?/span>,是消息,一个输?/span>:静态文?/span>,内部Ҏ(gu)消息,从配|文件中扑ֈ对应的生成方?/span>,取出相应的模?/span>,q行数据填充

 

分发服务主要吧生成服务生的文gq行分发,分发到前端的N台服务器?/span>,开始考虑得比较复?/span>,希望分发服务可以跨越协议(本地文gpȝ,局域网,http协议),跨越多种存储介质(文gpȝ,数据?/span>),实际最后定下来基本是本地文件系l或者局域网传输

 

?/span>:上图中文件分发的部分也可以通过定制MogileFS,来实现分布式文gpȝ

 

马后?/span>:

ȝh,静态化除了Ҏ(gu)构方面的影响,对开发和试程也有影响

Ҏ(gu)试提出更高的要求:

因ؓ一旦上U后,某个面发现问题,即是文字的修改,也需要重新生成许多页?/span>,所以测试h员必非总l?/span>,试周期也需要g?/span>

 

开发h员需要掌握模板语a

需要掌握一U模杉Ka,无论?/span>Xsltq是自己开发的模板语言,都需要花一定的旉掌握

 

需要给W一ơ生成腾够时?/span>:

如果不是新系l?/span>,那么数据q移和生成的q程比较痛?/span>,׃面众多,W一ơ生成的q程可能需要以天来计算,在制定上U方案是需要考虑到这个方?/span>

 

Nginx作ؓ前端的蟩?/span>,Ҏ(gu)其他|站的经?/span>,应该可以辑ֈ2-3万ƈ发连?/span>,但是使用之后,常常有卡壳的情况发生,具体症状为在览器中讉K面?/span>,q接时,或者一直不响应,此时Nginxq接数ƈ不高,好在q有W一套方案可以备?/span>,让我们有旉去解册个问?/span>,如果大家对这个问题有什么心?/span>,Ƣ迎交流



jinfeng_wang 2010-04-16 14:34 发表评论
]]>
多站Ҏ(gu)合—单点登录简单方?zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318517.htmljinfeng_wangjinfeng_wangFri, 16 Apr 2010 06:31:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318517.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318517.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318517.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318517.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318517.htmlhttp://www.yaosansi.com/post/1218.html


问题描述Q在一个比较复杂的|站环境下。有多个产品向外提供服务。每个品下都有自己的用L录界面。现在需要设计一个统一的登录界面。当用户在这个界面登录后可以自q使用各个产品和服务。同时意味着用户用一个帐号可以在不同服务里登录,另一斚w是在一个服务里面登录后可以无障的漫游到其他服务里面去?br />
实际应用QSohu的Passportfocus.cnQ?7173.comQsogou.comQchinaren.comq四个域名下的品全部整合在一起了。用户在q四个站点中M一个地斚w可以d。当用户d后可以自q使用其他域名下的服务。现在很多网站上都有bbs blog album服务。这些服务一般也是自q护自q用户信息。当发展C定时候,也需要一个Passport机制整合所有服务,使用户可以单点登录?br />
Sohu的实现方?/font>
?a target="_blank">http://passport.sohu.com/ d?fiddler可以拦截到如下的q回信息Q?br />
Click to Open in New Window

׃passport.sohu.com的登录界面用了iframe隐藏提交。所以页面没有看到刷新。隐藏的iframe把用户名和加密的password和其他信息发送给了passport.sohu.com。passport.sohu.com在Response中设|了成功d的cookie。这个cookie可以证实q个用户成功d了passport.sohu.com?br />
Click to Open in New Window

当用户在Passport成功d后。客L的JavascriptҎ(gu)成功d的标志,操作iframehhttp://passport.sohu.com/sso/crossdomain_all.jsp?action=login 因ؓ在同一个域名下Q没有跨域,在这ơ请求中Q上ơ成功登陆的cookie会被一q带着回去。服务器端检查到成功d的cookie后会Render回一D同时登录多个站点的html?

Click to Open in New Window

q段html 要向4个地址发送请求。截臛_现在都是在相同的Domain(passport.sohu.com)h和返回,为真正的跨站点登录做准备Q真正的跨站点登录还没有开始。下面passport.sohu.com通过sso/crossdomain.jsp 在服务器端进行Redirect 讄http head ?02q行跌{。蟩转后在这个蟩转后的域名下讄d成功的cookie。这是sohu实现跨站点登录的核心q程。下面是passport.sohu.comd17173.com的过E?br /> 1.  通过http://passport.sohu.com/sso/crossdomain_all.jsp?action=login Render回来的script <script type="text/javascript" src=" ' target=_blank href_cetemp='http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com"> '>http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com"></script> h同域下的http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com q时passport.sohu.com下成功登录的cookie会被带回厅R?

Click to Open in New Window

2.  服务器看到成功登录的Cookie后。在服务器端计算Z个加密后?7173.com的登录UrlQƈRedirect到这个Url?

Click to Open in New Window

3.  17173.com从url的QueryString中取得信息。ƈ在Response中设|Cookie。这个Cookiel于写到?7173.com下。而不是passport.sohu.com下。从而得用户在17173.com下登录。其实用户在17173.com下手动登录也是写上同LCookie。以后用户再讉K17173.com的页面时q个Cookie会被带回厅R这pC用户在17173.com下成功登录过了?

Click to Open in New Window

l过上面的步骤。用户在passport.sohu.com下登录的同时也在其他站点d了?br />
在上面的q程中,最核心的技巧就是在指定的域下写入想要的CookieQ?/font>

1.  Sohu使用了在同一个域名登录后通过再次hq个域名下某个链接后Q得到要d站点的请求UrlQ通过javascript佉K藏的iframeh要登录站点的UrlQ服务器端接到请求Redirect到要d站点Q然后通过Response写入CookieQ完成跨域名写Cookie的操作。这U写Cookie的方式,需要在跌{时对h的QueryStringq行加密。接受方需要对QueryStringq行解密?/strong>

2.  q种做法在服务器端不需要特别的处理。只要写好相应Post操作 WriteCookie操作 Redirect操作 可以了。在FireFox下就可以正常工作了。但是在IE下写Cookie的操作还不行QL写不q去Cookie。需要在Response中加入一D늉别的Header. P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"

q个Http Header 是P3P安全的要求。P3P的详?http://www.oreilly.com.cn/book.php?bn=7-302-07170-5
微Y对这个的解释Q?a target="_blank">http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q323752

一个更加轻量的方?/font>

Sohu的通行证方案已l可以轻杄各个域名下的用户都同步d了。但是在实现上Sohu会让客户端的览器请求两ơpassport.sohu.com。在W二ơ得C个登录多个站点的地址列表。在W三ơ请求时通过本域下的cookieq行w䆾验证Q最后在服务器端跌{C个含有加密Key的其它域名的Url地址Q最l写入登录成功的Cookie。除L开始的dQ要求用户在d后再q行两次h。ƈ且服务器端要再做一ơ蟩转。Sohu的做法可能由于Sohu服务器环境和数据存储的结构所军_?br />
其实d只需一ơ登录请求,和每个域名下一ơ请求就可以完成多站点登录了Q同时也不需要服务器端的跌{?br />
Click to Open in New Window

跨站点的h由script的src发出。各个域名下的ssologin处理QueryString中的keyQ解密keyQ验证Key的合法性。在Response中写入登录成功的Cookie。完成跨站点Cookie的写入?br />
两种Ҏ(gu)的比?/font>

1. Sohu使用的登录方式,hơ数多,但是每次h都有对应的验证过E,在服务端跌{Ӟ重要的蟩转Url地址在HttpHeader中,使得跌{地址更加安全Q得用户在跨域d旉常安全可靠?/strong>

2. 轻量U方案的d方式Q请求次数少Q没有服务器端的跌{Q对服务器压力小。但是需要对Keyq行加密解密。蟩转的Url会在Response的Http Body中Renderl用戗在使用轻量U方案的时候,最好在Key中加上时间戳Q过期时间设|ؓ3分钟。Keyq期认ؓq个Key是非法KeyQ不在Response中写入登录成功的Cookie?/strong>

jinfeng_wang 2010-04-16 14:31 发表评论
]]>
亿万用户|站MySpace的成功秘?zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318514.htmljinfeng_wangjinfeng_wangFri, 16 Apr 2010 06:22:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318514.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318514.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318514.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318514.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318514.html

高速增长的讉K量给C֌|络的技术体pd来了巨大挑战。MySpace的开发者多q来不断重构站点软g、数据库和存储系l,以期与自w的成长同步——目前,该站Ҏ(gu)讉K量已?00ѝ绝大多数网站需要应对的量都不及MySpace的一部分,但那些指望迈入庞大在U市场的人,可以从MySpace的成长过E学到知识?br />
用户的烦?/span>
DrewQ是个来自达拉斯?7岁小伙子Q在他的MySpace个h资料上Q可以看C的袒胸照Q看样子是自己够着手拍的。他的好友栏全是漂亮姑娘和靓车的链接Q另外还说自己参加了学校田径队,爱好吉他Q开一辆蓝色福牚w马?br /> 不过在用户反映问题的论坛里,g他的火气很大?#8220;赶紧弄好q该ȝ收g!”他大写了所有单词。用MySpace的用户个人消息系l可以收发信息,但当他要查看一条消息时Q页面却出现提示Q?#8220;非常抱歉……消息错误”?br />
Drew的抱怨说?.4亿用户非帔R视在U交系l,q对MySpace来说是个好消息。但也恰是这点让MySpace成了全世界最J忙的站点之一?br /> 11月,MySpace的美国国内互联网用户讉K量首次过Yahoo。comScore Media Metrix公司提供的资料显C,MySpace当月讉K量ؓ387亿,而Yahoo?80.5ѝ?br /> 昄QMySpace的成长太快了——从2003q?1月正式上U到现在不过三年。这使它很早p面对只有极少数公司才会遇到的高可扩展性问题的严峻挑战?br /> 事实上,MySpace的Web服务器和数据库经常性超负荷Q其用户频繁遭遇“意外错误”?#8220;站点ȝl护”{告C。包括Drew在内的MySpace用户l常无法收发消息、更C料或处理其他日常事务Q他们不得不在论坛抱怨不停?br />
其是最q,MySpace可能l常性超负荷。因为Keynote Systems公司性能监测服务机构负责人Shawn White_“难以惌Q在有些时候,我们发现20%的错误日志都来自MySpaceQ有时候甚臌?0%以至40%……而Yahoo、Salesforce.com和其他提供商用服务的站点Q从来不会出现这L数字?#8221;他告诉我们,其他大型站点的日错误率一般就1%多点?br />
Z提及QMySpace?006q??4h上开始了长达12时的瘫痪,期间只有一个可讉K面——该面解释说位于洛杉矶的主数据中心发生故障。ؓ了让大家耐心{待服务恢复Q该面提供了用Flash开发的zօ人(Pac-ManQ游戏。Web站点跟踪服务研究公司ȝ理Bill Tancer_其有趣的是QMySpace瘫痪期间Q访问量不降反升Q?#8220;q说明了Z对MySpace的痴q——所有h都拥在它的门口等着放行”?br /> 现Nielsen Norman Group 咨询公司负责人、原Sun Microsystems公司工程师,因在Web站点斚w的评闻名的Jakob Nielsen_MySpace的系l构建方法显然与Yahoo、eBay以及Google都不相同。和很多观察家一P他相信MySpace对其成长速度始料未及?#8220;虽然我不认ؓ他们必须在计机U学领域全面创新Q但他们面对的的是一个巨大的U学N?#8221;他说?br />
MySpace开发h员已l多ơ重构站点Y件、数据库和存储系l,以满爆炸性的成长需要,但此工作怸会停息?#8220;像_刷金门大桥Q工作完成之Ӟ是重新来过之日?#8221;Q译者注Q意指工Z桥头开始粉P当到达桥时Q桥头涂料已l剥落,必须重新开始)MySpace技术副总裁Jim Benedetto说?br /> 既然如此QMySpace的技术还有何可学之处Q因为MySpace事实上已l解决了很多pȝ扩展性问题,才能走到今天?br />
Benedetto说他的项目组有很多教训必LȝQ他们仍在学习,路O漫而修q。他们当前需要改q的工作包括实现更灵zȝ数据~存pȝQ以及ؓ避免再次出现cM7月瘫痪事件的地理上分布式架构?br />
背景知识
MySpace目前的努力方向是解决扩展性问题,但其领导人最初关注的是系l性能?br /> 3q多前,一家叫做Intermix MediaQ早先叫eUniverse。这家公总事各cȝ(sh)子邮件营销和网上商务)的公司推ZMySpace。而其创徏人是Chris DeWolfe和Tom AndersonQ他们原来也有一家叫做ResponseBase的电(sh)子邮件营销公司Q后?002q出售给Intermix。据Brad GreenspanQIntermix前CEOQ运作的一个网站披ԌResponseBase团队为此获得2百万金外加分红。Intermix是一安具R略性的互联|商务公司——部分做法可能有点过头?005q_U约L察长Eliot Spitzer——现在是U约州长——v诉Intermix使用恶意q告软g推广业务QIntermix最后以790万美元的代h(hun)达成和解?br />
2003q_国国会通过《反垃圾邮g法》(CAN-SPAM ActQ,意在控制滥发邮g的营销行ؓ。Intermix领导人DeWolfe和Anderson意识到新法案严重打d司的?sh)子邮g营销业务Q?#8220;因此必须L新的方向?#8221;受聘于Intermix负责重写公司邮g营销软g的Duc Chau说?br /> 当时有个叫Friendster的交友网站,Anderson和DeWolfe很早是它的会员。于是他们决定创q|上C֌。他们去除了Friendster在用戯我表q方面的诸多限制Qƈ重点H出音乐Q尤其是重金属乐Q,希望以此吸引用户。Chau使用Perl开发了最初的MySpace版本Q运行于Apache Web服务器,后台使用MySQL数据库。但它没有通过l审Q因为Intermix的多数开发h员对ColdFusionQ一个Web应用E序环境Q最初由Allaire开发,CؓAdobe所有)更ؓ熟?zhn)。因此,最后发布的产品采用ColdFusion开发,q行在Windows上,q用MS SQL Server作ؓ数据库服务器?br /> Chau在那时d了公司,开发工作交l其他hQ包括Aber WhitcombQIntermix的技术专Ӟ现在是MySpace技术ȝQ和BenedettoQMySpace现技术副总裁Q大概于MySpace上线一个月后加入)?br />
MySpace上线?003q_恰恰是Friendster在满x益增长的用户需求问题上遭遇ȝ的时期。在财富杂志最q的一ơ采访中QFriendster总裁Kent Lindstrom承认他们的服务出现问题选错了时候。那ӞFriendster传输一个页面需?0?0U,而MySpace只需2?U?br />
l果QFriendster用户开始{投MySpaceQ他们认为后者更为可靠?br /> 今天QMySpace无疑已是C֌|站之王。社区网站是指那些帮助用户彼此保持联pR通过介绍或搜索、基于共同爱好或教育l历交友的Web站点。在q个领域比较有名的还有最初面向大学生的Facebook、侧重职业交的LinkedInQ当然还不了Friendster。MySpace宣称自己?#8220;下一代门?#8221;Q强调内容的丰富多彩Q如音乐、趣事和视频{)。其q作方式颇似一个虚拟的夜M——ؓ未成qh在边上安排一个果汁吧Q而显著位|则是以性ؓ目的的约会,和寻扑ֈȀz֯气氛的年Mh的搜索服务?br />
用户注册Ӟ需要提供个人基本信息,主要包括c诏、性取向和婚姻状况。虽然MySpace屡遭批评Q指其ؓ|上性犯|提供了温床Q但对于未成qhQ有些功能还是不予提供的?br /> MySpace的个料页上表q自q方式很多Q如文本?#8220;关于本h”栏、选择加蝲入MySpace音乐播放器的歌曲Q以及视频、交友要求等。它q允许用户用CSSQ一UWeb标准格式语言Q用户以此可讄面元素的字体、颜色和面背景囑փQ自p计个人页面,q也提升了h气。不q结果是五花八门——很多用L面布局_野、颜色迷乱,q去后找不到东南西北Q不忍卒读;而有些h则用了专业设计的模版(可阅诅RToo Much of a Good Thing?》第49)Q页面效果很好?br /> 在网站上U?个月后,开始有大量用户邀h友注册MySpaceQ因此用户量大增?#8220;q就是网l的力量Q这U趋势一直没有停止?#8221;Chau说?br />
拥有Fox?sh)视|络?0th Century Fox׃公司的媒体帝国——新闻集团,看到了他们在互联|用户中的机会,于是?005q斥?.8亿美元收购了MySpace。新闻集团董事局dRupert Murdoch最q向一个投资团透露Q他认ؓMySpace目前是世界主要Web门户之一Q如果现在出售MySpaceQ那么可?0亿美元——这?005q收购h(hun)格的10倍还多!新闻集团q惊人地宣称QMySpace?006q?月结束的财政q度里L入约2亿美元,而且预期?007q度QFox Interactive公司L入将辑ֈ5亿美元,其中4亿来自MySpace?br /> 然而MySpaceq在l箋成长?2月䆾Q它的注册̎戯?.4亿,?005q?1月时不过4千万。当Ӟq个数字q不{于真实的用户个体数Q因为有些h可能有多个帐P而且个h资料也表明有些是乐队Q或者是虚构的名字,如L拉特Q译者注Q喜剧电(sh)影《Borat》主角)Q还有像Burger KingQ译者注Q美国最大的汉堡q锁集团Q这L品牌名?br />
当然Q这么多的用户不停发布消息、撰写评论或者更C料,甚至一些h整天都在Space上,必然lMySpace的技术工作带来前所未有的挑战。而传l新ȝ点的l大多数内容都是q辑团队整理后d提供l用h费,它们的内Ҏ(gu)据库通常可以优化为只L式,因ؓ用户评论{引L增加和更新操作很。而MySpace是由用户提供内容Q数据库很大比例的操作都是插入和更新Q而非d?br /> 览MySpace上的M个h资料Ӟpȝ都必d查询数据库,然后动态创建页面。当Ӟ通过数据~存Q可以减L据库的压力,但这U方案必解军_始数据被用户频繁更新带来的同步问题?br />
MySpace的站Ҏ(gu)构已l历?个版本——每ơ都是用h辑ֈ一个里E碑后,必须做大量的调整和优化。Benedetto_“但我们始l跟不上形势的发展速度。我们重构重构再重构Q一步步挪到今天”?br /> 管MySpace拒绝了正式采访,但Benedetto在参?1月于拉斯l加斯召开的SQL Server Connections会议时还是回{了Baseline的问题。本文的不少技术信息还来源于另一ơ重要会议——Benedetto和他的老板——技术ȝWhitcomb今年3月出席的Microsoft MIX Web开发者大会?br /> 据他们讲QMySpace很多大的架构变动都发生在2004?005q早期——用h在当时从几十万迅速攀升到了几百万?br />
在每个里E碑Q站点负担都会超q底层系l部分组件的最大蝲P特别是数据库和存储系l。接着Q功能出现问题,用户失声叫。最后,技术团队必Mؓ此修订系l策略?br /> 虽然?005q早期,站点账户数超q?百万后,pȝ架构到目前ؓ止保持了相对E_Q但MySpace仍然在ؓSQL Server支持的同时连接数{方面l攻坚,Benedetto_“我们已经可能把事情做到最?#8221;?br />
里程一Q?0万̎?/span>
按Benedetto 的说法,MySpace最初的pȝ很小Q只有两台Web服务器和一个数据库服务器。那时用的是Dell双CPU?G内存的系l?br /> 单个数据库就意味着所有数据都存储在一个地方,再由两台Web服务器分担处理用戯求的工作量。但像MySpace后来的几ơ底层系l修订时的情况一P三服务器架构很快不堪重负。此后一个时期内QMySpace基本是通过ȝ更多Web服务器来对付用户暴增问题的?br /> 但到?004q早期,MySpace用户数增长到50万后Q数据库服务器也已开始汗浃背?br /> 但和Web服务器不同,增加数据库可没那么简单。如果一个站点由多个数据库支持,设计者必考虑的是Q如何在保证数据一致性的前提下,让多个数据库分担压力?br /> 在第二代架构中,MySpaceq行?个SQL Server数据库服务器上——一个ؓ主,所有的新数据都向它提交Q然后由它复制到其他两个Q另两个全力向用户供l数据,用以在博客和个h资料栏显C。这U方式在一D|间内效果很好——只要增加数据库服务器,加大盘Q就可以应对用户数和讉K量的增加?br />
里程二Q?-2百万账户
MySpace注册数到?百万?百万区间后,数据库服务器开始受制于I/O定w——即它们存取数据的速度。而当时才?004q中Q距Mơ数据库pȝ调整不过数月。用L提交h被阻塞,像千h乐迷要挤q只能容U_百h的夜MQ站点开始遭?#8220;主要矛盾”QBenedetto_q意味着MySpace永远都会d落后于用户需求?br /> “有h?分钟都无法完成留aQ因此用hL抱怨说|站已经完蛋了?#8221;他补充道?br /> q一ơ的数据库架构按照垂直分割模式设计,不同的数据库服务于站点的不同功能Q如d、用戯料和博客。于是,站点的扩展性问题看似又可以告一D落了,可以歇一阵子?br /> 垂直分割{略利于多个数据库分担访问压力,当用戯求增加新功能ӞMySpace投入新的数据库予以支持它。̎户到?百万后,MySpaceq从存储讑֤与数据库服务器直接交互的方式切换到SANQStorage Area NetworkQ存储区域网l)——用高带宽、专门设计的|络大量磁盘存储设备连接在一P而数据库q接到SAN。这Ҏ(gu)施极大提升了pȝ性能、正常运行时间和可靠性,Benedetto说?br />
里程三Q?百万账户
当用Ll增加到3百万后,垂直分割{略也开始难以ؓl。尽站点的各个应用被设计得高度独立Q但有些信息必须׃n。在q个架构里,每个数据库必L各自的用戯副本——MySpace授权用户的电(sh)子花名册。这意味着一个用h册时Q该条̎戯录必d9个不同数据库上分别创建。但在个别情况下Q如果其中某台数据库服务器时不可到达,对应事务׃p|Q从而造成账户非完全创建,最l导致此用户的该Ҏ(gu)务无效?br /> 另外一个问题是Q个别应用如博客增长太快Q那么专门ؓ它服务的数据库就有巨大压力?br /> 2004q中QMySpace面Web开发者称之ؓ“向上扩展”?#8220;向外扩展”Q译者注QScale Up和Scale OutQ也U硬件扩展和软g扩展Q的抉择——要么扩展到更大更强、也更昂늚服务器上Q要么部|大量相对便宜的服务器来分担数据库压力。一般来_大型站点們֐于向外扩展,因ؓq将让它们得以保留通过增加服务器以提升pȝ能力的后路?br /> 但成功地向外扩展架构必须解决复杂的分布式计算问题Q大型站点如Google、Yahoo和Amazon.comQ都必须自行研发大量相关技术。以GoogleZQ它构徏了自q分布式文件系l?br /> 另外Q向外扩展策略还需要大量重写原来YӞ以保证系l能在分布式服务器上q行?#8220;搞不好,开发h员的所有工作都白?#8221;QBenedetto说?br /> 因此QMySpace首先重Ҏ(gu)在了向上扩展上,p了大U?个半月时间研I升U到32CPU服务器以理更大数据库的问题。Benedetto_“那时候,q个Ҏ(gu)看似可能解决一切问题?#8221;如稳定性,更棒的是对现有Y件几乎没有改动要求?br /> p糕的是Q高端服务器极其昂贵Q是购置同样处理能力和内存速度的多台服务器d的很多倍。而且Q站Ҏ(gu)构师预测Q从长期来看Q即便是巨型数据库,最后也会不堪重负,Benedetto_“换句话讲Q只要增长趋势存在,我们最后无论如何都要走上向外扩展的道\?#8221;
因此QMySpace最l将目光Ud分布式计架构——它在物理上分布的众多服务器Q整体必逻辑上等同于单台机器。拿数据库来_׃能再像过去那样将应用拆分Q再以不同数据库分别支持Q而必d整个站点看作一个应用。现在,数据库模型里只有一个用戯Q支持博客、个料和其他核心功能的数据都存储在相同数据库?br /> 既然所有的核心数据逻辑上都l织C个数据库Q那么MySpace必须扑ֈ新的办法以分担负荷——显Ӟq行在普通硬件上的单个数据库服务器是无能为力的。这ơ,不再按站点功能和应用分割数据库,MySpace开始将它的用户按每百万一l分Ԍ然后各l的全部数据分别存入独立的SQL Server实例。目前,MySpace的每台数据库服务器实际运行两个SQL Server实例Q也是说每台服务器服务大约2百万用户。Benedetto指出Q以后还可以按照q种模式以更粒度划分架构,从而优化负荷分担?br /> 当然Q还是有一个特D数据库保存了所有̎L名称和密码。用L录后Q保存了他们其他数据的数据库再接服务。特D数据库的用戯虽然庞大Q但它只负责用户dQ功能单一Q所以负药是比较容易控制的?br />
里程四Q?百万??百万账户
2005q早期,账户辑ֈ9百万后,MySpace开始用Microsoft的C#~写ASP.NETE序。C#是C语言的最新派生语aQ吸收了C++和Java的优点,依托于Microsoft .NET框架QMicrosoftY件组件化和分布式计算而设计的模型架构Q。ASP.NET则由~写Web站点脚本的ASP技术演化而来Q是Microsoft目前L的Web站点~程环境?br /> 可以说是立竿见媄QMySpace马上发现ASP.NETE序q行更有效率Q与ColdFusion相比Q完成同样Q务需消耗的处理器能力更。据技术ȝWhitcomb_C码需?50台服务器完成的工作,如果用ColdFusion则需?46台。Benedettoq指出,性能上升的另一个原因可能是在变换Y件^収ͼq用新语a重写代码的过E中Q程序员复审q优化了一些功能流E?br />
最l,MySpace开始大规模q移到ASP.NET。即便剩余的部分ColdFusion代码Q也从Cold-Fusion服务器搬CASP.NETQ因Z们得CBlueDragon.NETQ乔M州阿法利塔New Atlanta Communications公司的品,它能ColdFusion代码自动重新~译到Microsoftq_Q的帮助?br /> 账户辑ֈ1千万ӞMySpace再次遭遇存储瓉问题。SAN的引入解决了早期一些性能问题Q但站点目前的要求已l开始周期性超SAN的I/O定w——即它从盘存储pȝd数据的极限速度?br /> 原因之一是每数据?百万账户的分割策略,通常情况下的可以将压力均分到各台服务器Q但现实q一成不变。比如第七台账户数据库上U后Q仅?天就被塞满了Q主要原因是?jng)罗里达一个乐队的歌迷疯狂注册?br /> 某个数据库可能因ZQ何原因,在Q何时候遭遇主要负Pq时QSAN中绑定到该数据库的磁盘存储设备簇可能过载?#8220;SAN让磁盘I(y)/O能力大幅提升了,但将它们l定到特定数据库的做法是错误的?#8221;Benedetto说?br /> 最初,MySpace通过定期重新分配SAN中数据,以让其更为均衡的Ҏ(gu)基本解决了这个问题,但这是一个h工过E,“大概需要两个h全职工作?#8221;Benedetto说?br /> 长期解决Ҏ(gu)是迁Ud虚拟存储体系上,q样Q整个SAN被当作一个巨型存储池Q不再要求每个磁盘ؓ特定应用服务。MySpace目前采用了一U新型SAN讑֤——来自加利福g州弗里蒙特的3PARdata?br /> ?PAR的系l里Q仍能在逻辑上按定w划分数据存储Q但它不再被l定到特定磁盘或盘,而是散布于大量磁盘。这׃均分数据讉K负荷成ؓ可能。当数据库需要写入一l数据时QQ何空闲磁盘都可以马上完成q项工作Q而不再像以前那样d在可能已l过载的盘阵列处。而且Q因为多个磁盘都有数据副本,d数据Ӟ也不会SAN的Q何组件过载?br /> ?005q春天̎h辑ֈ1?百万ӞMySpace又启用了新的{略以减d储系l压力,卛_加数据缓存层——位于Web服务器和数据库服务器之间Q其唯一职能是在内存中徏立被频繁h数据对象的副本,如此一来,不访问数据库也可以向Web应用供给数据。换句话_100个用戯求同一份资料,以前需要查询数据库100ơ,而现在只需1ơ,其余都可从缓存数据中获得。当然如果页面变化,~存的数据必M内存擦除Q然后重C数据库获取——但在此之前Q数据库的压力已l大大减轻,整个站点的性能得到提升?br /> ~存为那些不需要记入数据库的数据提供了驿站Q比如ؓ跟踪用户会话而创建的临时文g——Benedetto坦言他需要在q方面补课,“我是数据库存储狂热分子,因此我L想着万事万物都存到数据库?#8221;但将像会话跟t这cȝ数据也存到数据库Q站点将陷入泥沼?br /> 增加~存服务器是“一开始就应该做的事情Q但我们成长太快Q以致于没有旉坐下来好好研I这件事情?#8221;Benedetto补充道?br />
里程五Q??百万账户
2005q中期,服务账户数达??百万ӞMySpace切换Cq处于beta试的SQL Server 2005。{换何太急?L看法?005版支?4位处理器。但Benedetto_“q不是主要原因,管q也很重要;主要q是因ؓ我们对内存的渴求?#8221;支持64位的数据库可以管理更多内存?br /> 更多内存意味着更高的性能和更大的定w。原来运?2位版本的SQL Server服务器,能同时用的内存最多只?G。切换到64位,好像加_了输水的直径。升U到SQL Server 2005?4位Windows Server 2003后,MySpace每台服务器配备了32G内存Q后?006q再ơ将配置标准提升?4G?br />
意外错误
如果没有对系l架构的历次修改与升U,MySpaceҎ(gu)不可能走C天。但是,Z么系l还l常吃撑着了?很多用户抱怨的“意外错误”是怎么引v的呢Q?br /> 原因之一是MySpace对Microsoft的Web技术的应用已经q入qMicrosoft自己也才刚刚开始探索的领域。比?1月,出SQL Server最大同时连接数QMySpacepȝ崩溃。Benedetto_q类可能引发pȝ崩溃的情况大概三天才会出Cơ,但仍然过于频J了Q以致惹人恼怒。一旦数据库|工Q?#8220;无论q种情况什么时候发生,未缓存的数据都不能从SQL Server获得Q那么你必然看C?#8216;意外错误’提示?#8221;他解释说?br /> d夏天QMySpace的Windows 2003多次自动停止服务。后来发现是操作pȝ一个内|功能惹的祸——预防分布式拒绝服务dQ黑客用很多客h向服务器发v大量q接hQ以致服务器瘫痪Q。MySpace和其他很多顶U大站点一P肯定会经帔R受攻击,但它应该从网l而不是依靠Windows本n的功能来解决问题——否则,大量MySpace合法用户q接时也会引h务器反击?br /> “我们׃大约一个月旉LW(wng)indows 2003服务器自动停止的原因?#8221;Benedetto说。最后,通过Microsoft的帮助,他们才知道该怎么通知服务器:“别开枪,是友军?#8221;
紧接着是在d7月某个周日晚上,MySpace总部所在地z杉矶停?sh),造成整个pȝ停运12时。大型Web站点通常要在地理上分布配|多个数据中心以预防单点故障。本来,MySpaceq有其他两个数据中心以应对突发事Ӟ但Web服务器都依赖于部|在z杉矶的SAN。没有洛杉矶的SANQWeb服务器除了恳求你耐心{待Q不能提供Q何服务?br /> Benedetto_L据中心的可靠性通过下列措施保证Q可接入两张不同늽Q另有后备电(sh)源和一台储备有30天燃料的发电(sh)机。但在这ơ事故中Q不仅两张电(sh)|失效,而且在切换到备䆾甉|的过E中Q操作员烧掉了主动力U\?br /> 2007q中QMySpace在另两个后备站点上也了SAN。这对分担负荷大有帮助——正常情况下Q每个SAN都能负担三分之一的数据访问量。而在紧急情况下QQ何一个站炚w可以独立支撑整个服务QBenedetto说?br /> MySpace仍然在ؓ提高E_性奋斗,虽然很多用户表示了够信M能原谅偶现的错误面?br /> “作ؓ开发h员,我憎恶BugQ它太气Z?#8221;Dan Tannerq个31岁的德克萨斯软g工程师说Q他通过MySpace重新联系C高中和大学同学?#8220;不过QMySpaceҎ(gu)们的用处很大Q因此我们可以原谅偶发的故障和错误?#8221; Tanner_如果站点某天出现故障甚至崩溃Q恢复以后他q是会l用?br /> q就是ؓ什么Drew在论坛里咆哮Ӟ大部分用户都告诉他应该保持^静,如果{几分钟Q问题就会解决的原因。Drew无法q静Q他写道Q?#8220;我已l两ơ给MySpace发邮Ӟ而它说一时前还是正常的Q现在出了点问题……完全是一堆废话?#8221;另一个用户回复说Q?#8220;毕竟它是免费的?#8221;Benedetto坦承100%的可靠性不是他的目标?#8220;它不是银行,而是一个免费的服务?#8221;他说?br /> 换句话说QMySpace的偶发故障可能造成某h最后更新的个h资料丢失Q但q不意味着|站弄丢了用Lp?#8220;关键是要认识刎ͼ与保证站Ҏ(gu)能相比Q丢失少许数据的故障是可接受的?#8221;Benedetto说。所以,MySpace甘冒丢失2分钟?时内Q意点数据的危险,在SQL Server配置里g长了“checkpoint”操作——它?yu)待更新数据怹记录到磁盘——的间隔旉Q因样做可以加快数据库的q行?br /> Benedetto_同样Q开发h员还l常在几个小时内完成构思、编码、测试和发布全过E。这有引入Bug的风险,但这样做可以更快实现新功能。而且Q因行大规模真实试不具可行性,他们的测试通常是在仅以部分z跃用户为对象,且用户对软g新功能和改进不知里的情况下q行的。因Z实上不可能做真实的加载测试,他们做的试通常都是针对站点?br /> “我们犯过大量错误Q?#8221;Benedetto_“但到头来Q我认ؓ我们做对的还是比做错的多?#8221;


jinfeng_wang 2010-04-16 14:22 发表评论
]]>
Web 2.0|站性能调优实践 zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318511.htmljinfeng_wangjinfeng_wangFri, 16 Apr 2010 05:58:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318511.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318511.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318511.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318511.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318511.htmlhttp://www.yaosansi.com/post/1150.html 


Web2.0|站性能调优实践

                                           ?王宗?/p>

当前web2.0革命风v云涌Qweb2.0服务Q而服务最基本的要求是速度快和E_Q离开q两个谈功能强大和易用性都没有M意义。本文介l一些关于笔者运营一个web2.0|站的优化心得和l验Q希望能够和大家共同探讨?/p>

Web2.0|站不同于以往以静态信息ؓȝ|站架构Q以往的结构大体分?层,一个是客户端浏览器Q一个就是web服务器;而web2.0以动态和交互ZQ一般是3层或?层,在静态信息网站的l构上的web服务器后端会增加应用服务器和数据库。一般会把浏览器和web服务器归为最上一层即为web层,应用服务器ؓ中间一层,数据库ؓ最底层。从优化角度来讲Q越上层优化获得益处大Q优化也是从上自下而来?/p>

Web层优?/h3>

DNS的解析时?/h4>

q个旉是在用L一ơ访问网站的时候生,解析旉会媄响用L讉K感受Q因此想要网站响应速度快,W一是不要在DNS解析上生问题。另外DNS的TTL旉也要考量QIE的DNSq期旉?0分钟QTTL讄的比q个长一点就可以。另外在web服务器上使用keep-live也会减少DNS查询ơ数?/p>

降低览器发赯求的数量

量降低览器发赯求的数量Q就是说量能够让浏览器~存M可以~存的东ѝ这样当用户讉Kq一ơ后Q第二次讉K可能会得发Lh数趋q?或者等?Q如果是静态的面则可能是0。方法包括:

把所有的样式表文件ƈ??/p>

把所有的js文gq成1?/p>

囄量能够合成1张,q个跟以前不一P现在大多数是adsl上网Q反而是大量的零图片能够媄响速度

面布局与样?/h4>

面采用xhtmlQ采用div+css布局Q而把样式表和xhtml文g分开Q一则能够降低xhtml文g大小Q二则能够对样式表文件进行其他缓存处理。这里还有个ui设计的原则,ui跟系l结构一P简z越好,q样整体面代码会比较少Q速度也会比较不错?/p>

JavaScript文g

JavaScript文g也最好放到html文g外,原因同上?/p>

静态文件的优化Ҏ(gu)

a)目前大多数的览器都支持gzip压羃文gQ因此ؓ文本、静态页面、样式表、JavaScript文g{可以压~处理的文gq行压羃处理能够减少内容获取旉Q一般压~完的大ؓ原大的10-30%。这个在apache{web服务器上q行讄Q笔者用lighttpd的设|ؓQ?/p>

server.modules = (

      ….

      "mod_compress",

      …

)

compress.cache-dir="/usr/local/lighttpd/cache"

compress.filetype = ("text/plain", "text/html", "text/css", "text/javascript")

b)q可以在静态文件服务器前面增加~存服务器比如squidQ进一步增强客L的访问性能。如果有好的财力Q还可以使用一些商业的CDN加速服务?/p>

应用Cookie的注意事?/h4>

Cookie的应用要注意Q要限制cookie的应用域和应用的目录以及q期旉。不然如果用hW一ơ访问的话,可能q一个小的静态图片都要发送cookie到服务器Q这样增加了通信负蝲。另外要限制cookie的大,一?k的cookie能够增加延迟辑ֈ80ms?/p>

提高面速度

面?-4个不同域名的服务器提供服务能够提高速度Q这个国外也有研I证明。比如主html文g由app.domain.com提供Q样式表由style.domain.com提供Q图片等由img.domain.com提供Q这h览器可以同时从多个服务器下蝲文gQ速度p够上厅R但是最好不要超q?个?/p>

样式表文件位|?/h4>

把样式表文g攑֜面?lt;head>Q这栯够先d。因为在ie中有个样式表的问题,样式表如果没有加载完会媄响后面的html内容的页面显C,因此虽然html文g都已l在览器了Q但是页面还是显CZ出来?/p>

把JavaScriptUdhtml文g末尾

把JavaScriptUdhtml文g末尾。ؓ什么这么做呢,因ؓJavaScript处理的过E中会阻塞后面的面昄Qƈ且也会得httph也被L。笔者的|站有q这L例子Q网站上放了一个合作方的JavaScriptQ结果每ơ访问时候感觉页面都停滞Q用户体验特别差Q后来让同事处理了一下,攑ֈ末尾{页面加载完了再昄在原有位|,一下子好了?/p>

量避免跌{

量避免跌{比如301?02。如果必ȝ话,?01?02的页面添加过期头。笔者原来的单点d需要进行蟩转,后来改进了不需要蟩转,整体的速度效果出来了?/p>

U除重复的脚?/h4>

要移除重复的脚本Qie会对重复的脚本发起重复的httphQ大多数|站在运营一D|间都有可能出现这个情况,W者的|站中就l常有市Zh员添加的重复的广告脚本?/p>

AJAX内容

AJAX内容也是可以q行~存的,同样可以压羃和缓存异步调用的xml、json{数据?/p>

对爬虫进行限?/h4>

对爬虫进行限Ӟ国内的一些爬虫非常厉宻Iq且不遵守robots规矩Q经常有反应某某厉害爬虫把网站搞瘫的事g。怎么对爬虫进行限制呢Q只能在web服务器上下功夫了Qapache{服务器都能够进行限ӞW者的lighttpd限制10个ƈ发的配置如下Q?nbsp;

 evasive.max-conns-per-ip = 10

web层的优化目的是极大的利用了览器的~存Ҏ(gu),从而达到几乎是本地讉K的速度Q下图是W者访问douban.com首页的效果图Ҏ(gu)Q?/p>

前一列数据是I的~存所需要下载的文g大小和httph数量Q后面是真实讉K的带cache的情况,效果特别明显。httph减少?5%Q内容cache?2%?/p>

应用E序层优?/h3>

应用服务器的优化

Php的可以采用一些优化手D|如Zend Optimizer、eAccelerator、MMCache、Zend Performance Suite{?/p>

Java的可以采用一些性能强的jdk、应用服务器Q对jdk参数q行优化{等

使用ETag

ETag像版本控制服务器中的版本号一P每次更新后的ETag是不一LQ而浏览器处理q似版本服务器的客L一P先把版本号发到服务器h。ETag的处理过E,先是Web服务器在响应的http头中发送ETagQ比如这P

ETag: "1111-2222-3333"

Last-Modified: Thu, 07 Oct 2007 15:20:18 GMT

而浏览器如果再次h该页面就会发送类似如下的_

If-None-Match: "1111-2222-3333"

If-Modified-Since: Thu, 07 Oct 2007 15:20:18 GMT

此时Q如果该面没有M变更Q则web服务器会响应一?04的头Qƈ且不需要附带页面内容给览器(即不需要再动态生成页面内容)Q这样就大大减少了服务器的处理和|\通信负蝲?/p>

同步变异?/h4>

同步变异步,在web2.0|站中经常有很复杂的处理Q比如一个用L注册q需要发邮g{操作,有时候可能还有其他的处理Q这LL{待旉比较长,q且Ҏ(gu)出现错误。此U情况下Q把其他处理变成异步的,从而直接把面快响应l用戗笔者的一个数据上传的E序也是如此处理Q一大堆数据Q上传时间可能就1-2U,而处理时间可能长的需要接q?0U(需要在数据库中q行上千ơ的插入操作Q,而在应用服务器容器内处理耗时则更长,W者后来改成异步处理以后,用户满意度则大幅上升?/p>

使用~存

q是~存Q可能的情况下尽量用缓存,毕竟现在内存非常便宜Q用I间换取旉效率应该是非常划的。尤其是对耗时比较长的、需要徏立网l链接的Q方法:采用memcachedq行数据库或者常用数据的~存Q应用数据库~冲池减徏立数据库q接的时?/p>

采用gzip压羃动态页?/h4>

可能情况下,也可以采用gzip压羃动态页面。如果服务器较多Qcpu负蝲不高Q则可以考虑对动态页面增加gzip压羃功能

集群处理

讉K压力大的时候,对应用服务器采用集群处理?/p>

应用服务器的优化主要是减程序处理的旉Q提高运行效率?/p>

数据库优?/h3>

q个议题跟具体数据库关系比较大,议题也比较广泛,W者就只简要列举一下:

讄专门的DBAQ专门负责数据库的安装、优化;对sqlq行优化采用数据库集和复制功能分担数据库压力?/p>

其他优化措施

|站的优化涉及的斚w比较多,其他斚w涉及的还包括|站架构、操作系l、服务器g、网l设备、isp机房|络{等的调优?/p>

工具

W者用到的工具Q都是firefox插gQ所以firefox是必备的了:

1、LiveHTTPHeaders (http://livehttpheaders.mozdev.org/)

2、Firebug (http://getfirebug.com)

3、YSlow (http://developer.yahoo.com/yslow/)Q要先装Firebug

4、Web Developer (http://chrispederick.com/work/web-developer/)

除了q些免费的工具外Q还可以采用一些商业的|站性能监测服务。一般网站性能监测服务商都会在不同的isp讄数据采集点,然后会定期模拟浏览器的访问对|站q行讉K获取各种数据Q比如dsn查询旉、第一个包获取旉、整个页面加载时间等{,然后汇d数据中心。数据中心则可以产生性能报表、不同时间的可访问率、哪个ispҎ(gu)出问题、发报等{。如果预够的话,可以采用q个服务。国外的有keynote、ip-label{,功能比较齐全Q但是服务费用比较贵而且国内的点比较?yu)。国内近些年也开始涌现出一些厂商,比如|络。笔者用的监测pȝ的图例:

W者网?q不同阶D늚优化q程

优化的原则是量不去优化Q在未发生性能问题的时候,没有必要M门考虑l节的性能问题Q当然大的结构应该是能够适应|站不断发展变化的。笔者的|站q?q的优化q程如下Q?/p>

1、开发完成,刚上U的时候,不做优化Q用户量,用了3台服务器?/p>

2?0万用L时候,主要对sqlq行了优化,q是3台服务器?/p>

3?0万用户到100万的q程中,采用了AJAX{,因此开始关注JavaScript的优化手D,讉K量也快速上去,因此寚w态文件进行分dƈ优化。服务器也进行了扩展Q扩展到5台服务器?/p>

4?00?200万用P业务pȝ增加了很多,因此数据库采用了复制Q程序方面应用了各种~存处理Q在数据库和E序之间增加了memcachedq行数据~存?/p>

5、在200万用户以上,主要在程序架构上做文章,Ҏ(gu)些服务用了集群。另外ؓ了监国内不同城市、isp的网l状况,使用了商业化的网站性能监测服务?/p>

jinfeng_wang 2010-04-16 13:58 发表评论
]]>
|络服务器设计的模型及一些设计方法zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318495.htmljinfeng_wangjinfeng_wangFri, 16 Apr 2010 03:36:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318495.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318495.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318495.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318495.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318495.html http://blog.csdn.net/proad/archive/2008/04/16/2296925.aspx


1. 常用服务器模?/strong>
a.q代服务器:只有一个进E?U程处理h。一般ؓ单进E?加上select多\复用,非阻塞socket?br /> b.q代/q发混合型服务器Q^时P代处理,Ҏ(gu)耗大的请求ƈ发处理。处理请求时讄一个超Ӟ当请求的处理旉时Ӟ创徏一个进E?U程Q把处理转给新的q程/U程处理Q主q程/U程l箋处理其他h?br /> c.q发服务器:多个q程/U程q发处理h?/p>

2. 以上三类的服务器比较
q代服务器:最单,性能不高?br /> q发服务器:性能较高Q但l构相对比较复杂Q开发难度中{?br /> q代/q发混合型服务器Q性能不错Q但l构通常比单U的q发服务器更复杂?/p>

3. 多进E的q发服务?/strong>
a. 每个q接fork一个进E:主进Eaccpetq接Q有新连接到来时fork一个进E,然后l箋acceptQ等待新的连接。数据传输由子进E处理,处理完后子进Eexit。每个子q程只处理一个连接?br /> b. Preforkq程Q主q程预先fork一些进E,各个子进E竞争acceptQ然后处理数据传输。一个子q程可以处理一个连接,也可以同时处理多个连接(通过select{)?br /> c. Preforkq程Q由父进EaccepthQ通过管道{发fd到子q程Q子q程收到fd后,处理数据传输Q处理结束后通知父进E。父q程处理的事情比较简单,Ҏ(gu)监控子进E?/p>

以上3U方式性能比较Q?br /> a.每个q接fork一个进E:处理smtp{状态较多,数据量比较大时比较简单实用,M性能不大好?br /> b.Preforkq程Q各个子q程竞争acceptQ比较简单,性能不错?br /> c.Preforkq程Q由父进EaccepthQ通过管道{发fd到子q程Q代码复杂,性能一般不如上一U?/p>

4. 多线E的q发服务?/strong>
a.每个q接一个线E?br /> b.Prethread多个U程Q各个线E互斥accept
c.Prethread多个U程Q主U程acceptq分发连接给子线E?/p>

5. 多进E与多线E的比较
使用U程的模型:性能比用进E要高,但代码比较复杂,对代码质量要求更高,U程出错后可能会影响到所有线E,多进E的模式一个进E出错一般不会媄响其他进E?br /> 多线E模型共享数据比较简单有效,多进E模型共享数据比较麻烦,效率也不如线E?/p>

6. 一些流行的|络服务器采用的模型

Sendmail: 采用多进E,每个q接fork一个进E?
每个q接fork一个子q程
子进E只处理一个连?br /> 子进Efork一个localmailq程Q可以由用户自己~写Q,通过道把数据{llocalmail处理Q把邮g处理业务逻辑独立出来
优点Q结构简单,不用l护复杂的状态机

Apache1.3:采用多进E? preforkq程
子进E竞争acceptQ每ơ只处理一个连?br /> 主进E不acceptQ根据负载情况调整子q程数量
子进E运行一D|间后Q主q程会让它退出,然后创徏一个新的进E,防止内存泄漏{?br /> 主进E通过shared memory监控子进E?/p>

UdQQ: Prefork多个q程Q竞争accept,
典型的一问一{TCP服务器,l构?br /> 每个q程通过select可以同时处理多个q接
采用q种l构的原因有Q?br /> 每秒h<1000Q可以满?br /> l构单,Ҏ(gu)开发、维?/p>

jinfeng_wang 2010-04-16 11:36 发表评论
]]>
Network Programming Using Libevent zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318479.htmljinfeng_wangjinfeng_wangFri, 16 Apr 2010 02:29:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318479.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318479.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318479.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318479.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318479.html

在課堂上孔R Unix Network Programming 後,我們知道在處理?User 時會有幾E方法解決:
  1. 一個新?Connection 進來Q用 fork() 產生一?Process 處理?
  2. 一個新?Connection 進來Q用 pthread_create() 產生一?Thread 處理?
  3. 一個新?Connection 進來Q丟?Event-based ArrayQ由 Main Process ?Nonblocking 的方式處理所有的 I/O?br />
這三E方法當然也都有各自的缺點:
  1. ?fork() 的問在於每一?Connection 進來時的成本太高?
  2. ?Multi-thread 的問在?Thread-safe ?Deadlock 問題難以解決Q另外有 Memory-leak 的問要處理?
  3. ?Event-based 的方式在於實做上不好寫,其是要注意C件產生時必須 NonblockingQ於是會需要實?Buffering 的問,?Multi-thread 所會遇到的 Memory-leak 問題在這邊會更嚴重。而在?CPU 的系i׃沒有辦法使用到所有的 CPU resource?br />
當然Q針前面兩項有各自的解法:
  1. ?Poll 的方式解決:當一?Process 處理完一?Connection 後,不直接死掉,而繼U回?accept() 的狀態繼U處理,但這樣會遇?Memory-leak 的問,於是採用這種方式的h通常會再加上「處理過 N ?Connection 後死掉,?Parent Process ?fork() 一L的」。最有名的例子是 Apache 1.3?
  2. Thread-safe 的問可以透過自己撰寫Q或是尋扑օ?Thread-safe Library 直接使用。Memory-leak 的問可以試著透過 Garbage Collection Library 分析Z?a >Apache 2.0 ?Thread MPM 是使用這個模式?br />
然而,目前高效率的 Server 都偏好採?Event-basedQ一斚w是沒?Create Process/Thread 所造成?OverheadQ另外一斚w是不需要透過 Shared Memory 或是 Mutex 在不同的 Process/Thread 之間交換資料?br />
然而,Event-based 在實做上的幾個複雜的地方在於Q?br />
  1. select() ?poll() 的效率過慢,造成每次要判斗有哪些 Event 發生」這g事情的成本很高,這在 BSD 支援 kqueue()、Linux 支援 epoll()、Solaris 支援 /dev/poll 後就解決了,但這兩i?Function 都不?StandardQ於是在不同的^C必須再改一ơ?br />
  2. 因為 NonblockingQ所以在 write() 或是 send() 時滿了需要自?Buffering?
  3. 因為 NonblockingQ所以不能?fgets() 或是其他似?functionQ於是需要自己刻一?Nonblocking ?fgets()。但是用者所丟過來的資料又不能保證在一?read() ?recv() 有一行,於是要自己做 Buffering?/li>
實際上這三件事情在 libevent 都有 Library 處理掉了?br />
另外值得注意的一點在?libevent 使用的是 3-clause BSD license 而非 GPLQ所以在不想公開E式?(像是商業用? 的情況下會比其他?Library 適合?br />


接下來要談的?libevent 要如何用,不過Z方便赯Q我們直接寫一個很單?Time Server 來當作例子:當你連上M?Server 端直接提供時間,然後i束連線?br />
在這些例子面我以 FreeBSD 6.0 當作測試的^収ͼ另外使用 libevent 1.1a 當作 Event-based LibraryQCompile 時請使用 gcc -I/usr/local/include -o timeserver timeserver.c -L/usr/local/lib -levent (如果 libevent ?Header ?Library 攑֜ /usr/include ?/usr/lib 下的話可以省略這兩個參??br />
原始E式在文章的最後頭?br />
event_init() 表示初始?libevent 所使用到的變數?br />
event_set(&ev, s, EV_READ | EV_PERSIST, connection_accept, &ev) ?s 這?File Description 攑օ ev (W一個參數與W二個參?Q並且告知當事g (W三個參數的 EV_READ) 發生時要呼叫 connection_accept() (W四個參?Q呼叫時要把 ev 當作參數丟進去 (W五個參??br />
其中?EV_PERSIST 表示當呼叫進去的時候不要把這?event 拿掉 (J續保留?Event Queue 面)Q這點可以?connection_accept() 內在ad connection_time() 的程式碼做比較?br />
?event_add(&ev, NULL) 是?ev ad?event queue 面Q第二個參數指定的?Timeout 時間Q設定成 NULL 表示忽略這項a定?br />
最後的 event_dispatch() 表示進入 event loopQ當 Queue 面的Q何一?File Description 發生事g的時候就會進入 callback function 埯?br />
這隻E式非常_糙Q有很多地方沒有注意?Blocking 的問,這點我們就先不了。當跑v來以後你可以連到 port 7000Q就會出Ng面的i果Qgslin@netnews [~] [3:14/W5] t 0 7000

gslin@netnews [~/work/C] [3:15/W3] t 0 7000
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
Fri Nov 25 03:15:10 2005
Connection closed by foreign host.

最基本的用就是這樣了,你可?man event 看到完整的說明?br />
這是 timeserver.cQ?br />

#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <event.h>
#include <stdio.h>
#include <time.h>

void connection_time(int fd, short event, struct event *arg)
{
char buf[32];
struct tm t;
time_t now;

time(&now);
localtime_r(&now, &t);
asctime_r(&t, buf);

write(fd, buf, strlen(buf));
shutdown(fd, SHUT_RDWR);

free(arg);
}

void connection_accept(int fd, short event, void *arg)
{
/* for debugging */
fprintf(stderr, "%s(): fd = %d, event = %d.\n", __func__, fd, event);

/* Accept a new connection. */
struct sockaddr_in s_in;
socklen_t len = sizeof(s_in);
int ns = accept(fd, (struct sockaddr *) &s_in, &len);
if (ns < 0) {
perror("accept");
return;
}

/* Install time server. */
struct event *ev = malloc(sizeof(struct event));
event_set(ev, ns, EV_WRITE, (void *) connection_time, ev);
event_add(ev, NULL);
}

int main(void)
{
/* Request socket. */
int s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
perror("socket");
exit(1);
}

/* bind() */
struct sockaddr_in s_in;
bzero(&s_in, sizeof(s_in));
s_in.sin_family = AF_INET;
s_in.sin_port = htons(7000);
s_in.sin_addr.s_addr = INADDR_ANY;
if (bind(s, (struct sockaddr *) &s_in, sizeof(s_in)) < 0) {
perror("bind");
exit(1);
}

/* listen() */
if (listen(s, 5) < 0) {
perror("listen");
exit(1);
}

/* Initial libevent. */
event_init();

/* Create event. */
struct event ev;
event_set(&ev, s, EV_READ | EV_PERSIST, connection_accept, &ev);

/* Add event. */
event_add(&ev, NULL);

event_dispatch();

return 0;
}

 

這次要談的跟 Network Programming 沒有直接的關係?br />
在寫 Nonblocking Network Program 通常要處?Buffering 的問,但並不好寫,主要是因?read() ?recv() 不保證可以一ơ讀C行的份量進來?br />
?libevent 面提供相當不錯?Buffer Library 可以用,完整的說明在 man event 的時候可以看刎ͼ最常用的應該就是以 evbuffer_add()?code>evbuffer_readline() 這兩?FunctionQ其他的知道存在可以了Q需要的時候再ȝ詳細的用法?br />
下面直接提供 libevent-buff.c 當作例Q編譯後看執行結果,再回頭來?source code 應該有感覺了:

#include <sys/time.h>
#include <event.h>
#include <stdio.h>

void printbuf(struct evbuffer *evbuf)
{
for (;;) {
char *buf = evbuffer_readline(evbuf);
printf("* buf = %p, the string = \"\e[1;33m%s\e[m\"\n", buf, buf);
if (buf == NULL)
break;
free(buf);
}
}

int main(void)
{
struct evbuffer *evbuf;

evbuf = evbuffer_new();
if (evbuf == NULL) {
fprintf(stderr, "%s(): evbuffer_new() failed.\n", __func__);
exit(1);
}

/* Add "gslin" into buffer. */
u_char *buf1 = "gslin";
printf("* Add \"\e[1;33m%s\e[m\".\n", buf1);
evbuffer_add(evbuf, buf1, strlen(buf1));
printbuf(evbuf);

u_char *buf2 = " is reading.\nAnd he is at home.\nLast.";
printf("* Add \"\e[1;33m%s\e[m\".\n", buf2);
evbuffer_add(evbuf, buf2, strlen(buf2));
printbuf(evbuf);

evbuffer_free(evbuf);
}

 



jinfeng_wang 2010-04-16 10:29 发表评论
]]>
亿数据的高q发通用搜烦引擎架构设计zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/15/318434.htmljinfeng_wangjinfeng_wangThu, 15 Apr 2010 08:35:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/15/318434.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318434.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/15/318434.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318434.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318434.html http://blog.s135.com/post/360/


曄在七月,写过一文章──?a target="_blank">ZSphinx+MySQL的千万数据全文索(搜烦引擎Q架构设?/a>》,前公司的分类信息搜烦Z此架构,效果明显Q甚臛_很大一部分带Where条g的MySQL SQL查询Q都改用了Sphinx+MySQL搜烦。但是,q套架构仍存在局限:一是MySQL本n的ƈ发能力有限,?00?00个ƈ发连接下Q查询和更新比较慢了;二是׃MySQL表的主键与Sphinx索引的ID一一对应Q从而无法跨多表建立整站查询Q而且新增加类别还得修攚w|文Ӟ比较ȝQ三是因为和MySQL集成Q无法发挥出Sphinx的优ѝ?br />
  最q,我设计出了下列这套最新的搜烦引擎架构Q目前已l写?#8220;搜烦查询接口”?#8220;索引更新接口”的beta版。经试Q在一?#8220;奔腾?3.6GHz 双核CPU?GB内存”的普通PC机,7000万条索引记录的条件下Q?#8220;搜烦查询接口”q_查询速度?.0XXU(查询速度已经辑ֈ癑ֺ、谷歌、搜狗、中国雅虎等搜烦引擎的水qI详见文章末尾?#8220;?”Q,q且能够支撑高达5000的ƈ发连接;?#8220;索引更新接口”q行数据分析、入队列、返回信息给用户的全q程Q高?500 Requests/Sec?br />
  “队列控制?#8221;q一部分是核心,它要控制队列dQ更新MySQL主表与增量表Q更新搜索引擎数据存储层Tokyo TyrantQ准实时Q?分钟内)完成更新Sphinx增量索引Q定期合qSphinx索引。我预计在这周写出beta版?br />
点击在新H口中浏览此囄

  囄说明Q?/strong>
  1、搜索查询接口:
  ①、Web应用服务器通过HTTP POST/GET方式Q将搜烦关键字等条gQ传递给搜烦引擎服务器的search.php接口Q?br />   ②③、search.php通过Sphinx的APIQ我Ҏ(gu)最新的Sphinx 0.9.9-rc1 APIQ改写了一个C语言的PHP扩展sphinx.soQ,查询Sphinx索引服务Q取得满x询条件的搜烦引擎唯一IDQ?5位搜索唯一IDQ前5位类别ID+?0位原数据表主键IDQ列表;
  ④⑤、search.php这些ID号作为keyQ通过Memcache协议一ơ性从Tokyo Tyrant中mget取回ID号对应的文本数据?br />   ⑥⑦、search.php搜索结果集Q按查询条gQ进行摘要和关键字高亮显C处理,以JSON格式或XML格式q回lWeb应用服务器?br />
  2、烦引更新接口:
  ⑴、Web应用服务器通过HTTP POST/GET方式Q将要增加、删除、更新的内容告知搜烦服务器的update.php接口Q?br />   cupdate.php接收到的信息处理后Q写入TT高速队列(我基于Tokyo Tyrant做的一个队列系l)Q?br />   注:q两步的速度可达?500ơ请?U以上,可应?000万PV的搜索烦引更新调用?br />
  3、搜索烦引与数据存储控制Q?/strong>
  ㈠?#8220;队列控制?#8221;守护q程从TT高速队列中循环d信息Q每?0条,直到末尾Q;
  ㈡?#8220;队列控制?#8221;读取出的信息写入搜索引擎数据存储层Tokyo TyrantQ?br />   ㈢?#8220;队列控制?#8221;读取出的信?strong>异步
写入MySQL主表Q这张主表按500万条记录q行分区Q仅作ؓ数据怹性备份用Q;
  ㈣?#8220;队列控制?#8221;读取出的信息写入MySQL增量表;
  ㈤?#8220;队列控制?#8221;?分钟内,触发Sphinx更新增量索引QSphinx的indexer会将MySQL增量表作为数据源Q徏立增量烦引。Sphinx的增量烦引和作ؓ数据源的MySQL增量表成对应关系Q?br />   ㈥?#8220;队列控制?#8221;每间?时Q短暂停止从TT高速队列中d信息Qƈ触发Sphinx增量烦引合q入ȝ引(q个q程非常快)Q同时清IMySQL增量表(保证了MySQL增量表的记录数始l只有几千条臛_十万条,大大加快Sphinx增量索引更新速度Q,然后恢复从TT高速队列中取出数据Q写入MySQL增量表?br />
  本架构用的开源YӞ
  1、Sphinx 0.9.9-rc1
  2、Tokyo Tyrant 1.1.9
  3、MySQL 5.1.30
  4、Nginx 0.7.22
  5、PHP 5.2.6

  本架构自ȝ发的E序Q?/strong>
  1、搜索查询接口(search.phpQ?br />   2、烦引更新接口(update.phpQ?br />   3、队列控制器
  4、Sphinx 0.9.9-rc1 API的PHP扩展Qsphinx.soQ?br />   5、基于Tokyo Tyrant的高速队列系l?br />




在DELL PowerEdge 6850服务器(四颗64 位Inter Xeon MP 7110N处理?/ 8GB内存Q、RedHat AS4 Linux操作pȝ、MySQL 5.1.26、MyISAM存储引擎、key_buffer=1024M环境下实,单表1000万条记录的数据量Q这张MySQL表拥有int、datetime、varchar、text{类型的10多个字段Q只有主键,无其它烦引)Q用主键QPRIMARY KEYQ作为WHERE条gq行SQL查询Q速度非常之快Q只耗费0.01U?br />
  俄罗斯的开源全文搜索引擎Y?a target="_blank">SphinxQ单一索引最大可包含1亿条记录Q在1千万条记录情况下的查询速度?.xU(毫秒U)。Sphinx创徏索引的速度为:创徏100万条记录的烦引只需3?分钟Q创?000万条记录的烦引可以在50分钟内完成,而只包含最?0万条记录的增量烦引,重徏一ơ只需几十U?br />
  Z以上几点Q我设计Zq套搜烦引擎架构。在生环境q行了一周,效果非常不错。有旉我会专ؓ配合Sphinx搜烦引擎Q开发一个逻辑单、速度快、占用内存低、非表锁的MySQL存储引擎插gQ用来代替MyISAM引擎Q以解决MyISAM存储引擎在频J更新操作时的锁表gq问题。另外,分布式搜索技术上已无M问题?br />


  一、搜索引擎架构设计:
  1、搜索引擎架构图Q?/strong>
  点击在新H口中浏览此囄

  2、搜索引擎架构设计思\Q?/strong>
  (1)、调用方式最化:
  量方便前端Web工程师,只需要一条简单的SQL语句“SELECT ... FROM myisam_table JOIN sphinx_table ON (sphinx_table.sphinx_id=myisam_table.id) WHERE query='...';”卛_实现高效搜烦?br />
  (2)、创建烦引、查询速度快:
  ①、Sphinx Search 是由俄罗斯hAndrew Aksyonoff 开发的高性能全文搜烦软g包,在GPL与商业协议双许可协议下发行?br />   Sphinx的特征:
  •Sphinx支持高速徏立烦引(可达10MB/U,而Lucene建立索引的速度?.8MB/U)
  •高性能搜烦Q在2-4 GB的文本上搜烦Q^?.1U内获得l果Q?br />   •高扩展性(实测最高可?00GB的文本徏立烦引,单一索引可包?亿条记录Q?br />   •支持分布式检?br />   •支持Z短语和基于统计的复合l果排序机制
  •支持L数量的文件字D(数值属性或全文索属性)
  •支持不同的搜索模式(“完全匚w”Q?#8220;短语匚w”?#8220;M匚w”Q?br />   •支持作ؓMysql的存储引?br />
  ②、通过国外《High Performance MySQL》专家组的测试可以看出,Ҏ(gu)主键q行查询的类?#8220;SELECT ... FROM ... WHERE id = ...”的SQL语句Q其中id为PRIMARY KEYQ,每秒钟能够处?0000ơ以上的查询Q而普通的SELECT查询每秒只能处理几十ơ到几百ơ:
  点击在新H口中浏览此囄

  ③、Sphinx不负责文本字D늚存储。假讑ְ数据库的id、date、title、body字段Q用sphinx建立搜烦索引。根据关键字、时间、类别、范围等信息查询一下sphinxQsphinx只会查询结果的IDL非文本信息告诉我们。要昄title、body{信息,q需要根据此ID号去查询MySQL数据库,或者从Memcachedb{其他的存储中取得。安装SphinxSE作ؓMySQL的存储引擎,MySQL与Sphinxl合hQ是一U便LҎ(gu)?br />   创徏一张Sphinxcd表,MyISAM表的主键ID和Sphinx表的ID作一个JOIN联合查询。这P对于MyISAM表来所Q只相当于一个WHERE id=...的主键查询,WHERE后的条g都交lSphinxd理,可以充分发挥两者的优势Q实现高速搜索查询?br />
  (3)、按服务cdq行分离Q?/strong>
  Z保证数据的一致性,我在配置Sphinxd索引源的MySQL数据库时Q进行了锁表。Sphinxd索引源的q程会耗费一定时_׃MyISAM存储引擎的读锁和写锁是互斥的Qؓ了避免写操作被长旉dQ导致数据库同步落后跟不上,我将提供“搜烦查询服务”的和提供“索引源服?#8221;的MySQL数据库进行了分开。监?306端口的MySQL提供“搜烦查询服务”Q监?406端口的MySQL提供“索引源服?#8221;?br />
  (4)?#8220;ȝ引+增量索引”更新方式Q?/strong>
  一般网站的特征Q信息发布较为频J;刚发布完的信息被~辑、修改的可能性大Q两天以前的老帖变动性较?yu)?br />   Zq个特征Q我设计了Sphinxȝ引和增量索引。对于前?7:00之前的记录徏立主索引Q每天凌晨自动重Zơ主索引Q对于前?7:00之后到当前最新的记录Q间?分钟自动重徏一ơ增量烦引?br />
  (5)?#8220;Ext3文gpȝQtmpfs内存文gpȝ”相结合:
  Z避免?分钟重徏增量索引D盘I(y)O较重Q从而引Ll负载上升,我将ȝ引文件创建在盘Q增量烦引文件创建在tmpfs内存文gpȝ“/dev/shm/”内?#8220;/dev/shm/”内的文g全部ȝ在内存中Q读写速度非常快。但是,重启服务器会D“/dev/shm/”内的文g丢失Q针对这个问题,我会在服务器开机时自动创徏“/dev/shm/”内目录结构和Sphinx增量索引?br />
  (6)、中文分词词库:
  我根?#8220;自整理的中文分词?#8221;Q?#8220;搜狗拼音输入法细?yu)词?#8221;Q?#8220;LibMMSeg高频字库”Q?.. l合整理成一份中文分词词库,Z某些考虑暂不提供。你可以使用LibMMSeg自带的中文分词词库?

jinfeng_wang 2010-04-15 16:35 发表评论
]]>
用rsync实现|站镜像和备?zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/14/318279.htmljinfeng_wangjinfeng_wangWed, 14 Apr 2010 09:14:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/14/318279.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318279.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/14/318279.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318279.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318279.html


2、rsync的配|?/p>

对于rsync服务器来_最重要和复杂的是它的配置了。rsync服务器的配置文g?etc/rsyncd.confQ其控制认证、访问、日志记录等{?/p>

该文件是׃个或多个模块l构l成。一个模块定义以Ҏ(gu)弧中的模块名开始,直到下一个模块定义开始或者文件结束,模块中包含格式ؓname = value的参数定义。每个模块其实就对应需要备份的一个目录树Q比方说在我们的实例环境中,有三个目录树需要备份:/www/?home/web_user1/?home/web_user2/Q那么就需要在配置文g中定义三个模块,分别对应三个目录树?/p>

配置文g是行为单位的Q也是每个新行都表CZ个新的注释、模块定义或者参数赋倹{以#开始的行表C注释,?"l束的行表示下面一行是该行的l。参数赋g{号后可能是一个大写不敏感的字符丌Ӏ一个以trure/false表示的布?yu)倹{?/p>

全局参数

在文件中[modlue]之前的所有参数都是全局参数Q当然也可以在全局参数部分定义模块参数Q这时候该参数的值就是所有模块的默认倹{?/p>

motd file

"motd file"参数用来指定一个消息文Ӟ当客戯接服务器时该文g的内Ҏ(gu)C给客户Q默认是没有motd文g的?/p>

log file

"log file"指定rsync的日志文Ӟ而不日志发送给syslog?/p>

pid file

指定rsync的pid文g?/p>

syslog facility

指定rsync发送日志消息给syslog时的消息U别Q常见的消息U别是:uth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, sys-log, user, uucp, local0, local1, local2, local3,local4, local5, local6和local7。默认值是daemon?/p>

模块参数

在全局参数之后需要定义一个或多个模块了,模块中可以定义以下参敎ͼ

comment

l模块指定一个描qͼ该描q连同模块名在客戯接得到模块列表时昄l客戗默认没有描q定义?/p>

path

指定该模块的供备份的目录树\径,该参数是必须指定的?/p>

use chroot

如果"use chroot"指定为trueQ那么rsync在传输文件以前首先chroot到path参数所指定的目录下。这样做的原因是实现额外的安全防护,但是~点是需要以roots权限Qƈ且不能备份指向外部的W号q接所指向的目录文件。默认情况下chrootgؓtrue?/p>

max connections

指定该模块的最大ƈ发连接数量以保护服务器,过限制的连接请求将被告知随后再试。默认值是0Q也是没有限制?/p>

lock file

指定支持max connections参数的锁文gQ默认值是/var/run/rsyncd.lock?/p>

read only

该选项讑֮是否允许客户上蝲文g。如果ؓtrue那么M上蝲h都会p|Q如果ؓfalseq且服务器目录读写权限允讔R么上载是允许的。默认gؓtrue?/p>

list

该选项讑֮当客戯求可以用的模块列表Ӟ该模块是否应该被列出。如果设|该选项为falseQ可以创建隐藏的模块。默认值是true?/p>

uid

该选项指定当该模块传输文g时守护进E应该具有的uidQ配合gid选项使用可以定哪些可以讉K怎么L文g权限Q默认值是"nobody"?/p>

gid

该选项指定当该模块传输文g时守护进E应该具有的gid。默认gؓ"nobody"?/p>

exlude

用来指定多个q格隔开的多个模式列表,q将其添加到exclude列表中。这{同于在客户端命令中使用--exclude来指定模式,不过配置文g中指定的exlude模式不会传递给客户端,而仅仅应用于服务器。一个模块只能指定一个exlude选项Q但是可以在模式前面使用"-"?+"来指定是excludeq是include?/p>

但是需要注意的一Ҏ(gu)该选项有一定的安全性问题,客户很有可能l过exlude列表Q如果希望确保特定的文g不能被访问,那就最好结合uid/gid选项一起用?/p>

exlude from

指定一个包含exclude模式的定义的文g名,服务器从该文件中dexlude列表定义?/p>

include

用来指定多个q格隔开的多个rsyncq应该exlude的模式列表。这{同于在客户端命令中使用--include来指定模式,l合include和exlude可以定义复杂的exlude/include规则 。一个模块只能指定一个include选项Q但是可以在模式前面使用"-"?+"来指定是excludeq是include?/p>

include from

指定一个包含include模式的定义的文g名,服务器从该文件中dinclude列表定义?/p>

auth users

该选项指定q格或逗号分隔的用户名列表Q只有这些用h允许q接该模块。这里的用户和系l用h有Q何关pR如?auth users"被设|,那么客户端发出对该模块的q接h以后会被rsynchchallengedq行验证w䆾q里使用的challenge/response认证协议。用L名和密码以明文方式存攑֜"secrets file"选项指定的文件中。默认情况下无需密码可以连接模?也就是匿名方??/p>

secrets file

该选项指定一个包含定义用户名:密码对的文g。只有在"auth users"被定义时Q该文g才有作用。文件每行包含一个username:passwd寏V一般来说密码最好不要超q?个字W。没有默认的secures file名,需要限式指定一个?例如Q?etc/rsyncd.secrets)

strict modes

该选项指定是否监测密码文g的权限,如果该选项gؓtrue那么密码文g只能被rsync服务器运行n份的用户讉KQ其他Q何用户不可以讉K该文件。默认gؓtrue?/p>

hosts allow

该选项指定哪些IP的客户允许连接该模块。客h式定义可以是以下形式Q?/p>

o xxx.xxx.xxx.xxxQ客户主机只有完全匹配该IP才允许访问。例如:192.167.0.1

o a.b.c.d/nQ属于该|络的客户都允许q接该模块。例如:192.168.0.0/24

o a.b.c.d/e.f.g.hQ属于该|络的客户都允许q接该模块。例如:192.168.0.0/255.255.255.0

o 一个主机名Q客户主机只有拥有该L名才允许讉KQ例如:backup.linuxaid.com.cn?/p>


o *.linuxaid.com.cnQ所有属于该域的L都允许?/p>

默认是允许所有主接?/p>

hosts deny

指定不允许连接rsync服务器的机器Q可以用hosts allow的定义方式来q行定义。默认是没有hosts deny定义?/p>

ignore errors

指定rsyncd在判断是否运行传输时的删除操作时忽略server上的IP错误Q一般来说rsync在出现IO错误时将蟩q?-delete操作Q以防止因ؓ暂时的资源不x其它IO错误D的严重问题?/p>

ignore nonreadable

指定rysnc服务器完全忽略那些用h有访问权限的文g。这对于在需要备份的目录中有些文件是不应该被备䆾者得到的情况是有意义的?/p>

transfer logging

使rsync服务器用ftp格式的文件来记录下蝲和上载操作在自己单独的日志中?/p>

log format

通过该选项用户在用transfer logging可以自己定制日志文g的字Dc其格式是一个包含格式定义符的字W串Q可以用的格式定义W如下所C:

o %h q程L?/p>

o %a q程IP地址

o %l 文g长度字符?/p>

o %p 该次rsync会话的进Eid

o %o 操作cdQ?send"?recv"

o %f 文g?/p>

o %P 模块路径

o %m 模块?/p>

o %t 当前旉

o %u 认证的用户名(匿名时是null)

o %b 实际传输的字节数

o %c 当发送文件时Q该字段记录该文件的校验?/p>

默认log格式为:"%o %h [%a] %m (%u) %f %l"Q一般来?在每行的头上会添?%t [%p] "。在源代码中同时发布有一个叫rsyncstats的perl脚本E序来统计这U格式的日志文g?/p>

timeout

通过该选项可以覆盖客户指定的IP时旉。通过该选项可以保rsync服务器不会永q等待一个崩溃的客户。超时单位ؓU钟Q?表示没有时定义Q这也是默认倹{对于匿名rsync服务器来_一个理想的数字?00?/p>

refuse options

通过该选项可以定义一些不允许客户对该模块使用的命令参数列表。这里必M用命令全名,而不能是U。但发生拒绝某个命o的情冉|服务器将报告错误信息然后退出。如果要防止使用压羃Q应该是Q?dont compress = *"?/p>

dont compress

用来指定那些不进行压~处理再传输的文Ӟ默认值是

*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

rsync客户命o

在对rsync服务器配|结束以后,下一步就需要在客户端发出rsync命o来实现将服务器端的文件备份到客户端来。rsync是一个功能非常强大的工具Q其命o也有很多功能特色选项Q我们下面就对它的选项一一q行分析说明?/p>

首先Qrsync的命令格式可以ؓQ?/p>

rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST

rsync [OPTION]... [USER@]HOST:SRC DEST

rsync [OPTION]... SRC [SRC]... DEST

rsync [OPTION]... [USER@]HOST::SRC [DEST]

rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST

rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST] 
rsync有六U不同的工作模式Q?/p>

拯本地文gQ当SRC和DES路径信息都不包含有单个冒?:"分隔W时启动这U工作模式?/p>

使用一个远EshellE序Q如rsh、sshQ来实现本地机器的内容拯到远E机器。当DST路径地址包含单个冒号":"分隔W时启动该模式?/p>

使用一个远EshellE序Q如rsh、sshQ来实现远E机器的内容拯到本地机器。当SRC地址路径包含单个冒号":"分隔W时启动该模式?/p>

从远Ersync服务器中拯文g到本地机。当SRC路径信息包含"::"分隔W时启动该模式?/p>

从本地机器拷贝文件到q程rsync服务器中。当DST路径信息包含"::"分隔W时启动该模式?/p>

列远E机的文件列表。这cM于rsync传输Q不q只要在命o中省略掉本地Z息即可?/p>

1、用?/p>

在用rsync传输文gӞ需要指定一个源和一个目的,其中一个可能是q程机器的资源信息。例如:

rsync *.c foo:src/

表示传输当前目录下所有以.cl尾的文件到机器foo的src目录下。如果Q何文件已l存在于q程pȝQ则会调用远E更新协议来实现仅仅传输那些更新q的文g?/p>

rsync -avz foo:src/bar /data/tmp

该命令则递归C输机器foo上的src/bar目录下的所有内容到本地/data/tmp/bar目录中。文件以归模式q行传输Q以保W号铄、属性、权限、属ȝ信息在传输中都被保存。此外,可以使用压羃技术来加快数据传输Q?/p>

rsync -avz foo:src/bar/ /data/tmp

路径信息?/"l尾时表C拷贝该目录Q而不?/"l尾表示拯该目录。当配合使用--delete选项时这两种情况的区别将会表现出来?/p>

也可以以本地模式来用rsyncQ如果SRC和DST路径中都没有M":"W号则表C命oq行在本地模式,{同于cp命o?/p>

rsync somehost.mydomain.com::

q种模式则将会列出somehost.mydomain.com.可以讉K的所有模块信息?/p>

选项说明

-v, --verbose 详细模式输出 
-q, --quiet _输出模式 
-c, --checksum 打开校验开养I强制Ҏ(gu)件传输进行校?span class="Apple-converted-space"> 
-a, --archive 归模式Q表CZ递归方式传输文gQƈ保持所有文件属性,{于-rlptgoD 
-r, --recursive 对子目录以递归模式处理 
-R, --relative 使用相对路径信息

rsync foo/bar/foo.c remote:/tmp/

则在/tmp目录下创建foo.c文gQ而如果?R参数Q?/p>

rsync -R foo/bar/foo.c remote:/tmp/

则会创徏文g/tmp/foo/bar/foo.cQ也是会保持完全\径信息?/p>

-b, --backup 创徏备䆾Q也是对于目的已经存在有同L文g名时Q将老的文g重新命名为~filename。可以?-suffix选项来指定不同的备䆾文g前缀?span class="Apple-converted-space"> 
--backup-dir 备份文?如~filename)存放在在目录下?span class="Apple-converted-space"> 
-suffix=SUFFIX 定义备䆾文g前缀 
-u, --update 仅仅q行更新Q也是跌所有已l存在于DSTQƈ且文件时间晚于要备䆾的文件?不覆盖更新的文g) 
-l, --links 保留软链l?span class="Apple-converted-space"> 
-L, --copy-links 惛_待常规文件一样处理Y铄 
--copy-unsafe-links 仅仅拯指向SRC路径目录树以外的铄 
--safe-links 忽略指向SRC路径目录树以外的铄 
-H, --hard-links 保留链l?span class="Apple-converted-space"> 
-p, --perms 保持文g权限 
-o, --owner 保持文g属主信息 
-g, --group 保持文g属组信息 
-D, --devices 保持讑֤文g信息 
-t, --times 保持文g旉信息 
-S, --sparse 对稀疏文件进行特D处理以节省DST的空?span class="Apple-converted-space"> 
-n, --dry-run现实哪些文g被传输 
-W, --whole-file 拯文gQ不q行增量?span class="Apple-converted-space"> 
-x, --one-file-system 不要跨越文gpȝ边界 
-B, --block-size=SIZE 验算法用的块尺寸,默认?00字节 
-e, --rsh=COMMAND 指定替代rsh的shellE序 
--rsync-path=PATH 指定q程服务器上的rsync命o所在\径信?span class="Apple-converted-space"> 
-C, --cvs-exclude 使用和CVS一LҎ(gu)自动忽略文gQ用来排除那些不希望传输的文?span class="Apple-converted-space"> 
--existing 仅仅更新那些已经存在于DST的文Ӟ而不备䆾那些新创建的文g 
--delete 删除那些DST中SRC没有的文?span class="Apple-converted-space"> 
--delete-excluded 同样删除接收端那些被该选项指定排除的文?span class="Apple-converted-space"> 
--delete-after 传输l束以后再删?span class="Apple-converted-space"> 
--ignore-errors 及时出现IO错误也进行删?span class="Apple-converted-space"> 
--max-delete=NUM 最多删除NUM个文?span class="Apple-converted-space"> 
--partial 保留那些因故没有完全传输的文Ӟ以是加快随后的再ơ传?span class="Apple-converted-space"> 
--force 强制删除目录Q即使不为空 
--numeric-ids 不将数字的用户和lID匚w为用户名和组?span class="Apple-converted-space"> 
--timeout=TIME IP时旉Q单位ؓU?span class="Apple-converted-space"> 
-I, --ignore-times 不蟩q那些有同样的时间和长度的文?span class="Apple-converted-space"> 
--size-only 当决定是否要备䆾文gӞ仅仅察看文g大小而不考虑文g旉 
--modify-window=NUM 军_文g是否旉相同时用的旉戳窗口,默认? 
-T --temp-dir=DIR 在DIR中创Z时文?span class="Apple-converted-space"> 
--compare-dest=DIR 同样比较DIR中的文g来决定是否需要备?span class="Apple-converted-space"> 
-P {同?--partial 
--progress 昄备䆾q程 
-z, --compress 对备份的文g在传输时q行压羃处理 
--exclude=PATTERN 指定排除不需要传输的文g模式 
--include=PATTERN 指定不排除而需要传输的文g模式 
--exclude-from=FILE 排除FILE中指定模式的文g 
--include-from=FILE 不排除FILE指定模式匚w的文?span class="Apple-converted-space"> 
--version 打印版本信息 
--address l定到特定的地址 
--config=FILE 指定其他的配|文Ӟ不用默认的rsyncd.conf文g 
--port=PORT 指定其他的rsync服务端口 
--blocking-io 对远Eshell使用dIO 
-stats l出某些文g的传输状?span class="Apple-converted-space"> 
--progress 在传输时现实传输q程 
--log-format=FORMAT 指定日志文g格式 
--password-file=FILE 从FILE中得到密?span class="Apple-converted-space"> 
--bwlimit=KBPS 限制I/O带宽QKBytes per second 
-h, --help 昄帮助信息

实例分析

q里假设有两台服务器QA和B。其中A是主web服务器,h域名www.linuxaid.com.cn(202.99.11.120)QB服务器是备䆾机,其域名ؓbackup.linuxaid.com.cn(202.99.11.121)。其中A的web内容存放在以下几个地方:/www/?home/web_user1/?home/web_user2/。我们需要在备䆾机B上徏立对q几个目录内容的备䆾?/p>

服务器配|实?/p>

那么?a style="font-size: 9pt; color: black; text-decoration: none" >www.linuxaid.com.cn上创建rsyncd的配|文?etc/rsyncd.confQ内容如下:

uid = nobody 
gid = nobody 
use chroot = no 
max connections = 4 
pid file = /var/run/rsyncd.pid 
lock file = /var/run/rsync.lock 
log file = /var/log/rsyncd.log

[www] 
path = /www/ 
ignore errors 
read only = true 
list = false 
hosts allow = 202.99.11.121 
hosts deny = 0.0.0.0/32 
auth users = backup 
secrets file = /etc/backserver.pas

[web_user1] 
path = /home/web_user1/ 
ignore errors 
read only = true 
list = false 
hosts allow = 202.99.11.121 
hosts deny = 0.0.0.0/32 
uid = web_user1 
gid = web_user1 
auth users = backup 
secrets file = /etc/backserver.pas

[web_user2] 
path = /home/web_user2/ 
ignore errors 
read only = true 
list = false 
hosts allow = 202.99.11.121 
hosts deny = 0.0.0.0/32 
uid = web_user2 
gid = web_user2 
auth users = backup 
secrets file = /etc/backserver.pas

q里定义有四个三个模块,分别对应于三个需要备份的目录树。这里只允许202.99.11.121备䆾本机的数据,q且需要认证。三个模块授权的备䆾用户都ؓbackupQƈ且用户信息保存在文g/etc/backserver.pas中,其内容如下:

backup:bk_passwd

q且该文件只能是root用户可读写的Q否则rsyncd启动时会出错。这些文仉|完毕以后,需要在A服务器上启动rsyncd服务器:

rsync --daemon

客户命oCZ

/usr/local/bin/rsync -vzrtopg --delete --exclude "logs/" --exclude "conf/ssl.*/" --progressbackup@202.99.11.120::www /backup/www/ --password-file=/etc/rsync.pass

上面q个命o行中-vzrtopg里的v是verboseQz是压~,r是recursiveQtopg都是保持文g原有属性如属主、时间的参数?-progress是指昄l的q度情况Q?-delete是指如果服务器端删除了这一文gQ那么客L也相应把文g删除Q保持真正的一致?-exclude "logs/" 表示不对/www/logs目录下的文gq行备䆾?-exclude "conf/ssl.*/"表示不对/www/conf/ssl.*/目录下的文gq行备䆾?/p>

backup@202.99.11.120::www 表示对该命o是对服务?02.99.11.120中的www模块q行备䆾Qbackup表示使用backup来对该模块进行备份?/p>

--password-file=/etc/rsync.pass来指定密码文Ӟq样可以在脚本中用而无需交互式地输入验证密码了,q里需要注意的是这份密码文件权限属性要讑־只有root可读?/p>

q里备份的内容存放在备份机?backup/www/目录下?/p>

[root@linuxaid /]# /usr/local/bin/rsync -vzrtopg --delete --exclude "logs/" --exclude "conf/ssl.*/" --progress backup@202.99.11.120::www /backup/www/ --password-file=/etc/rsync.pass 
receiving file list ... done 
./ 
1 
785 (100%) 
1.py 
4086 (100%) 
2.py 
10680 (100%) 
a 
0 (100%) 
ip 
3956 (100%) 
./ 
wrote 2900 bytes read 145499 bytes 576.34 bytes/sec 
total size is 2374927 speedup is 45.34

对其它两个模块操作的命o分别为:

/usr/local/bin/rsync -vzrtopg --delete --progress backup@202.99.11.120::web_user1 /backup/web_user1/ --password-file=/etc/rsync.pass

/usr/local/bin/rsync -vzrtopg --delete --progress backup@202.99.11.120::web_user2 /backup/web_user2/ --password-file=/etc/rsync.pass

可以客户命令通过crontab -e命o来实现自动备份,如crontab -eQ?/p>

一些示例脚?/p>

q里q些脚本都是rsync|站上的例子Q?/p>

1、每隔七天将数据往中心服务器做增量备䆾

#!/bin/sh

# This script does personal backups to a rsync backup server. You will end up 
# with a 7 day rotating incremental backup. The incrementals will go 
# into subdirectories named after the day of the week, and the current 
# full backup goes into a directory called "current" 
# tridge@linuxcare.com

# directory to backup 
BDIR=/home/$USER

# excludes file - this contains a wildcard pattern per line of files to exclude 
EXCLUDES=$HOME/cron/excludes

# the name of the backup machine 
BSERVER=owl

# your password on the backup server 
export RSYNC_PASSWORD=XXXXXX


########################################################################

BACKUPDIR=`date +%A` 
OPTS="--force --ignore-errors --delete-excluded --exclude-from=$EXCLUDES 
--delete --backup --backup-dir=/$BACKUPDIR -a"

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin

# the following line clears the last weeks incremental directory 
[ -d $HOME/emptydir ]' 'mkdir $HOME/emptydir 
rsync --delete -a $HOME/emptydir/ $BSERVER::$USER/$BACKUPDIR/ 
rmdir $HOME/emptydir

# now the actual transfer 
rsync $OPTS $BDIR $BSERVER::$USER/current

2、备份至一个空闲的盘

#!/bin/sh

export PATH=/usr/local/bin:/usr/bin:/bin

LIST="rootfs usr data data2"

for d in $LIST; do 
mount /backup/$d 
rsync -ax --exclude fstab --delete /$d/ /backup/$d/ 
umount /backup/$d 
done

DAY=`date "+%A"`

rsync -a --delete /usr/local/apache /data2/backups/$DAY 
rsync -a --delete /data/solid /data2/backups/$DAY

3、对vger.rutgers.edu的cvs树进行镜?/p>

#!/bin/bash

cd /var/www/cvs/vger/ 
PATH=/usr/local/bin:/usr/freeware/bin:/usr/bin:/bin

RUN=`lps x | grep rsync | grep -v grep | wc -l` 
if [ "$RUN" -gt 0 ]; then 
echo already running 
exit 1 
fi

rsync -az vger.rutgers.edu::cvs/CVSROOT/ChangeLog $HOME/ChangeLog

sum1=`sum $HOME/ChangeLog` 
sum2=`sum /var/www/cvs/vger/CVSROOT/ChangeLog`

if [ "$sum1" = "$sum2" ]; then 
echo nothing to do 
exit 0 
fi

rsync -az --delete --force vger.rutgers.edu::cvs/ /var/www/cvs/vger/ 
exit 0

FAQ

QQ如何通过sshq行rsyncQ而且无须输入密码Q?span class="Apple-converted-space"> 
AQ可以通过以下几个步骤

1. 通过ssh-keygen在server A上徏立SSH keysQ不要指定密码,你会在~/.ssh下看到identity和identity.pub文g 
2. 在server B上的home目录建立子目?ssh 
3. A的identity.pub拯到server B?span class="Apple-converted-space"> 
4. identity.pub加到~[user b]/.ssh/authorized_keys 
5. 于是server A上的A用户Q可通过下面命o以用户B ssh到server B上了 
e.g. ssh -l userB serverB 
q样׃server A上的用户A可以ssh以用户B的n份无需密码登陆到server B上了?/p>

QQ如何通过在不危害安全的情况下通过防火墙用rsync? 
AQ解{如下:

q通常有两U情况,一U是服务器在防火墙内Q一U是服务器在防火墙外。无论哪U情况,通常q是使用sshQ这时最好新Z个备份用Pq且配置sshd仅允许这个用户通过RSA认证方式q入?如果服务器在防火墙内Q则最好限定客L的IP地址Q拒l其它所有连接。如果客h在防火墙内,则可以简单允讔R火墙打开TCP端口22的ssh外发q接ok了?/p>

QQ我能将更改q或者删除的文g也备份上来吗Q?span class="Apple-converted-space"> 
AQ当然可以:

你可以用如Qrsync -other -options -backupdir = ./backup-2000-2-13 ...q样的命令来实现?span class="Apple-converted-space"> 
q样如果源文?/path/to/some/file.c改变了,那么旧的文g׃被移?/backup-2000-2-13/path/to/some/file.cQ?span class="Apple-converted-space"> 
q里q个目录需要自己手工徏立v?/p>

QQ我需要在防火墙上开攑֓些端口以适应rsyncQ?span class="Apple-converted-space"> 
AQ视情况而定

rsync可以直接通过873端口的tcpq接传文Ӟ也可以通过22端口的ssh来进行文件传递,但你也可以通过下列命o改变它的端口Q?/p>

rsync --port 8730 otherhost:: 
或?span class="Apple-converted-space"> 
rsync -e 'ssh -p 2002' otherhost:

QQ我如何通过rsync只复制目录结构,忽略掉文件呢Q?span class="Apple-converted-space"> 
AQrsync -av --include '*/' --exclude '*' source-dir dest-dir

QQؓ什么我M出现"Read-only file system"的错误呢Q?span class="Apple-converted-space"> 
AQ看看是否忘了设"read only = no"?/p>

QQؓ什么我会出?a style="font-size: 9pt; color: black; text-decoration: none" href="mailto:'@ERROR">'@ERROR: invalid gid'的错误呢Q?span class="Apple-converted-space"> 
AQrsync使用旉认是用uid=nobody;gid=nobody来运行的Q如果你的系l不存在nobodyl的话,׃出现q样的错误,可以试试gid = nogroup或者其?/p>

QQ绑定端?73p|是怎么回事Q?span class="Apple-converted-space"> 
AQ如果你不是以root权限q行q一守护q程的话Q因?024端口以下是特权端口,会出现这L错误。你可以?-port参数来改变?/p>

QQؓ什么我认证p|Q?span class="Apple-converted-space"> 
AQ从你的命o行看来:

你用的是Q?span class="Apple-converted-space"> 
> bash$ rsync -a 144.16.251.213::test test 
> Password: 
> @ERROR: auth failed on module test 
> 
> I dont understand this. Can somebody explain as to how to acomplish this. 
> All suggestions are welcome.

应该是没有以你的用户名登陆导致的问题Q试试rsync -a max@144.16.251.213::test test 



jinfeng_wang 2010-04-14 17:14 发表评论
]]>
վ֩ģ壺 Ʒ޸һ| ɫվWWWĻ | ۺƵ| þþƷƵ| AVҹƬ| ҹþþƷ | Ƶ| ĻĻ| ˳վ߹ۿ| պëƬƵѿ| ޹ҹĻƷվ | sss߹ۿѸ| ɫһɫһ| 99Ƶ| Ʒ鶹123| 123Ʒ| õӰ߹ۿ| ŮƵ| ޱרwww| һƷ| ѲձƬ| ëƬպëƬ| ѹ߹ۿ| Ѽվһҳ | ŷƵ| 97ȾþƵƷ99| һ߲| ޹˳Ļһ| ҹƷþþþ| ŷ޾Ʒ| Ʒһ | þþþ޹AV鶹| Ƭһ| 84paoǿѸ| ˳ɵӰվɫwww| LƷþ| ƷһƵ| Ʒ޸һ| ޺ݺۺϾþ| һëƬ߲| ޵һվƵ|