最近一直在學習大型網站的架構和性能優化,瘋狂地從網上尋找各種可能的架構資料,終于在InfoQ上找到2009 QCon舉辦的QCon全球企業開發大會北京站演講資料。
挑了我最喜歡的幾個大型網站(豆瓣、淘寶、優酷),先看了豆瓣的主講人洪強寧分享的《豆瓣網技術架構變遷》。看完后有幾個感覺:
※ 羅馬不是一天建成的
豆瓣在5年內經歷了6次架構的調整,和淘寶有得一拼啊。任何優秀的架構都是在不斷的問題和瓶頸中發展起來的
※ 總是考慮使用Memcached
應該在系統架構的第一時間就考慮使用Memcached,按照洪大師的說法。豆瓣現在的內存緩存有38G。Memcached的好處地球人都知道了
※提防Memcached的并發訪問
Memcached雖然是劑猛藥,但也有可
能成為毒藥。特別是在高并發的情況下同時獲取一批緩存數據的時候(不知道新版本的Memcached解決這個問題沒有,當時我第一次看到這個功能時那是激
動得內牛滿面啊~~~)。要知道Memcached畢竟只是個緩存工具,不是內存數據庫。不要指望他提供什么鎖、并發控制的機制(不過它倒是提供了一個原
子操作increment,用于遞增數據,對于刷新頁面訪問量之類的比較有用)
※ 根據數據訪問特性合理規劃表類型
使用MySQL的數據庫,可以方便地使用不
同的存儲引擎對應不同操作類型的表(貌似對于其它數據庫,還沒有這種功能。也可能是我孤陋寡聞了)。對于讀寫不平衡但并發低的情況,采用MyISAM可以
獲得較高的效率。網上google了一把,ISAM的意思是Indexed Sequential Access Method
(有索引的順序訪問方法),它的優勢是速度快,支持全文搜索;但對事務支持差(PS:個人意見這個用來做數據分析或者數據挖掘最好了
^_^)。如果是用于高并發的讀寫訪問,那么只能采用InnoDB類型的表了。
※ 動靜分離
使用lighttpd具有比Apache更好的靜態文件處理功能(PS:個人見到從豆瓣的第一個版本開始到目前為止的版本,只有兩點是不變的:1.使用lighttpd對精通文件進行分離,直接從FS讀取。動態的走SCGI接口。2.使用Memcached)。
※ 對緩存、數據庫進行負載均衡,例如MySQL Proxy
使用類似于Load
Balance來平衡Memcached的負載。不同于Round-robin方式,采用的是hash分配。自己實現Hash算法(PS:這個倒是和網上
的多數觀點一樣,但緩存的東西多了,命中率總是會下降,要么擴大內存要么改算法,避免多次的重新分配)
※ 不要忽視小文件的讀寫
在豆瓣的某個發展階段,就出現了因為大量的小圖片讀寫而造成大量的磁盤IO和碎片的問題。原來豆瓣一開始也是把所有圖片都放在一個目錄下啊(
),后來出現問題后才改成1000個圖片一個目錄。要不按照洪大師的說法:一個ls就可以讓服務器掛掉。
※ 屏蔽表名和物理表的關系
通過中間映射實現底層物理數據表的無縫遷移。(PS:這個只要是做過Java的都知道了,IoC,代理其實也就是這個作用),具體的做法就是只傳一個邏輯表名進去,后臺函數映射后解析成一個真正的物理表所在的位置,方便日后的數據遷移,只要維護這個映射表就好了
※ 數據復制(主從模式)是必經階段
當主數據庫出現瓶頸時,要考慮采用數據庫
復制的方式(Master /
Slave模式),主庫負責事務性讀寫,從庫負責非事務性讀(不能有寫)。數據庫復制的形式在豆瓣的發展上發生了很多次變化,我看到的就有從單點的復制到
最終的跨機房復制。這一點可以從后面的PPT看到
※ 數據庫復制是存在時間延遲的
數據庫復制的延遲時間要考慮在內,否則會出現當主庫寫完后,未來得及復制到從庫就出現Application從從庫讀數據的情況,嚴重的話用戶每次更新數據后再刷新看到的永遠都是舊的數據(緩存還沒有更新,同步的數據還在路上呢....)。
※ 人肉刷新緩存有時候是必要的
接上面的問題,洪大師的團隊最終采用了“人肉刷新”---- 即在可預見的情況下,內存中的數據更新后,主動調用Memcached的flush()方法刷新一下緩存,先同步了緩存再說,后面的數據你就慢慢復制吧。這個只能靠程序員自己控制了....ORZ
※ 統一的Data mining入口
豆瓣的數據庫復制機制中有一個特別的“Data mining”模塊,由它負責把數據寫到主DB,再從主DB
replicate到從DB,然后Data mining模塊從從DB read。這個有點搞不懂?這個“Data
mining”到底是什么來頭?怎么所有數據都從這里寫,甚至連主DB的數據都是從這里寫進去的?
※ 分離服務器
把服務器分成控制服務器、應用服務器、代理服務器。分別對應入口轉發,應用請求,負載均衡。把數據挖掘、日志分析、爬蟲應用之類占用帶寬,耗內存的東西全都移到后端,放在月黑風高,夜深人靜的時候去進行吧。
※ 硬件的故障不可忽視
SCSI比SATA的穩定性要高,花在內存上的錢是值得的
※ 永遠不要高估機房托管方、空間提供商的智商和責任心
比如洪大師說的:搬機器的時候不小心把你們服務器的電源線拔了之類的問題...
※ 如果你夠牛B,那么考慮實現自己的內存數據庫和文件系統
例如DoubanFS、DoubanDB(貌似這是一個基于key-value的內存數據庫,看來內存數據庫在未來大有可為啊,該死的hibernate,該死的iBatis,該死的OR-Mapping)。
以上是豆瓣洪大師的觀點,加上最近看到的其它,也一并總結一下吧:
※ 盡可能在長事務的情況下使用異步通信,例如發送SMS、MMS到網關然后等待回應
※ 對數據庫采用水平分區而非垂直分區以加強后期的擴展性
※ 合理恰當地使用索引
※ 在高層次的地方使用緩存,而不要在低層次的地方使用緩存
※ 建立科學合理的性能、壓力測試環境。性能瓶頸總是出現在你意想不到的地方
posted on 2010-03-19 22:21
Paul Lin 閱讀(1527)
評論(0) 編輯 收藏 所屬分類:
架構與性能