大型網站資料庫及資料訪問最佳化(轉)

kitesky發表於2010-07-14
千萬人同時訪問的網站,一般是有很多個資料庫同時工作,說明白一點就是資料庫叢集和併發控制,這樣的網站實時性也是相對的。這些網站都有一些共同的特點:資料量大,線上人數多,併發請求多,pageview高,響應速度快。總結了一下各個大網站的架構,主要提高效率及穩定性的幾個地方包括一下幾個方面。[@more@]

1、程式
程式開發是一方面,系統架構設計(硬體+網路+軟體)是另一方面。

軟體架構方面,做網站首先需要很多web伺服器儲存靜態資源,比如圖片、影片、靜態頁等,千萬不要把靜態資源和應用伺服器放在一起。

一個好的程式設計師寫出來的程式會非常簡潔、效能很好,一個初級程式設計師可能會犯很多低階錯誤,這也是影響網站效能的原因之一。
網站要做到效率高,不光是程式設計師的事情,資料庫最佳化、程式最佳化這是必須的,在效能最佳化上要資料庫和程式齊頭並進!快取也是兩方面同時入手。第一,資料庫快取和資料庫最佳化,這個由dba完成(而且這個有非常大的潛力可挖,只是由於我們都是程式設計師而忽略了他而已)。第二,程式上的最佳化,這個非常的有講究,比如說重要一點就是要規範SQL語句,少用in 多用or,多用preparestatement,另外避免程式冗餘如查詢資料少用雙重迴圈等。另外選用優秀的開源框架加以支援,我個人認為中後臺的支援是最最重要的,可以選取spring+ibatis。因為ibatis直接操作SQL並有快取機制。spring的好處就不用我多說了,IOC的機制可以避免new物件,這樣也節省開銷。據我分析,絕大部分的開銷就是在NEW的時候和連線資料庫時候產生的,請儘量避免。另外可以用一些記憶體測試工具來做一個demo說明hibernate和ibatis誰更快!前臺你想用什麼就用什麼,struts,webwork都成,如果覺得自己挺牛X可以試試用tapestry。

用資料庫也未必不能解決訪問量巨大所帶來的問題,作成靜態檔案硬碟的定址時間也未必少於資料庫的搜尋時間,當然對資料的索引要下一翻工夫。我自己覺得門戶往往也就是當天、熱門的資料點選率較高,將其做快取最多也不過1~2G的資料量吧,舉個例子:

◎ 拿網易新聞來說
格式化一下,方便理解:http://域名/年/月日/新聞所屬分類/新聞ID.html
可以把當天釋出的、熱門的、流攬量大的作個緩寸,用hashtable(key:年-月-日-分類-ID,value:新聞物件),靜態將其放到記憶體(速度絕對快過硬碟定址靜態頁面)。

通常是採用oracle儲存過程+2個weblogic,更新機制也幾乎一樣每簽發一條新聞,就會生成靜態頁面,然後發往前端的web伺服器,前端的web都是做負載均衡的。另外還有定時的程式,每5-15分鐘自動生成一次。在釋出新聞的同時將資料快取。當然快取也不會越來越大,在個特定的時間段(如凌晨)剔除過期的資料。做一個大的網站遠沒有想象中那麼簡單,伺服器基本就要百十個的。

這樣可以大大增加一臺計算機的處理速度,如果一臺機器處理不了,可以用httpserver叢集來解決問題了。

2、網路
中國的網路分南北電信和網通,訪問的ip就要區分南北進入不同的網路。

3、叢集

通常會使用CDN與GSBL與DNS負載均衡技術,每個地區一組前臺伺服器群,例如:網易,百度使用了DNS負載均衡技術,每個頻道一組前臺伺服器,一搜使用了DNS負載技術,所有頻道共用一組前臺伺服器叢集。

網站使用基於Linux叢集的負載均衡,失敗恢復,包括應用伺服器和資料庫伺服器,基於linux-ha的服務狀態檢測及高可用化。
應用伺服器叢集可以採用apache+tomcat叢集和weblogic叢集等;web伺服器叢集可以用反向代理,也可以用NAT的方式,或者多域名解析都可以;Squid也可以,方法很多,可以根據情況選擇。

4、資料庫

因為是千萬人同時訪問的網站,所以一般是有很多個資料庫同時工作的,說明白一點就是資料庫叢集和併發控制,資料分佈到地理位置不同的資料中心,以免發生斷電事故。另外還有一點的是,那些網站的靜態化網頁並不是真的,而是透過動態網頁與靜態網頁網址交換做出現的假象,這可以用urlrewrite這樣的開源網址對映器實現。這樣的網站實時性也是相對的,因為在資料庫複製資料的時候有一個過程,一般在技術上可以用到hibernate和ecache,但是如果要使網站工作地更好,可以使用EJB和websphere,weblogic這樣大型的伺服器來支援,並且要用oracle這樣的大型資料庫。
大型入口網站不建議使用Mysql資料庫,除非你對Mysql資料的最佳化非常熟悉。Mysql資料庫伺服器的master-slave模式,利用資料庫伺服器在主從伺服器間進行同步,應用只把資料寫到主伺服器,而讀資料時則根據負載選擇一臺從伺服器或者主伺服器來讀取,將資料按不同策略劃分到不同的伺服器(組)上,分散資料庫壓力。
大型網站要用oracle,資料方面操作儘量多用儲存過程,絕對提升效能;同時要讓DBA對資料庫進行最佳化,最佳化後的資料庫與沒最佳化的有天壤之別;同時還可以擴充套件分散式資料庫,以後這方面的研究會越來越多;

5、頁面

從開始就考慮使用虛擬儲存/簇檔案系統。它能讓你大量並行IO訪問,而且不需要任何重組就能夠增加所需要的磁碟。
頁面資料呼叫更要認真設計,一些資料查詢可以不透過資料庫的方式,實時性要求不高的可以使用lucene來實現,即使有實時性的要求也可以用lucene,lucene+compass還是非常優秀的。

新聞類的網站可以用靜態頁儲存,採用定時更新機制減輕伺服器負擔;首頁每個小模組可以使用oscache快取,這樣不用每次都拉資料。
前端的基於靜態頁面快取的web加速器,主要應用有squid等。squid 將大部分靜態資源(圖片,js,css等)快取起來,直接返回給訪問者,減少應用伺服器的負載
網站的靜態化網頁並不是真的,而是透過動態網頁與靜態網頁網址交換做出現的假象,這可以用urlrewrite這樣的開源網址對映器實現,字尾名為htm或者html並不能說明程式生成了靜態頁面,可能是透過url重寫來實現的,為的只不過是在搜尋引擎中提升自己網站的覆蓋面積罷了。
生成靜態頁面的伺服器和www伺服器是兩組不同的伺服器,頁面生成後才會到www伺服器,一部分資料庫並不是關聯式資料庫,這樣更適合資訊衍生,www、mail伺服器、路由器多,主要用負載平衡解決訪問瓶頸。
◎ 靜態頁面的缺點:
1) 增加了程式的複雜度
2) 不利於管理資料
3) 速度不是最快
4) 傷硬碟

6、快取

從一開始就應該使用快取,快取記憶體是一個更好的地方儲存臨時資料,比如Web站點上跟蹤一個特定使用者的會話產生的臨時檔案,就不再需要記錄到資料庫裡。

不能用lucene實現的可以用快取,分散式快取可以用memcached,如果有錢的話用10來臺機器做快取,> 10G的儲存量相信存什麼都夠了;如果沒錢的話可以在頁面快取和資料快取上下功夫,多用OSCACHE和EHCACHE,SWARMCACHE也可以,不過據說同步性不是很好;

可以使用Memcache進行快取,用大記憶體把這些不變的資料全都快取起來,而當修改時就通知cache過期,memcache是LJ開發的一款分散式快取產品,很多大型網站在應用,我們可以把Cache Server與App Server裝在一起。因為Cache Server對CPU消耗不大,而有了Cache Server的支援,App Server對記憶體要求也不是太高,所以可以和平共處,更有效的利用資源。


以上一些不太成熟的想法,可以從某一個層次開始,逐步細化,把產品的效能指標提高上去。


本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/iflash50/archive/2009/06/20/4282058.aspx

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/66009/viewspace-1035270/,如需轉載,請註明出處,否則將追究法律責任。

相關文章