Web服務的一個重要特色就是流量大、數據多,僅靠一臺服務器確定難以支撐大規模的服務。 因此咱們常常會看到諸如如下的一些術語,教人好生不懂:web
*:系統架構、物理架構、Web服務基礎設施數據庫
*:應用服務器瀏覽器
*:數據庫服務器緩存
*:索引服務器服務器
*:反向代理服務器架構
*:緩存服務器app
*:分佈式、可擴展性less
*:cpu負載、IO負載分佈式
若是你也不懂,那麼本文對你來講就是一個很好的開始,關於web服務架構方面,前面還有幾篇不錯的文章可供參考閱讀---大型網站架構演化歷程(上)、大型網站架構演化歷程(下)、大型網站的靈魂——性能(請戳我)。性能
本文的主要目標—讀懂下面這張圖例:
cpu負載和I/O負載
咱們從CPU和IO提及。 一個典型的Web服務就是網站服務——用戶經過瀏覽器向服務器發起請求,服務器從數據庫提取數據後,加工處理返回HTML頁面給用戶。
上圖中的4個箭頭「<—」都須要消耗Server的CPU計算資源,而從Database中獲取數據則消耗IO資源。 當用戶數量、請求數量上升時,Server的CPU資源告急(IO資源負載也有增長);當儲存的數據量上升時,Server的IO資源也要告急。
好比說單臺Server每分鐘能夠處理3000次請求(PV, Page View),那麼每個月就能夠處理100萬PV,超過這個數量服務器就撐不住了; 每次請求都須要從文件系統提取數據的話,因爲讀取磁盤所需的時間是內存的100000-1000000倍,每分鐘的請求數多了數據提取速度必然跟不上,數據庫就掛了。
可擴展性
如何處理規模逐漸增大服務需求呢?這要求你的系統要有可擴展性:
橫向擴展:橫向擴展又叫分佈式,一臺Server撐不住我就多來幾臺。 但現實遠比理想複雜。
縱向擴展:縱向擴展是金融高富帥或者企業軟件比較常採用的方法,由於服務器的價格和性能不成正比,性能達到必定程度後,每一分性能的提升須要投入更多的錢——服務器性能的邊際價格是不斷上升的。 對於互聯網的草根創業團隊來講,這顯然是不可接受的。
cpu能力的擴展
CPU負載的分散比較容易,由於CPU的計算不存在依賴性,即當前請求的結果不依賴於上一次請求的結果。 HTTP協議的stateless就是一個很好的例子。 這樣CPU撐不住的時候,我直接clone幾臺徹底一塊兒的就行了,而被克隆的這種服務通常就稱做應用服務器。
應用服務器和Web服務器的界限並不很清晰。 Web服務器負責接收用戶發過來的請求和返回資源對象給用戶,而應用服務器則負責經過計算產生這個資源對象(好比調用CGI腳本)。
這樣CPU的負載問題就解決了,咱們的架構變成了這個樣子。
I/O能力的擴展
內存讀取的速度遠高於磁盤,根據操做系統緩存(Cache)的原理,咱們提升數據讀取速度的基本思路是——提升內存大小能夠顯著的下降IO負載,即爲你的Server換上更大更多的內存條。 相應的基本方針——當操做系統的緩存沒法處理時,再進一步考慮分佈式。 IO負載分散的本質也就是廉價小容量內存的分散。
IO負載的分散可比CPU的難多了,因爲存在數據同步的問題,咱們這裏不討論數據庫服務器之間全盤的數據複製和冗餘化。 既然數據量太大,大到一臺服務器的內存裝不下,那咱們就把數據分割開來——數據分割(數據壓縮也能夠達到必定的效果)。
Web服務的請求是存在訪問模式,好比爬蟲和普通用戶的訪問(爬蟲會請求很早之前的頁面,而普通用戶大多訪問當前的熱門頁面),咱們把應對用戶的熱門的資源對象放在一臺服務器,應對爬蟲的資源對象放在另外一臺。
即便不存在訪問模式,咱們也能夠經過分區(Partitioning),即表分割來作到。 好比如今MySQL數據庫裏有一個用戶ID表,用戶量增加後表的record數是13億,咱們根據ID的大小來排序,分割成幾個ID表,每一個表幾千萬個ID,這樣單個表大小就是GB級別——內存夠裝了。
不論是哪種狀況,咱們都須要一臺索引服務器,來作應用服務器和數據服務器的mapping。
那麼如今咱們的架構就是:
本文的說明就到這裏爲止了,相信你如今再回頭看開頭的那張系統架構圖將會很是容易了吧。
轉自:燈塔大數據