1. 程式人生 > >關於大型網站技術演進的思考(二):儲存的瓶頸(2)

關於大型網站技術演進的思考(二):儲存的瓶頸(2)

上篇裡我講到某些網站在高併發下會報出503錯誤,503錯誤的含義是指網站服務端暫時無法提供服務的含義,503還表達了網站服務端現在有問題但是以後可能會提供正常的服務,對http協議熟悉的人都知道,5開頭的響應碼錶達了服務端出現了問題,在我們開發測試時候最為常見的是500錯誤,500代表的含義是服務端程式出現了錯誤導致網站無法正常提供服務,500通常是服務端異常和錯誤所致,如果生產系統裡發現了500錯誤,那麼只能說明網站存在邏輯性的錯誤,這往往是系統上線前的測試做的不到位所致。

回到503錯誤,我上文解釋為拒絕訪問,其實更加準確的回答應該是服務不可用,那麼為什麼我會說503錯誤在高併發的情況下90%的原因是資料庫所致呢?上文我做出了詳細的解釋,但是今天我回味了一下,發現那個解釋還不是太突出重點,問題的重點是在高併發的情況整個網站系統首先暴露出問題的是資料庫,如果我們把整個網站系統比作一個盛水的木桶,那麼木桶最短的那個板就是資料庫了,一般而言網站的服務應用出問題都會是解決儲存問題之後才會出現。

資料庫出現了瓶頸並不是程式存在邏輯性錯誤,資料庫瓶頸的表現就是資料庫因為承受了太多的訪問後,資料庫無法迅速的做出響應,嚴重時候資料庫會拒絕進一步操作死鎖在哪裡不能做出任何反應。資料庫猶如一把巨型的大鎖,很多人爭搶這個鎖時候會導致這個大鎖完全被鎖死,最終請求的處理就停留在這個大鎖上最終導致網站提示出503錯誤,503錯誤最終會傳遞到所有的客戶端上,最終的現象就是全站不可用了。

上文裡我講到session共享的一個方案是將session資料儲存在外部一個獨立的快取伺服器裡,我開始說用一臺伺服器做快取伺服器,後面提到如果覺得一臺伺服器做快取不安全,那麼採用分散式快取伺服器例如memcached,那麼這裡就有一個問題了,為了保證web服務的可用性,我們會把web服務分開部署到不同的伺服器上,這些伺服器都是對等關係,其中一臺伺服器不能正常提供服務不會影響到整個網站的穩定性,那麼我們採取memcached叢集是不是可以達到同樣的效果了?即快取伺服器叢集中一臺伺服器掛掉,不會影響到使用者對網站的使用了?問題的答案是令人失望了,假如我們使用兩臺伺服器做快取伺服器來儲存session資訊,那麼如果其中一臺伺服器掛掉了,那麼網站將會有一半的使用者將不能正常使用網站,原因是他們的session資訊丟失了,網站無法正常的跟蹤使用者的會話狀態。

我之所以提到這個問題是想告訴大家以memcached為代表的分散式快取和我們傳統理解的分散式系統是有區別的,傳統的分散式系統都會包含一個容災維護系統穩定性的功能,但實際的分散式技術是多種多樣的,例如memcached的分散式技術並不是為了解決容災維護系統穩定性的模式設計,換個說法就是memcached叢集的設計是沒有過分考慮冗餘的問題,而只有適當的冗餘才能保證系統的健壯性問題。分散式技術的實現是千差萬別的,每個優秀的分散式系統都有自身獨有的特點。

前面的講述memcached技術並非本文的主題,而且這個主題也不是一兩句話能說清楚的,這裡我簡單的介紹下memcached實現的原理,當網站使用快取叢集時候,快取資料是通過一定的演算法將快取資料儘量均勻分不到不同伺服器上,如果使用者A的快取在伺服器A上,那麼伺服器B上是沒有該使用者的快取資料,早期的memcache資料分散式的演算法是根據快取資料的key即鍵值計算出一個hash值,這個hash值再除以快取伺服器的個數,得到的餘數會對應某一臺伺服器,例如1對應伺服器A,2對應伺服器B,那麼餘數是1的key值快取就會儲存在伺服器A上,這樣的演算法會導致某一臺伺服器掛掉,那麼網站損失的快取資料的佔比就會比較高,為了解決這個問題,memcached引入了一致性hash演算法。關於一致性hash網上有很多資料,這裡我就貼出一個連結,本文就不做過多論述了。連結地址如下:

一致性hash可以伺服器宕機時候這臺伺服器對整個快取資料的影響最小。

上文裡我講到了讀寫分離的設計方案,而讀寫分離方案主要是應用於網站讀寫比例嚴重失衡的網站,而網際網路上絕大部分網站都是讀操作的比例遠遠大於寫操作,這是網站的主流,如果一個網站讀寫比例比較均衡,那麼這個網站一般都是提供專業服務的網站,這種網站對於個人而言是一個提供生活便利的工具,它們和企業軟體類似。大部分關注大型網站架構技術關心的重點應該是那種對於讀寫比例失衡的網站,因為它們做起來更加有挑戰性。

將資料庫進行讀寫分離是網站解決儲存瓶頸的第一步,為什麼說是第一步呢?因為讀寫分離從業務角度而言它是一種粗粒度的資料拆分,因此它所包含的業務複雜度比較低,容易操作和被掌控,從技術而言,實現手段也相對簡單,因此讀寫分離是一種低成本解決儲存瓶頸的一種手段,這種方案是一種改良方案而不是革命性的的方案,不管是從難度,還是影響範圍或者是經濟成本角度考慮都是很容易讓相關方接受的。

那麼我們僅僅將資料庫做讀寫分離為何能產生好的效率了?回答這個問題我們首先要了解下硬碟的機制,硬碟的物理機制就有一個大圓盤飛速旋轉,然後有個磁頭不斷掃描這個大圓盤,這樣的物理機制就會導致硬碟資料的順序操作比隨機操作效率更高,這點對於硬碟的讀和寫還算公平,但是寫操作在高併發情況下會有點複雜,寫操作有個特性就是我們要保證寫操作的準確性,但是高併發下可能會出現多個使用者同時修改某一條資料,為了保證資料能被準確的修改,那麼我們通常要把並行的操作轉變為序列操作,這個時候就會出現一個鎖機制,鎖機制的實現是很複雜的,它會消耗很多系統性能,如果寫操作摻雜了讀操作情況就更復雜,效率會更加低效,相對於寫操作讀操作就單純多了,如果我們的資料只有讀操作,那麼讀的效能也就是硬碟順序讀能力和隨機讀能力的體現,即使摻雜了併發也不會對其有很大的影響,因此如果把讀操作和寫操作分離,效率自然會得到很大提升。

既然讀寫分離可以提升儲存系統的效率,那麼為什麼我們又要引入快取系統和搜尋技術了?快取將資料存在記憶體中,記憶體效率是硬碟的幾萬倍,這樣的好處不言而喻,而選擇搜尋技術的背後的原理就不同了,資料庫儲存的資料稱之為結構化資料,結構化資料的限制很多,當結構化資料遇到了千變萬化的隨機訪問時候,其效率會變得異常低效,但是如果一個網站不能提供靈活、高效的隨機訪問能力,那麼這個網站就會變得單板沒有活力,例如我們在淘寶裡查詢我們想要的商品,但是時常我們並不清楚自己到底想買啥,如果是在實體店裡店員會引導我們的消費,但是網站又如何引導我們的消費,那麼我們必須要賦予網站通過人們簡單意向隨機找到各種不同的商品,這個對於資料庫就是一個like操作的,但是資料裡資料量達到了一定規模以後like的低效是無法讓人忍受的,這時候搜尋技術在隨機訪問的能力正好可以彌補資料庫這塊的不足。

業務再接著的增長下去,資料量也會隨之越來越大了,這樣發展下去總有一天主庫也會產生瓶頸了,那麼接下來我們又該如何解決主庫的瓶頸了?方法很簡單就是我們要拆分主庫的資料了,那麼我該以什麼維度拆分資料了?一個數據庫裡有很多張表,不同的表都針對不同的業務,網站的不同業務所帶來的資料量也不是不同的,這個時候系統的短板就是那些資料量最大的表,所以我們要把那些會讓資料庫產生瓶頸的表拆出來,例如電商系統裡商品表和交易表往往資料量非常大,那麼我們可以把這兩種表建立在單獨的兩個資料庫裡,這樣就拆分了資料庫的壓力,這種做法叫做資料垂直拆分,不過垂直拆分會給原有的資料庫查詢,特別是有事務的相關操作產生影響,這些問題我們必須要進行改造,關於這個問題,我將在下篇裡進行討論。

當我們的系統做完了讀寫分離,資料垂直拆分後,我們的網站還在迅猛發展,最終一定又會達到新的資料庫瓶頸,當然這些瓶頸首先還是出現在那些資料量大的表裡,這些表資料的處理已經超出了單臺伺服器的能力,這個時候我們就得對這個單庫單表的資料進行更進一步的拆分,也就是將一張表分佈到兩臺不同的資料庫裡,這個做法就是叫做資料的水平拆分了

Ok,今天內容就講到這裡了,有這兩篇文章我們可以理出一個解決大型網站資料瓶頸的一個脈絡了,具體如下:

單庫資料庫–>資料庫讀寫分離–>快取技術–>搜尋技術–>資料的垂直拆分–>資料的水平拆分

以上的每個技術細節在具體實現中可能存在很大的不同,但是問題的緣由大致是一致的,我們理清這個脈絡就是想告訴大家我們如果碰到這樣的問題應該按何種思路進行思考和設計解決方案,好了,今天就寫到這裡了,晚安。

相關推薦

關於大型網站技術演進思考--儲存瓶頸2

  上篇裡我講到某些網站在高併發下會報出503錯誤,503錯誤的含義是指網站服務端暫時無法提供服務的含義,503還表達了網站服務端現在有問題但是以後可能會提供正常的服務,對http協議熟悉的人都知道,5開頭的響應碼錶達了服務端出現了問題,在我們開發測試時候最為常見的是500錯誤,500代表的含義是服務端程式出

關於大型網站技術演進思考--網站靜態化處理—快取4

  上篇我補充了下SSI的知識,SSI是一個十分常見的技術,記得多年前我看到很多入口網站頁面的字尾是.shtml,那麼這就說明很多入口網站都曾經使用過SSI技術,其實現在搜狐網站也還在用shtml,如下圖所示:     由此可見SSI在網際網路的應用還是非常廣泛的。其實網際網路很多網頁如果我們按照動靜分離

關於大型網站技術演進思考儲存瓶頸2

上篇裡我講到某些網站在高併發下會報出503錯誤,503錯誤的含義是指網站服務端暫時無法提供服務的含義,503還表達了網站服務端現在有問題但是以後可能會提供正常的服務,對http協議熟悉的人都知道,5開頭的響應碼錶達了服務端出現了問題,在我們開發測試時候最為常見的是5

關於大型網站技術演進思考--存儲的瓶頸5

做了 技術分享 表數 例子 執行 同時 設備 系統重啟 拆分 原引:http://www.cnblogs.com/sharpxiajun/p/4265853.html 上文裏我遺留了兩個問題,一個問題是數據庫做了水平拆分以後,如果我們對主鍵的設計采取一種均勻分布的策略,那麽

關於大型網站技術演進思考十四--網站靜態化處理—前後端分離—上6

  前文講到了CSI技術,這就說明網站靜態化技術的講述已經推進到了瀏覽器端了即真正到了web前端的範疇了,而時下web前端技術的前沿之一就是前後端分離技術了,那麼在這裡網站靜態化技術和前後端分離技術產生了交集,所以今天我將討論下前後端分離技術,前後端分離技術討論完後,下一篇文章我將會以網站靜態化技術的角度回過

關於大型網站技術演進思考--網站靜態化處理—動靜整合方案2

  上篇文章我簡要的介紹了下網站靜態化的演進過程,有朋友可能認為這些知識有點過於稀鬆平常了,而且網站靜態化的技術基點也不是那麼高深和難以理解,因此它和時下日新月異的web前端技術相比,就顯得不倫不類了。其實當我打算寫本系列的之前我個人覺得web前端有一個點是很多人都知道重要,但是有常常低估它作用的,那就是we

關於大型網站技術演進思考十五--網站靜態化處理—前後端分離—中7

  上篇裡我講到了一種前後端分離方案,這套方案放到服務端開發人員面前比放在web前端開發人員面前或許得到的掌聲會更多,我想很多資深前端工程師看到這樣的技術方案可能會有種說不出來的矛盾心情,當我的工作逐漸走向越來越專業化的前端開發後,我就時常被這套前後端分離方案所困惑,最近我終於明白了這個困惑的本源在哪裡了,那

關於大型網站技術演進思考十七--網站靜態化處理—滿足靜態化的前後端分離9

  前後端分離的主題雖然講完了,但是前後端分離的內容並沒有結束,本篇將繼續前後端分離的問題,只不過這次前後端分離的講述將會圍繞著本系列的主題網站靜態化進行。在講本篇主題之前,我需要糾正一下前後端分離主題講述中會讓朋友們產生誤導的地方,這種誤導就是對時下流行的一些前後端分離方案(沒有使用nodejs的前後端分離

關於大型網站技術演進思考--網站靜態化處理--總述1

  在儲存瓶頸的開篇我提到像hao123這樣的導航網站只要它部署的web伺服器數量足夠,它可以承載超大規模的併發訪問量,如果是一個動態的網站,特別是使用到了資料庫的網站是很難做到通過增加web伺服器數量的方式來有效的增加網站併發訪問能力的。但是現實情況是像淘寶、京東這樣的大型動態網站在承擔高併發的情況下任然能

關於大型網站技術演進思考--儲存瓶頸6

  在講資料庫水平拆分時候,我列出了水平拆分資料庫需要解決的兩個難題,它們分別是主鍵的設計問題和單表查詢的問題,主鍵問題前文已經做了比較詳細的講述了,但是第二個問題我沒有講述,今天我將會講講如何解決資料表被水平拆分後的單表查詢問題。   要解決資料表被水平拆分後的單表查詢問題,我們首先要回到問題的源頭,我們

關於大型網站技術演進思考十六--網站靜態化處理—前後端分離—下8

  我第一次聽說nodejs技術大概是在2009年年末,不過我真正認真在網路上進一步瞭解nodejs還是在2010年年中,當時對nodejs的認識和我現在對nodejs的認識有著天壤的區別,開始想了解nodejs我只是為了感慨谷歌公司開發的V8引擎居然如此強大,它不僅僅可以作為chrome瀏覽器的javasc

關於大型網站技術演進思考十九--網站靜態化處理—web前端優化—上11

對於一個網路請求的處理,是由兩個不同型別的操作共同完成,這兩個操作是CPU的計算操作和IO操作,如果我們以處理效率角度來評判這兩個操作,CPU操作效率是光速的,而IO操作就不盡然了,計算機裡的IO操作就是對儲存資料介質的操作,計算機裡有如下幾個介質可以儲存資料,它們分別是:CPU的一級快取、二級快取、記憶

關於大型網站技術演進思考十一--網站靜態化處理—動靜分離策略3

  前文裡我講到了網站靜態化的關鍵點是動靜分離,動靜分離是讓動態網站裡的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們就可以根據靜態資源的特點將其做快取操作,這就是網站靜態化處理的核心思路。由此可見,網站靜態化處理的核心就是動靜分離和快取兩大方面,上篇我簡單講述了動靜整合

關於大型網站技術演進思考--儲存瓶頸1

  前不久公司請來了位網際網路界的技術大牛跟我們做了一次大型網站架構的培訓,兩天12個小時資訊量非常大,知識的廣度和難度也非常大,培訓完後我很難完整理出全部聽到的知識,今天我換了個思路是回味這次培訓,這個思路就是通過本人目前的經驗和技術水平來思考下大型網站技術演進的過程。   首先我們要思考一個問題,什麼樣

關於大型網站技術演進思考--儲存瓶頸4

  如果資料庫需要進行水平拆分,這其實是一件很開心的事情,因為它代表公司的業務正在迅猛的增長,對於開發人員而言那就是有不盡的專案可以做,雖然會感覺很忙,但是人過的充實,心裡也踏實。   資料庫水平拆分簡單說來就是先將原資料庫裡的一張表在做垂直拆分出來放置在單獨的資料庫和單獨的表裡後更進一步的把本來是一個整體

關於大型網站技術演進思考--儲存瓶頸7

  本文開篇提個問題給大家,關係資料庫的瓶頸有哪些?我想有些朋友看到這個問題肯定會說出自己平時開發中碰到了一個跟資料庫有關的什麼什麼問題,然後如何解決的等等,這樣的答案沒問題,但是卻沒有代表性,如果出現了一個新的儲存瓶頸問題,你在那個場景的處理經驗可以套用在這個新問題上嗎?這個真的很難說。   其實不管什麼

關於大型網站技術演進思考十八--網站靜態化處理—反向代理10

  反向代理也是一種可以幫助實現網站靜態化的重要技術,今天我就來講講反向代理這個主題。那麼首先我們要了解下什麼是反向代理。和反向代理相對應的是正向代理,正向代理也就是我們常說的代理服務,正向代理是非常常見的,例如在某些公司裡我們想使用網際網路,那麼我們就得在瀏覽器裡設定一個代理伺服器,通過代理伺服器我們才能正

關於大型網站技術演進思考--儲存瓶頸5

  上文裡我遺留了兩個問題,一個問題是資料庫做了水平拆分以後,如果我們對主鍵的設計採取一種均勻分佈的策略,那麼它對於被水平拆分出的表後續的查詢操作將有何種影響,第二個問題就是水平拆分的擴容問題。這兩個問題在深入下去,本系列就越來越技術化了,可能最終很多朋友讀完後還是沒有找到解決實際問題的啟迪,而且我覺得這些問

關於大型網站技術演進思考--儲存瓶頸3

  儲存的瓶頸寫到現在就要進入到深水區了,如果我們所做的網站已經到了做資料庫垂直拆分和水平拆分的階段,那麼此時我們所面臨的技術難度的挑戰也會大大增強。   這裡我們先回顧下資料庫的垂直拆分和水平拆分的定義:   垂直拆分:把一個數據庫中不同業務單元的資料分到不同的資料庫裡。   水平拆分:是根據一定的規

關於大型網站技術演進思考十三--網站靜態化處理—CSI5

  講完了SSI,ESI,下面就要講講CSI了 ,CSI是瀏覽器端的動靜整合方案,當我文章發表後有朋友就問我,CSI技術是不是就是通過ajax來載入資料啊,我當時的回答只是說你的理解有點片面,那麼到底什麼是CSI技術了?這個其實要和動靜資源整合的角度來定義。   CSI技術其實是在頁面進行動靜分離後,將頁面