大型Web2.0站點構建技術初探
一、 web2.0網站常用可用性功能模塊分析
二、 Flickr的幕后故事
三、 YouTube 的架構擴展
四、 mixi.jp:使用開源軟件搭建的可擴展SNS網站
五、 Technorati的后臺數據庫架構
六、 通過了解MySpace的六次重構經歷,來認識分布式系統(tǒng)到底該如何創(chuàng)建
七、 從LiveJournal后臺發(fā)展看大規(guī)模網站性能優(yōu)化方法
八、 說說大型高并發(fā)高負載網站的系統(tǒng)架構
一、 web2.0 網站常用可用性功能模塊分析
Web 2.0網站是指將傳統(tǒng)的網站構架(平臺、內容源、用戶、傳播方式等)轉化到以用戶為核心的網站構架上來,包括一系列體現web2.0概念的元素、定位和創(chuàng)意。web2.0網站在構架上須體現兩大宗旨,即強大的后臺系統(tǒng)和簡單的前臺頁面,也即提供良好的用戶體驗,體現以人為本,技術服務人類的宗旨。
web2.0網站常用功能塊通常包括以下幾大項:
1. Tag 標簽功能塊
Tag(中文叫做"標簽") 是一種新的組織和管理在線信息的方式。它不同于傳統(tǒng)的、針對文件本身的關鍵字檢索,而是一種模糊化、智能化的分類。
網頁使用Tag標簽的好處:
為頁面設置一個或者多個Tag標簽可以引導讀者閱讀更多相關文章,為別人帶去流量同理也為自己帶來流量。
可以幫助讀者及時了解一些未知的概念和知識點,提高用戶體驗。
Tag是人的意志和趨向的體現,Tag可以幫助你找到興趣相投的人。
基于以上優(yōu)勢,Tag標簽代替了傳統(tǒng)的分類法,成為web2.0網站使用率最高的功能塊(與其說是功能塊倒不如說是一種內容導航和內容組織形式)。
一句話:Tag標簽是一種更靈活的分類方法,功能在于引導,特點是無處不在,體現智能性、模糊性和趨向性。
2. RSS 訂閱功能塊
RSS是在線共享內容的一種簡易方式(也叫聚合內容,Really Simple Syndication)。通常在時效性比較強的內容上使用RSS訂閱能更快速獲取信息,網站提供RSS輸出,有利于讓用戶獲取網站內容的最新更新。網絡用戶可以在客戶端借助于支持RSS的聚合工具軟件(例如SharpReader,NewzCrawler、FeedDemon),在不打開網站內容頁面的情況下閱讀支持RSS輸出的網站內容。
RSS訂閱的方式:
訂閱到客戶端軟件如周伯通、遨游瀏覽器RSS閱讀、Foxmail RSS閱讀等,此方式使用者較多
訂閱到在線閱讀(聚合類)門戶網站如Google Reader,Yahoo Reader,抓蝦、Gougou等,省去了安裝RSS閱讀器的麻煩
訂閱到在線單用戶聚合器如Lilina等,比較靈活
RSS訂閱功能的最大好處是定向投遞,也就是說RSS機制更能體現用戶的意愿和個性,獲取信息的方式也最直接和簡單,這是RSS訂閱功能備受青睞的一大主要原因。
3. 推薦和收藏功能塊
說到推薦功能,不僅web2.0網站在大量使用,傳統(tǒng)的以cms平臺為代表的內容模式的網站也在大量使用,推薦功能主要是指向一些網摘或者聚合類門戶網站推薦自己所瀏覽到的網頁。當然,一種變相的推薦就是閱讀者的自我收藏行為,在共享的模式下也能起到推薦的作用。
比較有名的推薦目標有以del.icio.us為代表的網摘類網站包括國內比較有名氣的365key、和訊網摘、新浪vivi、天極網摘等。這里值得一提的是前段時間曾涌現了大批網摘類網站,但他們堅持活下來的好像沒有幾個了,推薦使用前面提到的這幾個網摘門戶,人氣基本上是使最旺的。
4. 評論和留言功能塊
web2.0強調參與性,強調發(fā)揮用戶的主導作用,這里的參與性除了所謂的訂閱、推薦功能外更多地體現在用戶對內容的評價和態(tài)度,這就要靠評論功能塊來完成。一個典型的web2.0網站或者說一個能體現人氣的web2.0網站都會花大量篇幅來體現用戶的觀點和視覺。這里尤其要提到web2.0中的帶頭老大web blog,評論功能已經成為博客主人與瀏覽者交流的主要陣地,是體現網站人氣的最直觀因素。
評論功能塊應用在博客系統(tǒng)中實際上已經和博客內容相分離,而更好的應用恰恰是一些以點評為主的web2.0網站比如豆瓣、點評網等,這里的評論功能塊直接制造了內容也極大地體現了網站的人氣,所以說評論功能塊是web2.0網站最有力的武器。
5. 站內搜索功能塊
搜索是信息來源最直接的方式之一,無論你的網站是否打上web2.0的烙印,搜索對于一個體系龐大、內容豐富的大型網站都是非常必要的。Tag標簽在某種程度上起到搜索的作用,它能夠有效聚合以此Tag為關鍵詞的內容,但這種情況的前提是此Tag標簽對瀏覽者是可見的,也就是說當Tag標簽擺在瀏覽者的眼前時才成立,而對于那些瀏覽者想要的信息卻沒有Tag標簽來引導時搜索就是達到此目的的最好方法。
對于web2.0網站,站內搜索以標題或者Tag為搜索域都能起到好的效果,但本人不建議使用內容搜索域,因為這不符合搜索的高效性原則。同時,具有突出關鍵詞的內容往往都可以用Tag標簽來引導,因此使用內容域來搜索實際上是一種浪費服務器資源的行為,而且搜索結果的準確性將大打折扣。
6. 群組功能塊
我為什么要把群組作為web2.0網站的功能塊來分析呢,因為群組是web2.0網站的一大特點,也是web2.0所要體現的服務宗旨所在。一個web2.0網站,博客也好、播客也好、點評也好,抑或是網摘、聚合門戶,他們都強調人的參與性。物以類聚、人以群分,每個參與者都有自己的興趣趨向,web2.0網站的另一主要功能就是幫助這些人找到同樣興趣的人并形成一個活躍的群體,這是web2.0網站的根本。
總結:web2.0網站倡導的是集體創(chuàng)作、共享資源,靠的是人氣,體現的是參與性,一個沒有參與性的web2.0網站都不足以成為web2.0。以上提到的這幾個功能塊就是以吸引用戶參與和引導用戶參與為目的的,真正的web2.0不是什么深奧的東西,只有一點,那就是如何讓瀏覽者沸騰起來。
二、 Flickr 的幕后故事
我們都看到 Flickr 的成功,而又有多少"精英"們了解過 Flickr 背后的過程是多么充滿艱險。
Flickr 是全 CGI 的動態(tài)構架,并以一種 .gne 的腳本作為 CGI 程序語言。不管網站制作菜鳥還是高手都會疑惑:gne 是哪種程序語言?答案:gne 不是一種語言,Flickr 是以極為經典的 PHP + MySQL 方式實現的,在被 Yahoo 收購服務器搬入美國之前,使用了 21 臺(69.90.111.101-121) Apache/PHP 做 Web、23 臺圖片服務器、另有 MySQL 服務器組成的數據庫集群的服務器數量未知。現在估計使用的是 Yahoo 的負載均衡系統(tǒng),對外只有一個 Web 的 IP 和圖片服務器的 IP 了。
那為何 .php 的文件要改成 .gne 呢?以往有大型網站為向后兼容性考慮,隱藏以程序語言命名的腳本文件擴展名,比如 Baidu 隱藏了 .php(Google 的 http 服務器是自己寫的,整合了腳本程序,個別頁面是 .py--Python);還有一些網站是改成自己網站名相關的擴展名,如 MSN 的群組則是 .msnw,榕樹下是 .rs。
那 Flickr 的 gne 是什么意思?我在維基百科的 Flickr 條目上找到了答案(中文 Flickr 條目上沒有寫明) 。原來 GNE 是 Game NeverEnding 的縮寫,Flickr 的開發(fā)者 Ludicorp 在 2002-2004 年一直在開發(fā)這套以 Game NerverEnding 為名稱的大型多人在線角色扮演游戲--一套基于瀏覽器的 Web 游戲系統(tǒng),個人以為應該就是當年九城的虛擬城市。但是開發(fā)近 3 年后該計劃不得不破產,最終只發(fā)布了一個 Beta 版,而 Ludicorp 將這套系統(tǒng)稍加移植,就有了 Flickr。呵呵,原來 gne 是一個項目的名稱。關于 GNE 的一些連接:http://del.icio.us/schee/gne。
早期的 Flickr 想做成在類似聊天室的地方讓網友分享、交流自己的照片,注重社區(qū)形式和保護照片不被外部引用(見徐子涵2004年的文章),可能是看到了 Hello 的模式吧。但是聰明的 Flickr 團隊不久就改變了策略,淡化了傳統(tǒng)的社區(qū)形式--如聊天室、而加強了現在使其功成名就的 Tag 組織形式,一種更自由更隨興更輕松好玩的大社區(qū)形式,或者叫它廣義社區(qū)吧,我隨便叫的,可能太學究,看著別太在意就是了。另外,將原來照片只能在 Flash 內瀏覽的限制區(qū)除了,并大力推薦用戶將照片引用到自己的 Blog,這無疑對于挑戰(zhàn)傳統(tǒng)相冊系統(tǒng)有決定性意義。減少 Flash 后的網頁更多地引進了新興的 Ajax 技術,使界面操作變得非常 Cool。
這就是 Flickr 的歷史,清晰地看到了他們對于優(yōu)秀產品的執(zhí)著。有了技術和經驗積累,加上不斷堅持,總有一天時來運轉,你的產品會成為新潮流的里程碑。
還有一句話要告訴 Yupoo 等:把 Flickr 想成一個有 Tag 功能的在線相冊就已經錯遠了;復制粘貼者們想當然將 Flickr 去其糟粕取其精華,結果無關緊要的拿來了,將令人激動的優(yōu)點都去掉了,結果剩下什么?
三、 YouTube 的架構擴展
在西雅圖擴展性的技術研討會上,YouTube 的 Cuong Do 做了關于 YouTube Scalability 的報告。視頻內容在 Google Video 上有(地址),可惜國內用戶看不到。
Kyle Cordes 對這個視頻中的內容做了介紹。里面有不少技術性的內容。值得分享一下。(Kyle Cordes 的介紹是本文的主要來源)
簡單的說 YouTube 的數據流量, "一天的YouTube流量相當于發(fā)送750億封電子郵件.", 2006 年中就有消息說每日 PV 超過 1 億,現在? 更夸張了,"每天有10億次下載以及6,5000次上傳", 真假姑且不論, 的確是超乎尋常的海量. 國內的互聯網應用,但從數據量來看,怕是只有 51.com 有這個規(guī)模. 但技術上和 YouTube 就沒法子比了.
1. Web 服務器
YouTube 出于開發(fā)速度的考慮,大部分代碼都是 Python 開發(fā)的。Web 服務器有部分是 Apache, 用 FastCGI 模式。對于視頻內容則用 Lighttpd 。據我所知,MySpace 也有部分服務器用 Lighttpd ,但量不大。YouTube 是 Lighttpd 最成功的案例。(國內用 Lighttpd 站點不多,豆瓣用的比較舒服。by Fenng)
2. 視頻
視頻的縮略圖(Thumbnails)給服務器帶來了很大的挑戰(zhàn)。每個視頻平均有4個縮略圖,而每個 Web 頁面上更是有多個,每秒鐘因為這個帶來的磁盤 IO 請求太大。YouTube 技術人員啟用了單獨的服務器群組來承擔這個壓力,并且針對 Cache 和 OS 做了部分優(yōu)化。另一方面,縮略圖請求的壓力導致 Lighttpd 性能下降。通過 Hack Lighttpd 增加更多的 worker 線程很大程度解決了問題。而最新的解決方案是起用了 Google 的 BigTable, 這下子從性能、容錯、緩存上都有更好表現。看人家這收購的,好鋼用在了刀刃上。
出于冗余的考慮,每個視頻文件放在一組迷你 Cluster 上,所謂 "迷你 Cluster" 就是一組具有相同內容的服務器。最火的視頻放在 CDN 上,這樣自己的服務器只需要承擔一些"漏網"的隨即訪問即可。YouTube 使用簡單、廉價、通用的硬件,這一點和 Google 風格倒是一致。至于維護手段,也都是常見的工具,如 rsync, SSH 等,只不過人家更手熟罷了。
3. 數據庫
YouTube 用 MySQL 存儲元數據--用戶信息、視頻信息什么的。數據庫服務器曾經一度遇到 SWAP 顛簸的問題,解決辦法是刪掉了 SWAP 分區(qū)! 管用。
最初的 DB 只有 10 塊硬盤,RAID 10 ,后來追加了一組 RAID 1。夠省的。這一波 Web 2.0 公司很少有用 Oracle 的(我知道的只有 Bebo,參見這里). 在擴展性方面,路線也是和其他站點類似,復制,分散 IO。最終的解決之道是"分區(qū)",這個不是數據庫層面的表分區(qū),而是業(yè)務層面的分區(qū)(在用戶名字或者 ID 上做文章,應用程序控制查找機制)
YouTube 也用 Memcached.
很想了解一下國內 Web 2.0 網站的數據信息,有誰可以提供一點 ?
四、 mixi.jp :使用開源軟件搭建的可擴展SNS網站
Mixi目前是日本排名第三的網站,全球排名42,主要提供SNS服務:日記,群組,站內消息,評論,相冊等等,是日本最大的SNS網站。Mixi從2003年12月份開始開發(fā),由現在它的CTO - Batara Kesuma一個人焊,焊了四個月,在2004年2月份開始上線運行。兩個月后就注冊了1w用戶,日訪問量60wPV。在隨后的一年里,用戶增長到了21w,第二年,增長到了200w。到今年四月份已經增長到370w注冊用戶,并且還在以每天1.5w人的注冊量增長。這些用戶中70%是活躍用戶(活躍用戶:三天內至少登錄一次的用戶),平均每個用戶每周在線時間為將近3個半小時。
下面我們來看它的技術架構。Mixi采用開源軟件作為架構的基礎:Linux 2.6,Apache 2.0,MySQL,Perl 5.8,memcached,Squid等等。到目前為止已經有100多臺MySQL數據庫服務器,并且在以每月10多臺的速度增長。Mixi的數據庫連接方式采用的是每次查詢都進行連接,而不是持久連接。數據庫大多數是以InnoDB方式運行。Mixi解決擴展問題主要依賴于對數據庫的切分。
首先進行垂直切分,按照表的內容將不同的表劃分到不同的數據庫中。然后是水平切分,根據用戶的ID將不同用戶的內容再劃分的不同的數據庫中,這是比較通常的做法,也很管用。劃分的關鍵還是在于應用中的實現,需要將操作封裝在在數據層,而盡量不影響業(yè)務層。當然完全不改變邏輯層也不可能,這時候最能檢驗以前的設計是否到位,如果以前設計的不錯,那創(chuàng)建連接的時候傳個表名,用戶ID進去差不多就解決問題了,而以前如果sql代碼到處飛,或者數據層封裝的不太好的話那就累了。
這樣做了以后并不能從根本上解決問題,尤其是對于像mixi這種SNS網站,頁面上往往需要引用大量的用戶信息,好友信息,圖片,文章信息,跨表,跨庫操作相當多。這個時候就需要發(fā)揮memcached的作用了,用大內存把這些不變的數據全都緩存起來,而當修改時就通知cache過期,這樣應用層基本上就可以解決大部分問題了,只會有很小一部分請求穿透應用層,用到數據庫。Mixi的經驗是平均每個頁面的加載時間在0.02秒左右(當然根據頁面大小情況不盡相似),可以說明這種做法是行之有效的。Mixi一共在32臺機器上有緩存服務器,每個Cache Server 2G內存,這些Cache Server與App Server裝在一起。因為Cache Server對CPU消耗不大,而有了Cache Server的支援,App Server對內存要求也不是太高,所以可以和平共處,更有效的利用資源。
圖片的處理就顯得相對簡單的多了。對于mixi而言,圖像主要有兩部分:一部分是經常要使用到的,像用戶頭像,群組的頭像等等,大概有100多GB,它們被Squid和CDN所緩存,命中率相對比較高;另一部分是用戶上傳的大量照片,它們的個體訪問量相對而言比較小,命中率也比較低,使用Cache不劃算,所以對于這些照片的策略是直接在用戶上傳的時候分發(fā)到到圖片存儲服務器上,在用戶訪問的時候直接進行訪問,當然圖片的位置需要在數據庫中進行記錄,不然找不到放在哪臺服務器上就郁悶了。
五、 Technorati 的后臺數據庫架構
Technorati (現在被阻尼了, 可能你訪問不了)的 Dorion Carroll 在 2006 MySQL 用戶會議 上介紹了一些關于 Technorati 后臺數據庫架構的情況.
基本情況
目前處理著大約 10Tb 核心數據, 分布在大約 20 臺機器上.通過復制, 多增加了 100Tb 數據, 分布在 200 臺機器上. 每天增長的數據 1TB. 通過 SOA 的運用, 物理與邏輯的訪問相隔離, 似乎消除了數據庫的瓶頸. 值得一提的是, 該擴展過程始終是利用普通的硬件與開源軟件來完成的. 畢竟 , Web 2.0 站點都不是燒錢的主. 從數據量來看,這絕對是一個相對比較大的 Web 2.0 應用.
Tag 是 Technorati 最為重要的數據元素. 爆炸性的 Tag 增長給 Technorati 帶來了不小的挑戰(zhàn).
2005 年 1 月的時候, 只有兩臺數據庫服務器, 一主一從. 到了 06 年一月份, 已經是一主一從, 6 臺 MyISAM 從數據庫用來對付查詢, 3 臺 MyISAM 用作異步計算.
一些核心的處理方法:
1) 根據實體(tags/posttags)) 進行分區(qū)
衡量數據訪問方法,讀和寫的平衡.然后通過不同的維度進行分區(qū).( Technorati 數據更新不會很多, 否則會成為數據庫災難)
2) 合理利用 InnoDB 與 MyISAM
InnoDB 用于數據完整性/寫性能要求比較高的應用. MyISAM 適合進行 OLAP 運算. 物盡其用.
3) MySQL 復制
復制數據到從主數據庫到輔數據庫上,平衡分布查詢與異步計算, 另外一個功能是提供冗余. 如圖:
六、 通過了解MySpace 的六次重構經歷,來認識分布式系統(tǒng)到底該如何創(chuàng)建.
在每個里程碑,站點負擔都會超過底層系統(tǒng)部分組件的最大載荷,特別是數據庫和存儲系統(tǒng)。接著,功能出現問題,用戶失聲尖叫。最后,技術團隊必須為此修訂系統(tǒng)策略。
雖然自2005年早期,站點賬戶數超過7百萬后,系統(tǒng)架構到目前為止保持了相對穩(wěn)定,但MySpace仍然在為SQL Server支持的同時連接數等方面繼續(xù)攻堅,Benedetto說,"我們已經盡可能把事情做到最好"。
1. 里程碑一:50 萬賬戶
按Benedetto 的說法,MySpace最初的系統(tǒng)很小,只有兩臺Web服務器和一個數據庫服務器。那時使用的是Dell雙CPU、4G內存的系統(tǒng)。
單個數據庫就意味著所有數據都存儲在一個地方,再由兩臺Web服務器分擔處理用戶請求的工作量。但就像MySpace后來的幾次底層系統(tǒng)修訂時的情況一樣,三服務器架構很快不堪重負。此后一個時期內,MySpace基本是通過添置更多Web服務器來對付用戶暴增問題的。
但到在2004年早期,MySpace用戶數增長到50萬后,數據庫服務器也已開始汗流浹背。
但和Web服務器不同,增加數據庫可沒那么簡單。如果一個站點由多個數據庫支持,設計者必須考慮的是,如何在保證數據一致性的前提下,讓多個數據庫分擔壓力。
在第二代架構中,MySpace運行在3個SQL Server數據庫服務器上--一個為主,所有的新數據都向它提交,然后由它復制到其他兩個;另兩個全力向用戶供給數據,用以在博客和個人資料欄顯示。這種方式在一段時間內效果很好--只要增加數據庫服務器,加大硬盤,就可以應對用戶數和訪問量的增加。
2. 里程碑二:1-2 百萬賬戶
MySpace注冊數到達1百萬至2百萬區(qū)間后,數據庫服務器開始受制于I/O容量--即它們存取數據的速度。而當時才是2004年中,距離上次數據庫系統(tǒng)調整不過數月。用戶的提交請求被阻塞,就像千人樂迷要擠進只能容納幾百人的夜總會,站點開始遭遇"主要矛盾",Benedetto說,這意味著MySpace永遠都會輕度落后于用戶需求。
"有人花5分鐘都無法完成留言,因此用戶總是抱怨說網站已經完蛋了。"他補充道。
這一次的數據庫架構按照垂直分割模式設計,不同的數據庫服務于站點的不同功能,如登錄、用戶資料和博客。于是,站點的擴展性問題看似又可以告一段落了,可以歇一陣子。
垂直分割策略利于多個數據庫分擔訪問壓力,當用戶要求增加新功能時,MySpace將投入新的數據庫予以支持它。賬戶到達2百萬后,MySpace還從存儲設備與數據庫服務器直接交互的方式切換到SAN(Storage Area Network,存儲區(qū)域網絡)--用高帶寬、專門設計的網絡將大量磁盤存儲設備連接在一起,而數據庫連接到SAN。這項措施極大提升了系統(tǒng)性能、正常運行時間和可靠性,Benedetto說。
3. 里程碑三:3 百萬賬戶
當用戶繼續(xù)增加到3百萬后,垂直分割策略也開始難以為繼。盡管站點的各個應用被設計得高度獨立,但有些信息必須共享。在這個架構里,每個數據庫必須有各自的用戶表副本--MySpace授權用戶的電子花名冊。這就意味著一個用戶注冊時,該條賬戶記錄必須在9個不同數據庫上分別創(chuàng)建。但在個別情況下,如果其中某臺數據庫服務器臨時不可到達,對應事務就會失敗,從而造成賬戶非完全創(chuàng)建,最終導致此用戶的該項服務無效。
另外一個問題是,個別應用如博客增長太快,那么專門為它服務的數據庫就有巨大壓力。
2004年中,MySpace面臨Web開發(fā)者稱之為"向上擴展"對"向外擴展"(譯者注:Scale Up和Scale Out,也稱硬件擴展和軟件擴展)的抉擇--要么擴展到更大更強、也更昂貴的服務器上,要么部署大量相對便宜的服務器來分擔數據庫壓力。一般來說,大型站點傾向于向外擴展,因為這將讓它們得以保留通過增加服務器以提升系統(tǒng)能力的后路。
但成功地向外擴展架構必須解決復雜的分布式計算問題,大型站點如Google、Yahoo和Amazon.com,都必須自行研發(fā)大量相關技術。以Google為例,它構建了自己的分布式文件系統(tǒng)。
另外,向外擴展策略還需要大量重寫原來軟件,以保證系統(tǒng)能在分布式服務器上運行。"搞不好,開發(fā)人員的所有工作都將白費",Benedetto說。
因此,MySpace首先將重點放在了向上擴展上,花費了大約1個半月時間研究升級到32CPU服務器以管理更大數據庫的問題。Benedetto說,"那時候,這個方案看似可能解決一切問題。"如穩(wěn)定性,更棒的是對現有軟件幾乎沒有改動要求。
糟糕的是,高端服務器極其昂貴,是購置同樣處理能力和內存速度的多臺服務器總和的很多倍。而且,站點架構師預測,從長期來看,即便是巨型數據庫,最后也會不堪重負,Benedetto說,"換句話講,只要增長趨勢存在,我們最后無論如何都要走上向外擴展的道路。"
因此,MySpace最終將目光移到分布式計算架構--它在物理上分布的眾多服務器,整體必須邏輯上等同于單臺機器。拿數據庫來說,就不能再像過去那樣將應用拆分,再以不同數據庫分別支持,而必須將整個站點看作一個應用。現在,數據庫模型里只有一個用戶表,支持博客、個人資料和其他核心功能的數據都存儲在相同數據庫。
既然所有的核心數據邏輯上都組織到一個數據庫,那么MySpace必須找到新的辦法以分擔負荷--顯然,運行在普通硬件上的單個數據庫服務器是無能為力的。這次,不再按站點功能和應用分割數據庫,MySpace開始將它的用戶按每百萬一組分割,然后將各組的全部數據分別存入獨立的SQL Server實例。目前,MySpace的每臺數據庫服務器實際運行兩個SQL Server實例,也就是說每臺服務器服務大約2百萬用戶。Benedetto指出,以后還可以按照這種模式以更小粒度劃分架構,從而優(yōu)化負荷分擔。
當然,還是有一個特殊數據庫保存了所有賬戶的名稱和密碼。用戶登錄后,保存了他們其他數據的數據庫再接管服務。特殊數據庫的用戶表雖然龐大,但它只負責用戶登錄,功能單一,所以負荷還是比較容易控制的。
4. 里程碑四:9 百萬到1 千7 百萬賬戶
2005年早期,賬戶達到9百萬后,MySpace開始用Microsoft的C#編寫ASP.NET程序。C#是C語言的最新派生語言,吸收了C++和Java的優(yōu)點,依托于Microsoft .NET框架(Microsoft為軟件組件化和分布式計算而設計的模型架構)。ASP.NET則由編寫Web站點腳本的ASP技術演化而來,是Microsoft目前主推的Web站點編程環(huán)境。
可以說是立竿見影, MySpace馬上就發(fā)現ASP.NET程序運行更有效率,與ColdFusion相比,完成同樣任務需消耗的處理器能力更小。據技術總監(jiān)Whitcomb說,新代碼需要150臺服務器完成的工作,如果用ColdFusion則需要246臺。Benedetto還指出,性能上升的另一個原因可能是在變換軟件平臺,并用新語言重寫代碼的過程中,程序員復審并優(yōu)化了一些功能流程。
最終,MySpace開始大規(guī)模遷移到ASP.NET。即便剩余的少部分ColdFusion代碼,也從Cold-Fusion服務器搬到了ASP.NET,因為他們得到了BlueDragon.NET(喬治亞州阿爾法利塔New Atlanta Communications公司的產品,它能將ColdFusion代碼自動重新編譯到Microsoft平臺)的幫助。
賬戶達到1千萬時,MySpace再次遭遇存儲瓶頸問題。SAN的引入解決了早期一些性能問題,但站點目前的要求已經開始周期性超越SAN的I/O容量--即它從磁盤存儲系統(tǒng)讀寫數據的極限速度。
原因之一是每數據庫1百萬賬戶的分割策略,通常情況下的確可以將壓力均分到各臺服務器,但現實并非一成不變。比如第七臺賬戶數據庫上線后,僅僅7天就被塞滿了,主要原因是佛羅里達一個樂隊的歌迷瘋狂注冊。
某個數據庫可能因為任何原因,在任何時候遭遇主要負荷,這時,SAN中綁定到該數據庫的磁盤存儲設備簇就可能過載。"SAN讓磁盤I/O能力大幅提升了,但將它們綁定到特定數據庫的做法是錯誤的。"Benedetto說。
最初,MySpace通過定期重新分配SAN中數據,以讓其更為均衡的方法基本解決了這個問題,但這是一個人工過程,"大概需要兩個人全職工作。"Benedetto說。
長期解決方案是遷移到虛擬存儲體系上,這樣,整個SAN被當作一個巨型存儲池,不再要求每個磁盤為特定應用服務。MySpace目前采用了一種新型SAN設備--來自加利福尼亞州弗里蒙特的3PARdata。
在3PAR的系統(tǒng)里,仍能在邏輯上按容量劃分數據存儲,但它不再被綁定到特定磁盤或磁盤簇,而是散布于大量磁盤。這就使均分數據訪問負荷成為可能。當數據庫需要寫入一組數據時,任何空閑磁盤都可以馬上完成這項工作,而不再像以前那樣阻塞在可能已經過載的磁盤陣列處。而且,因為多個磁盤都有數據副本,讀取數據時,也不會使SAN的任何組件過載。
當2005年春天賬戶數達到1千7百萬時,MySpace又啟用了新的策略以減輕存儲系統(tǒng)壓力,即增加數據緩存層--位于Web服務器和數據庫服務器之間,其唯一職能是在內存中建立被頻繁請求數據對象的副本,如此一來,不訪問數據庫也可以向Web應用供給數據。換句話說,100個用戶請求同一份資料,以前需要查詢數據庫100次,而現在只需1次,其余都可從緩存數據中獲得。當然如果頁面變化,緩存的數據必須從內存擦除,然后重新從數據庫獲取--但在此之前,數據庫的壓力已經大大減輕,整個站點的性能得到提升。
緩存區(qū)還為那些不需要記入數據庫的數據提供了驛站,比如為跟蹤用戶會話而創(chuàng)建的臨時文件--Benedetto坦言他需要在這方面補課,"我是數據庫存儲狂熱分子,因此我總是想著將萬事萬物都存到數據庫。"但將像會話跟蹤這類的數據也存到數據庫,站點將陷入泥沼。
增加緩存服務器是"一開始就應該做的事情,但我們成長太快,以致于沒有時間坐下來好好研究這件事情。"Benedetto補充道。
5. 里程碑五:2 千6 百萬賬戶
2005年中期,服務賬戶數達到2千6百萬時,MySpace切換到了還處于beta測試的SQL Server 2005。轉換何太急?主流看法是2005版支持64位處理器。但Benedetto說,"這不是主要原因,盡管這也很重要;主要還是因為我們對內存的渴求。"支持64位的數據庫可以管理更多內存。
更多內存就意味著更高的性能和更大的容量。原來運行32位版本的SQL Server服務器,能同時使用的內存最多只有4G。切換到64位,就好像加粗了輸水管的直徑。升級到SQL Server 2005和64位Windows Server 2003后,MySpace每臺服務器配備了32G內存,后于2006年再次將配置標準提升到64G。
意外錯誤
如果沒有對系統(tǒng)架構的歷次修改與升級,MySpace根本不可能走到今天。但是,為什么系統(tǒng)還經常吃撐著了?很多用戶抱怨的"意外錯誤"是怎么引起的呢?
原因之一是MySpace對Microsoft的Web技術的應用已經進入連Microsoft自己也才剛剛開始探索的領域。比如11月,超出SQL Server最大同時連接數,MySpace系統(tǒng)崩潰。Benedetto說,這類可能引發(fā)系統(tǒng)崩潰的情況大概三天才會出現一次,但仍然過于頻繁了,以致惹人惱怒。一旦數據庫,"無論這種情況什么時候發(fā)生,未緩存的數據都不能從SQL Server獲得,那么你就必然看到一個'意外錯誤'提示。"他解釋說。
去年夏天,MySpace的Windows 2003多次自動停止服務。后來發(fā)現是操作系統(tǒng)一個內置功能惹的禍--預防分布式拒絕服務攻擊(黑客使用很多客戶機向服務器發(fā)起大量連接請求,以致服務器癱瘓)。MySpace和其他很多頂級大站點一樣,肯定會經常遭受攻擊,但它應該從網絡級而不是依靠Windows本身的功能來解決問題--否則,大量MySpace合法用戶連接時也會引起服務器反擊。
"我們花了大約一個月時間尋找Windows 2003服務器自動停止的原因。"Benedetto說。最后,通過Microsoft的幫助,他們才知道該怎么通知服務器:"別開槍,是友軍。"
緊接著是在去年7月某個周日晚上,MySpace總部所在地洛杉磯停電,造成整個系統(tǒng)停運12小時。大型Web站點通常要在地理上分布配置多個數據中心以預防單點故障。本來,MySpace還有其他兩個數據中心以應對突發(fā)事件,但Web服務器都依賴于部署在洛杉磯的SAN。沒有洛杉磯的SAN,Web服務器除了懇求你耐心等待,不能提供任何服務。
Benedetto說,主數據中心的可靠性通過下列措施保證:可接入兩張不同電網,另有后備電源和一臺儲備有30天燃料的發(fā)電機。但在這次事故中,不僅兩張電網失效,而且在切換到備份電源的過程中,操作員燒掉了主動力線路。
2007年中,MySpace在另兩個后備站點上也建設了SAN。這對分擔負荷大有幫助--正常情況下,每個SAN都能負擔三分之一的數據訪問量。而在緊急情況下,任何一個站點都可以獨立支撐整個服務,Benedetto說。
MySpace仍然在為提高穩(wěn)定性奮斗,雖然很多用戶表示了足夠信任且能原諒偶現的錯誤頁面。
"作為開發(fā)人員,我憎惡Bug,它太氣人了。"Dan Tanner這個31歲的德克薩斯軟件工程師說,他通過MySpace重新聯系到了高中和大學同學。"不過,MySpace對我們的用處很大,因此我們可以原諒偶發(fā)的故障和錯誤。" Tanner說,如果站點某天出現故障甚至崩潰,恢復以后他還是會繼續(xù)使用。
這就是為什么Drew在論壇里咆哮時,大部分用戶都告訴他應該保持平靜,如果等幾分鐘,問題就會解決的原因。Drew無法平靜,他寫道,"我已經兩次給MySpace發(fā)郵件,而它說一小時前還是正常的,現在出了點問題……完全是一堆廢話。"另一個用戶回復說,"畢竟它是免費的。"Benedetto坦承100%的可靠性不是他的目標。"它不是銀行,而是一個免費的服務。"他說。
換句話說,MySpace的偶發(fā)故障可能造成某人最后更新的個人資料丟失,但并不意味著網站弄丟了用戶的錢財。"關鍵是要認識到,與保證站點性能相比,丟失少許數據的故障是可接受的。"Benedetto說。所以,MySpace甘冒丟失2分鐘到2小時內任意點數據的危險,在SQL Server配置里延長了"checkpoint"操作--它將待更新數據永久記錄到磁盤--的間隔時間,因為這樣做可以加快數據庫的運行。
Benedetto說,同樣,開發(fā)人員還經常在幾個小時內就完成構思、編碼、測試和發(fā)布全過程。這有引入Bug的風險,但這樣做可以更快實現新功能。而且,因為進行大規(guī)模真實測試不具可行性,他們的測試通常是在僅以部分活躍用戶為對象,且用戶對軟件新功能和改進不知就里的情況下進行的。因為事實上不可能做真實的加載測試,他們做的測試通常都是針對站點。
"我們犯過大量錯誤,"Benedetto說,"但到頭來,我認為我們做對的還是比做錯的多。"
七、 從LiveJournal 后臺發(fā)展看大規(guī)模網站性能優(yōu)化方法
LiveJournal 是99年始于校園中的項目,幾個人出于愛好做了這樣一個應用,以實現以下功能:
- 博客,論壇
- 社會性網絡,找到朋友
- 聚合,把朋友的文章聚合在一起
LiveJournal采用了大量的開源軟件,甚至它本身也是一個開源軟件。
在上線后,LiveJournal實現了非常快速的增長:
- 2004年4月份:280萬注冊用戶。
- 2005年4月份:680萬注冊用戶。
- 2005年8月份:790萬注冊用戶。
- 達到了每秒鐘上千次的頁面請求及處理。
- 使用了大量MySQL服務器。
- 使用了大量通用組件。
二、LiveJournal 架構現狀概況
三、從LiveJournal 發(fā)展中學習
LiveJournal從1臺服務器發(fā)展到100臺服務器,這其中經歷了無數的傷痛,但同時也摸索出了解決這些問題的方法,通過對LiveJournal的學習,可以讓我們避免LJ曾經犯過的錯誤,并且從一開始就對系統(tǒng)進行良好的設計,以避免后期的痛苦。
下面我們一步一步看LJ發(fā)展的腳步。
1 、一臺服務器
一臺別人捐助的服務器,LJ最初就跑在上面,就像Google開始時候用的破服務器一樣,值得我們尊敬。這個階段,LJ的人以驚人的速度熟悉的Unix的操作管理,服務器性能出現過問題,不過還好,可以通過一些小修小改應付過去。在這個階段里LJ把CGI升級到了FastCGI。
最終問題出現了,網站越來越慢,已經無法通過優(yōu)過化來解決的地步,需要更多的服務器,這時LJ開始提供付費服務,可能是想通過這些錢來購買新的服務器,以解決當時的困境。
毫無疑問,當時LJ存在巨大的單點問題,所有的東西都在那臺服務器的鐵皮盒子里裝著。
2 、兩臺服務器
用付費服務賺來的錢LJ買了兩臺服務器:一臺叫做Kenny的Dell 6U機器用于提供Web服務,一臺叫做Cartman的Dell 6U服務器用于提供數據庫服務。
LJ有了更大的磁盤,更多的計算資源。但同時網絡結構還是非常簡單,每臺機器兩塊網卡,Cartman通過內網為Kenny提供MySQL數據庫服務。
暫時解決了負載的問題,新的問題又出現了:
- 原來的一個單點變成了兩個單點。
- 沒有冷備份或熱備份。
- 網站速度慢的問題又開始出現了,沒辦法,增長太快了。
- Web服務器上CPU達到上限,需要更多的Web服務器。
3 、四臺服務器
又買了兩臺,Kyle和Stan,這次都是1U的,都用于提供Web服務。目前LJ一共有3臺Web服務器和一臺數據庫服務器。這時需要在3臺Web服務器上進行負載均橫。
LJ把Kenny用于外部的網關,使用mod_backhand進行負載均橫。
然后問題又出現了:
- 單點故障。數據庫和用于做網關的Web服務器都是單點,一旦任何一臺機器出現問題將導致所有服務不可用。雖然用于做網關的Web服務器可以通過保持心跳同步迅速切換,但還是無法解決數據庫的單點,LJ當時也沒做這個。
- 網站又變慢了,這次是因為IO和數據庫的問題,問題是怎么往應用里面添加數據庫呢?
4 、五臺服務器
又買了一臺數據庫服務器。在兩臺數據庫服務器上使用了數據庫同步(Mysql支持的Master-Slave模式),寫操作全部針對主數據庫(通過Binlog,主服務器上的寫操作可以迅速同步到從服務器上),讀操作在兩個數據庫上同時進行(也算是負載均橫的一種吧)。
實現同步時要注意幾個事項:
- 讀操作數據庫選擇算法處理,要選一個當前負載輕一點的數據庫。
- 在從數據庫服務器上只能進行讀操作
- 準備好應對同步過程中的延遲,處理不好可能會導致數據庫同步的中斷。只需要對寫操作進行判斷即可,讀操作不存在同步問題。
5 、更多服務器
有錢了,當然要多買些服務器。部署后快了沒多久,又開始慢了。這次有更多的Web服務器,更多的數據庫服務器,存在 IO與CPU爭用。于是采用了BIG-IP作為負載均衡解決方案。
6 、現在我們在哪里:
現在服務器基本上夠了,但性能還是有問題,原因出在架構上。
數據庫的架構是最大的問題。由于增加的數據庫都是以Slave模式添加到應用內,這樣唯一的好處就是將讀操作分布到了多臺機器,但這樣帶來的后果就是寫操作被大量分發(fā),每臺機器都要執(zhí)行,服務器越多,浪費就越大,隨著寫操作的增加,用于服務讀操作的資源越來越少。
由一臺分布到兩臺
最終效果
現在我們發(fā)現,我們并不需要把這些數據在如此多的服務器上都保留一份。服務器上已經做了RAID,數據庫也進行了備份,這么多的備份完全是對資源的浪費,屬于冗余極端過度。那為什么不把數據分布存儲呢?
問題發(fā)現了,開始考慮如何解決。現在要做的就是把不同用戶的數據分布到不同的服務器上進行存儲,以實現數據的分布式存儲,讓每臺機器只為相對固定的用戶服務,以實現平行的架構和良好的可擴展性。
為了實現用戶分組,我們需要為每一個用戶分配一個組標記,用于標記此用戶的數據存放在哪一組數據庫服務器中。每組數據庫由一個master及幾個slave組成,并且slave的數量在2-3臺,以實現系統(tǒng)資源的最合理分配,既保證數據讀操作分布,又避免數據過度冗余以及同步操作對系統(tǒng)資源的過度消耗。
由一臺(一組)中心服務器提供用戶分組控制。所有用戶的分組信息都存儲在這臺機器上,所有針對用戶的操作需要先查詢這臺機器得到用戶的組號,然后再到相應的數據庫組中獲取數據。
這樣的用戶架構與目前LJ的架構已經很相像了。
在具體的實現時需要注意幾個問題:
- 在數據庫組內不要使用自增ID,以便于以后在數據庫組之間遷移用戶,以實現更合理的I/O,磁盤空間及負載分布。
- 將userid,postid存儲在全局服務器上,可以使用自增,數據庫組中的相應值必須以全局服務器上的值為準。全局服務器上使用事務型數據庫InnoDB。
- 在數據庫組之間遷移用戶時要萬分小心,當遷移時用戶不能有寫操作。
7 、現在我們在哪里
問題:
- 一個全局主服務器,掛掉的話所有用戶注冊及寫操作就掛掉。
- 每個數據庫組一個主服務器,掛掉的話這組用戶的寫操作就掛掉。
- 數據庫組從服務器掛掉的話會導致其它服務器負載過大。
對于Master-Slave模式的單點問題,LJ采取了Master-Master模式來解決。所謂Master-Master實際上是人工實現的,并不是由MySQL直接提供的,實際上也就是兩臺機器同時是Master,也同時是Slave,互相同步。
Master-Master實現時需要注意:
- 一個Master出錯后恢復同步,最好由服務器自動完成。
- 數字分配,由于同時在兩臺機器上寫,有些ID可能會沖突。
解決方案:
- 奇偶數分配ID,一臺機器上寫奇數,一臺機器上寫偶數
- 通過全局服務器進行分配(LJ采用的做法)。
Master-Master模式還有一種用法,這種方法與前一種相比,仍然保持兩臺機器的同步,但只有一臺機器提供服務(讀和寫),在每天晚上的時候進行輪換,或者出現問題的時候進行切換。
8 、現在我們在哪里
現在插播一條廣告,MyISAM VS InnoDB。
使用InnoDB:
- 支持事務
- 需要做更多的配置,不過值得,可以更安全的存儲數據,以及得到更快的速度。
使用MyISAM:
- 記錄日志(LJ用它來記網絡訪問日志)
- 存儲只讀靜態(tài)數據,足夠快。
- 并發(fā)性很差,無法同時讀寫數據(添加數據可以)
- MySQL非正常關閉或死機時會導致索引錯誤,需要使用myisamchk修復,而且當訪問量大時出現非常頻繁。
9 、緩存
去年我寫過 一篇文章介紹memcached ,它就是由LJ的團隊開發(fā)的一款緩存工具,以key-value的方式將數據存儲到分布的內存中。LJ緩存的數據:
- 12臺獨立服務器(不是捐贈的)
- 28個實例
- 30GB總容量
- 90-93%的命中率(用過squid的人可能知道,squid內存加磁盤的命中率大概在70-80%)
如何建立緩存策略?
想緩存所有的東西?那是不可能的,我們只需要緩存已經或者可能導致系統(tǒng)瓶頸的地方,最大程度的提交系統(tǒng)運行效率。通過對MySQL的日志的分析我們可以找到緩存的對象。
緩存的缺點?
- 沒有完美的事物,緩存也有缺點:
- 增大開發(fā)量,需要針對緩存處理編寫特殊的代碼。
- 管理難度增加,需要更多人參與系統(tǒng)維護。
- 當然大內存也需要錢。
10 、Web 訪問負載均衡
在數據包級別使用BIG-IP,但BIG-IP并不知道我們內部的處理機制,無法判斷由哪臺服務器對這些請求進行處理。反向代理并不能很好的起到作用,不是已經夠快了,就是達不到我們想要的效果。
所以,LJ又開發(fā)了 Perlbal 。特點:
- 快,小,可管理的http web 服務器/代理
- 可以在內部進行轉發(fā)
- 使用Perl開發(fā)
- 單線程,異步,基于事件,使用epoll , kqueue
- 支持Console管理與http遠程管理,支持動態(tài)配置加載
- 多種模式:web服務器,反向代理,插件
- 支持插件:GIF/PNG互換?
11 、MogileFS
LJ使用開源的 MogileFS 作為分布式文件存儲系統(tǒng)。MogileFS使用非常簡單,它的主要設計思想是:
- 文件屬于類(類是最小的復制單位)
- 跟蹤文件存儲位置
- 在不同主機上存儲
- 使用MySQL集群統(tǒng)一存儲分布信息
- 大容易廉價磁盤
到目前為止就這么多了,更多文檔可以在 http://www.danga.com/words/ 找到。 Danga.com 和 LiveJournal.com 的同學們拿這個文檔參加了兩次MySQL Con,兩次OS Con,以及眾多的其它會議,無私的把他們的經驗分享出來,值得我們學習。在web2.0時代快速開發(fā)得到大家越來越多的重視,但良好的設計仍是每一個應用的基礎,希望web2.0們在成長為Top500網站的路上,不要因為架構阻礙了網站的發(fā)展。
八、 說說大型高并發(fā)高負載網站的系統(tǒng)架構
我在Cernet做過撥號接入平臺的搭建,而后在Yahoo3721負載搜索引擎前端平臺開發(fā),又在貓撲處理過大型社區(qū)貓撲大雜燴的架構升級等工作,同時自己接觸和開發(fā)過不少大中型網站的模塊,因此在大型網站應對高負載和并發(fā)的解決方案上有一些積累和經驗,可以和大家一起探討一下。
一個小型的網站,比如個人網站,可以使用最簡單的html靜態(tài)頁面就實現了,配合一些圖片達到美化效果,所有的頁面均存放在一個目錄下,這樣的網站對系統(tǒng)架構、性能的要求都很簡單,隨著互聯網業(yè)務的不斷豐富,網站相關的技術經過這些年的發(fā)展,已經細分到很細的方方面面,尤其對于大型網站來說,所采用的技術更是涉及面非常廣,從硬件到軟件、編程語言、數據庫、WebServer、防火墻等各個領域都有了很高的要求,已經不是原來簡單的html靜態(tài)網站所能比擬的。
大型網站,比如門戶網站。在面對大量用戶訪問、高并發(fā)請求方面,基本的解決方案集中在這樣幾個環(huán)節(jié):使用高性能的服務器、高性能的數據庫、高效率的編程語言、還有高性能的Web容器。但是除了這幾個方面,還沒法根本解決大型網站面臨的高負載和高并發(fā)問題。
上面提供的幾個解決思路在一定程度上也意味著更大的投入,并且這樣的解決思路具備瓶頸,沒有很好的擴展性,下面我從低成本、高性能和高擴張性的角度來說說我的一些經驗。
1、HTML靜態(tài)化
其實大家都知道,效率最高、消耗最小的就是純靜態(tài)化的html頁面,所以我們盡可能使我們的網站上的頁面采用靜態(tài)頁面來實現,這個最簡單的方法其實也是最有效的方法。但是對于大量內容并且頻繁更新的網站,我們無法全部手動去挨個實現,于是出現了我們常見的信息發(fā)布系統(tǒng)CMS,像我們常訪問的各個門戶站點的新聞頻道,甚至他們的其他頻道,都是通過信息發(fā)布系統(tǒng)來管理和實現的,信息發(fā)布系統(tǒng)可以實現最簡單的信息錄入自動生成靜態(tài)頁面,還能具備頻道管理、權限管理、自動抓取等功能,對于一個大型網站來說,擁有一套高效、可管理的CMS是必不可少的。
除了門戶和信息發(fā)布類型的網站,對于交互性要求很高的社區(qū)類型網站來說,盡可能的靜態(tài)化也是提高性能的必要手段,將社區(qū)內的帖子、文章進行實時的靜態(tài)化,有更新的時候再重新靜態(tài)化也是大量使用的策略,像Mop的大雜燴就是使用了這樣的策略,網易社區(qū)等也是如此。
同時,html靜態(tài)化也是某些緩存策略使用的手段,對于系統(tǒng)中頻繁使用數據庫查詢但是內容更新很小的應用,可以考慮使用html靜態(tài)化來實現,比如論壇中論壇的公用設置信息,這些信息目前的主流論壇都可以進行后臺管理并且存儲再數據庫中,這些信息其實大量被前臺程序調用,但是更新頻率很小,可以考慮將這部分內容進行后臺更新的時候進行靜態(tài)化,這樣避免了大量的數據庫訪問請求。
2、圖片服務器分離
大家知道,對于Web服務器來說,不管是Apache、IIS還是其他容器,圖片是最消耗資源的,于是我們有必要將圖片與頁面進行分離,這是基本上大型網站都會采用的策略,他們都有獨立的圖片服務器,甚至很多臺圖片服務器。這樣的架構可以降低提供頁面訪問請求的服務器系統(tǒng)壓力,并且可以保證系統(tǒng)不會因為圖片問題而崩潰,在應用服務器和圖片服務器上,可以進行不同的配置優(yōu)化,比如apache在配置ContentType的時候可以盡量少支持,盡可能少的LoadModule,保證更高的系統(tǒng)消耗和執(zhí)行效率。
3、數據庫集群和庫表散列
大型網站都有復雜的應用,這些應用必須使用數據庫,那么在面對大量訪問的時候,數據庫的瓶頸很快就能顯現出來,這時一臺數據庫將很快無法滿足應用,于是我們需要使用數據庫集群或者庫表散列。
在數據庫集群方面,很多數據庫都有自己的解決方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是類似的方案,您使用了什么樣的DB,就參考相應的解決方案來實施即可。
上面提到的數據庫集群由于在架構、成本、擴張性方面都會受到所采用DB類型的限制,于是我們需要從應用程序的角度來考慮改善系統(tǒng)架構,庫表散列是常用并且最有效的解決方案。我們在應用程序中安裝業(yè)務和應用或者功能模塊將數據庫進行分離,不同的模塊對應不同的數據庫或者表,再按照一定的策略對某個頁面或者功能進行更小的數據庫散列,比如用戶表,按照用戶ID進行表散列,這樣就能夠低成本的提升系統(tǒng)的性能并且有很好的擴展性。sohu的論壇就是采用了這樣的架構,將論壇的用戶、設置、帖子等信息進行數據庫分離,然后對帖子、用戶按照板塊和ID進行散列數據庫和表,最終可以在配置文件中進行簡單的配置便能讓系統(tǒng)隨時增加一臺低成本的數據庫進來補充系統(tǒng)性能。
4、緩存
緩存一詞搞技術的都接觸過,很多地方用到緩存。網站架構和網站開發(fā)中的緩存也是非常重要。這里先講述最基本的兩種緩存。高級和分布式的緩存在后面講述。
架構方面的緩存,對Apache比較熟悉的人都能知道Apache提供了自己的緩存模塊,也可以使用外加的Squid模塊進行緩存,這兩種方式均可以有效的提高Apache的訪問響應能力。
網站程序開發(fā)方面的緩存,Linux上提供的Memory Cache是常用的緩存接口,可以在web開發(fā)中使用,比如用Java開發(fā)的時候就可以調用MemoryCache對一些數據進行緩存和通訊共享,一些大型社區(qū)使用了這樣的架構。另外,在使用web語言開發(fā)的時候,各種語言基本都有自己的緩存模塊和方法,PHP有Pear的Cache模塊,Java就更多了,.net不是很熟悉,相信也肯定有。
5、鏡像
鏡像是大型網站常采用的提高性能和數據安全性的方式,鏡像的技術可以解決不同網絡接入商和地域帶來的用戶訪問速度差異,比如ChinaNet和EduNet之間的差異就促使了很多網站在教育網內搭建鏡像站點,數據進行定時更新或者實時更新。在鏡像的細節(jié)技術方面,這里不闡述太深,有很多專業(yè)的現成的解決架構和產品可選。也有廉價的通過軟件實現的思路,比如Linux上的rsync等工具。
6、負載均衡
負載均衡將是大型網站解決高負荷訪問和大量并發(fā)請求采用的終極解決辦法。
負載均衡技術發(fā)展了多年,有很多專業(yè)的服務提供商和產品可以選擇,我個人接觸過一些解決方法,其中有兩個架構可以給大家做參考。
- 硬件四層交換
第四層交換使用第三層和第四層信息包的報頭信息,根據應用區(qū)間識別業(yè)務流,將整個區(qū)間段的業(yè)務流分配到合適的應用服務器進行處理。 第四層交換功能就象是虛IP,指向物理服務器。它傳輸的業(yè)務服從的協議多種多樣,有HTTP、FTP、NFS、Telnet或其他協議。這些業(yè)務在物理服務器基礎上,需要復雜的載量平衡算法。在IP世界,業(yè)務類型由終端TCP或UDP端口地址來決定,在第四層交換中的應用區(qū)間則由源端和終端IP地址、TCP和UDP端口共同決定。
在硬件四層交換產品領域,有一些知名的產品可以選擇,比如Alteon、F5等,這些產品很昂貴,但是物有所值,能夠提供非常優(yōu)秀的性能和很靈活的管理能力。Yahoo中國當初接近2000臺服務器使用了三四臺Alteon就搞定了。
- 軟件四層交換
大家知道了硬件四層交換機的原理后,基于OSI模型來實現的軟件四層交換也就應運而生,這樣的解決方案實現的原理一致,不過性能稍差。但是滿足一定量的壓力還是游刃有余的,有人說軟件實現方式其實更靈活,處理能力完全看你配置的熟悉能力。
軟件四層交換我們可以使用Linux上常用的LVS來解決,LVS就是Linux Virtual Server,他提供了基于心跳線heartbeat的實時災難應對解決方案,提高系統(tǒng)的魯棒性,同時可供了靈活的虛擬VIP配置和管理功能,可以同時滿足多種應用需求,這對于分布式的系統(tǒng)來說必不可少。
一個典型的使用負載均衡的策略就是,在軟件或者硬件四層交換的基礎上搭建squid集群,這種思路在很多大型網站包括搜索引擎上被采用,這樣的架構低成本、高性能還有很強的擴張性,隨時往架構里面增減節(jié)點都非常容易。這樣的架構我準備空了專門詳細整理一下和大家探討。
對于大型網站來說,前面提到的每個方法可能都會被同時使用到,我這里介紹得比較淺顯,具體實現過程中很多細節(jié)還需要大家慢慢熟悉和體會,有時一個很小的squid參數或者apache參數設置,對于系統(tǒng)性能的影響就會很大,希望大家一起討論,達到拋磚引玉之效。
來源: http://blog.csdn.net/guxianga/archive/2007/09/19/1791131.aspx
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
