關于大型web服務器的設計思路
大型網站,比如門戶網站,在海量用戶訪問、高并發請求方面,基本的解決方案是以下幾點:
1、高性能的數據庫(oracle/db2/mysql...)
2、高性能的Web容器(weblogic/apache...)
3、高效率的編程語言(java/C#)
4、使用高性能的服務器(小型機、PC服務器)
5、集群分布式運行(比如上百臺小型機器在線運行)
但是在在線用戶上百萬,日點擊量超億,而數據達幾十T,甚至日數據量就達到T級別這種情況下還是難以解決
大型網站面臨的高負載和高并發問題。
本人也經常關注這方面的解決方案,結合自己的經驗。總結了一部分常用的設計,希望各位多多指點。
一、設計上有足夠彈性
這是在前期架構設計師要足夠考慮到的。最終目的是通過物理設備的線性投入來應付業務量的增長,而不止于受到技術框架應用部署的限制,甚至推到重來,這樣的結構設計就是彈性的設計,當然這里還包括業務上的彈性設計(目前的開發模式、架構設計在很大程度上也是為了解決這個問題)。
一般企業也是極力避免這種情況的發生,否則失去的不僅是成本投入還包括了客戶資源。
二、頁面靜態化
即靜態html格式,這樣避免了對數據資源的訪問,同時也大大降低了應用的CPU消耗。如果能靜態頁面的信息盡量靜態化。
三、無狀態
這里說的無狀態是服務器盡量設計成無狀態的與客戶端通訊,避免了占用大量內存的情況,但這也不是絕對的。部分應用中的狀態保留也能大大減少IO流量與數據庫的訪問壓力。看具體情況而定。
四、數據庫集群、橫向/縱向切分
數據庫集群能緩解數據庫的壓力,但節點過多又會引起寫入同步消耗過大。
數據庫橫向切分也就是把一個業務數據按不同屬性(比如地域歸屬、用戶名hashcode)來平均的分到各個數據庫上。這樣控制分庫的粒度也就是控制了數據庫的分布,能大大緩解單個數據壓力過大訪問受限的情況,不利的情況是經常要跨庫訪問,這樣情況可能會變得比較復雜。
數據庫縱向切分也就是按業務內容來分不同的數據庫,比如客戶資料是一個數據庫保存,而商品訂單資料又分一個數據庫保存,這樣也能把數據庫壓力分解一部分。
通過數據庫的切分也能大大減少單個故障點的影響范圍。
五、異步批量處理
對于非緊急數據,可以采用異步批量處理,安排在非高峰時刻也能提高應用的使用效率。同時批量本身在實現上效率也高于單筆業務處理。
六、表的分區分段分表設計
這是針對一個數據庫的情況下,防止單表數據過大,采用分段分區把一張表分解到不同的物理設備上,提高查詢速度,而可以按業務性質把一張表分成多張表,分區分表可以組合應用,這樣在DB維護上也非常有益。同時分表也能有效降低I/O鎖情況。
七、分歷史數據庫
對于很多網站來說海量的歷史數據是很少用到的,可以按照業務性質,把不修改的數據遷移到專門的歷史數據庫上歸檔,比如三個月以前的交易訂單、用戶的資料修改記錄等。對于需要查詢歷史數據的情況,可以單獨提供這類應用來查詢歷史數據庫。這樣能避免不斷增加的交易數據帶來的性能壓力。
八、分活動和非活躍用戶
這是按照用戶的優先級別分別存儲訪問,對于少量的活躍用戶提供高速的訪問(比如通過緩存),這樣實際上大大提高了大部分用戶請求的處理速度,實際上也大幅度降低應用壓力提高并發能力,而對于非活躍用戶繼續保留了完整的請求服務,客戶基本不會產生使用上的差異。
九、分布式的應用
包括前臺服務器和中間件(其實包括前面描述的多個數據庫),把壓力盡可能的均勻地分布到很多服務器上,而服務器可以是上百臺的線性增加。
十、使用 Epoll/IOCP 來提高并發性能
這些在游戲類網站上非常有用,能大大提高單臺應用服務器的處理能力。結合多線程多進程多服務器處理可以解決高并發請求的情況。
十一、建立專門的文檔服務器
包括的頁面圖片、軟件、文檔等數據,由于IO流量大,比較占用應用服務器,必要的時候單獨建立服務器存放。這種對于有大量圖片的應用比如淘寶商品應該是非常有效的。
十二、分查詢與更新業務數據庫
對于更新類關鍵業務提供強有力的高效保證(這類業務相對查詢量應該比較少),而對于查詢庫則可以提供廉價的數據庫服務。
十三、緩存
其實所有的應用都或多或少的使用到了緩存,緩存包括 CPU /內存 /硬盤/網絡/客戶端的緩存,客戶端可以緩存js/圖片等信息,而不用頻繁的訪問應用,內存緩存是非常有效的方式,可以把靜態的數據放到應用內存上,而不是頻繁訪問數據庫查詢,對于簡單數據庫其實還可以使用專業的緩存應用,比如memcache。
十四、海量數據使用非關系數據庫
對于訪問記錄等數據結構簡單可靠性要求不高的數據持久化,可以不用關系數據庫,因為數據庫提供的食物訪問一致性、隔離性、關系維護消耗了絕大部分資源,而這些功能對不是應用的要點。所以可以考慮使用文件方式或者其他號稱NOSQL的方式來存儲使用。
本人認為應用通過分布式并發負載均衡運行可以解決應用服務器的性能問題(通過良好的設計來保證當業務持續增加的時候通過服務器的線性增加就能解決),關鍵點是數據庫的唯一一致性要求(一份數據只能保存在一個地方,更新查詢都以它為基礎)決定了數據庫的成本是非常高的,甚至于無法用資金來解決(大型機也不見得能保證海量數據的訪問處理),所以只要解決了數據庫的存放問題也就能解決高性能網站的主要問題。
上邊說了這么多基本上還是把數據對象分開存放、盡量減少對于數據庫的訪問的原則提出解決方案的。
對于系統的高可用性這里也總結出幾條:
A、良好成熟的框架設計(并不一定是非常先進),優秀的業務模型,高內聚低耦合的模塊功能。
B、優化部署配置,包括數據庫的優化。
C、預防為主,有專門的監控負責人,能定期分析系統健康負載情況。在問題爆發前能及時預警。
D、有良好的單點控制與應急措施,比如當發帖非常耗性能的時候,單獨關掉“發帖”,
保證大部分的游覽功能。 保證客戶應用的最大化
E、有效專業的開發管理團隊與規范的制度