利用Memcache解決資料庫高並發訪問的瓶頸問題【轉】

來源:互聯網
上載者:User

標籤:

對於高並發高訪問的Web應用程式來說,資料庫存取瓶頸一直是個令人頭疼的問題。特別當你的程式架構還是建立在單資料庫模式,而一個資料池串連數峰值已經達到500的時候,那你的程式運行離崩潰的邊緣也不遠了。很多小網站的開發人員一開始都將注意力放在了產品需求設計上,缺忽視了程式整體效能,可擴充性等方面的考慮,結果眼看著訪問量一天天網上爬,可突然發現有一天網站因為訪問量過大而崩潰了,到時候哭都來不及。所以我們一定要未雨綢繆,在資料庫還沒罷工前,想方設法給它減負,這也是這篇文章的主要議題。

  大家都知道,當有一個request過來後,web伺服器交給app伺服器,app處理並從db中存取相關資料,但db存取的花費是相當高昂的。特別是每次都取相同的資料,等於是讓資料庫每次都在做高耗費的無用功,資料庫如果會說話,肯定會發牢騷,你都問了這麼多遍了,難道還記不住嗎?是啊,如果app拿到第一次資料並存到記憶體裡,下次讀取時直接從記憶體裡讀取,而不用麻煩資料庫,這樣不就給資料庫減負了?而且從記憶體取資料必然要比從資料庫媒介取快很多倍,反而提升了應用程式的效能。

  因此,我們可以在web/app層與db層之間加一層cache層,主要目的:1.減少資料庫讀取負擔;2.提高資料讀取速度。而且,cache存取的媒介是記憶體,而一台伺服器的記憶體容量一般都是有限制的,不像硬碟容量可以做到TB層級。所以,可以考慮採用分布式的cache層,這樣更易於破除記憶體容量的限制,同時又增加了靈活性。

  Memcached介紹

  Memcached是開源的分布式cache系統,現在很多的大型web應用程式套件組合括facebook,youtube,wikipedia,yahoo等等都在使用memcached來支援他們每天數億級的頁面訪問。通過把cache層與他們的web架構整合,他們的應用程式在提高了效能的同時,還大大降低了資料庫的負載。

  具體的memcached資料大家可以直接從它的官方網站上得到。這裡我就簡單給大家介紹一下memcached的工作原理:

  Memcached處理的原子是每一個(key,value)對(以下簡稱kv對),key會通過一個hash演算法轉化成hash-key,便於尋找、對比以及做到儘可能的散列。同時,memcached用的是一個二級散列,通過一張大hash表來維護。

  Memcached有兩個核心組件組成:服務端(ms)和用戶端(mc),在一個memcached的查詢中,mc先通過計算key的hash值來確定kv對所處在的ms位置。當ms確定後,用戶端就會發送一個查詢請求給對應的ms,讓它來尋找確切的資料。因為這之間沒有互動以及多播協議,所以memcached互動帶給網路的影響是最小化的。

  舉例說明:考慮以下這個情境,有三個mc分別是X,Y,Z,還有三個ms分別是A,B,C:

  設定kv對

  X想設定key=”foo”,value=”seattle”

  X拿到ms列表,並對key做hash轉化,根據hash值確定kv對所存的ms位置

  B被選中了

  X串連上B,B收到請求,把(key=”foo”,value=”seattle”)存了起來

  擷取kv對

  Z想得到key=”foo”的value

  Z用相同的hash演算法算出hash值,並確定key=”foo”的值存在B上

  Z串連上B,並從B那邊得到value=”seattle”

  其他任何從X,Y,Z的想得到key=”foo”的值的請求都會發向B

  Memcached伺服器(ms)

  記憶體配置

  預設情況下,ms是用一個內建的叫“塊分配器”的組件來分配記憶體的。捨棄c++標準的malloc/free的記憶體配置,而採用塊分配器的主要目的是為了避免記憶體片段,否則作業系統要花費更多時間來尋找這些邏輯上連續的記憶體塊(實際上是斷開的)。用了塊分配器,ms會輪流的對記憶體進行大塊的分配,並不斷重用。當然由於塊的大小各不相同,當資料大小和塊大小不太相符的情況下,還是有可能導致記憶體的浪費。

  同時,ms對key和data都有相應的限制,key的長度不能超過250位元組,data也不能超過塊大小的限制---1MB。

  因為mc所使用的hash演算法,並不會考慮到每個ms的記憶體大小。理論上mc會分配機率上等量的kv對給每個ms,這樣如果每個ms的記憶體都不太一樣,那可能會導致記憶體使用量率的降低。所以一種替代的解決方案是,根據每個ms的記憶體大小,找出他們的最大公約數,然後在每個ms上開n個容量=最大公約數的instance,這樣就等於擁有了多個容量大小一樣的子ms,從而提供整體的記憶體使用量率。

  緩衝策略

  當ms的hash表滿了之後,新的插入資料會替代老的資料,更新的策略是LRU(最近最少使用),以及每個kv對的有效時限。Kv對儲存有效時限是在mc端由app設定並作為參數傳給ms的。

  同時ms採用是偷懶替代法,ms不會開額外的進程來即時監測過時的kv對並刪除,而是若且唯若,新來一個插入的資料,而此時又沒有多餘的空間放了,才會進行清除動作。

  快取資料庫查詢

  現在memcached最流行的一種使用方式是快取資料庫查詢,下面舉一個簡單例子說明:

  App需要得到userid=xxx的使用者資訊,對應的查詢語句類似:

  “SELECT*FROMusersWHEREuserid=xxx”

  App先去問cache,有沒有“user:userid”(key定義可預先定義約束好)的資料,如果有,返回資料;如果沒有,App會從資料庫中讀取資料,並調用cache的add函數,把資料加入cache中。

  當取的資料需要更新,app會調用cache的update函數,來保持資料庫與cache的資料同步。

  從上面的例子我們也可以發現,一旦資料庫的資料發現變化,我們一定要及時更新cache中的資料,來保證app讀到的是同步的正確資料。當然我們可以通過定時器方式記錄下cache中資料的失效時間,時間一過就會激發事件對cache進行更新,但這之間總會有時間上的延遲,導致app可能從cache讀到髒資料,這也被稱為狗洞問題。(以後我會專門描述研究這個問題)

  資料冗餘與故障預防

  從設計角度上,memcached是沒有資料冗餘環節的,它本身就是一個大規模的高效能cache層,加入資料冗餘所能帶來的只有設計的複雜性和提高系統的開支。

  當一個ms上丟失了資料之後,app還是可以從資料庫中取得資料。不過更謹慎的做法是在某些ms不能正常工作時,提供額外的ms來支援cache,這樣就不會因為app從cache中取不到資料而一下子給資料庫帶來過大的負載。

  同時為了減少某台ms故障所帶來的影響,可以使用“熱備份”方案,就是用一台新的ms來取代有問題的ms,當然新的ms還是要用原來ms的IP地址,大不了資料重新裝載一遍。

  另外一種方式,就是提高你ms的節點數,然後mc會即時偵查每個節點的狀態,如果發現某個節點長時間沒有響應,就會從mc的可用server列表裡刪除,並對server節點進行重新hash定位。當然這樣也會造成的問題是,原本key儲存在B上,變成儲存在C上了。所以此方案本身也有其弱點,最好能和“熱備份”方案結合使用,就可以使故障造成的影響最小化。

  Memcached用戶端(mc)

  Memcached用戶端有各種語言的版本供大家使用,包括java,c,php,.net等等。

  大家可以根據自己項目的需要,選擇合適的用戶端來整合。

       緩衝式的Web應用程式架構

  有了緩衝的支援,我們可以在傳統的app層和db層之間加入cache層,每個app伺服器都可以綁定一個mc,每次資料的讀取都可以從ms中取得,如果沒有,再從db層讀取。而當資料要進行更新時,除了要發送update的sql給db層,同時也要將更新的資料發給mc,讓mc去更新ms中的資料。

  假設今後我們的資料庫可以和ms進行通訊了,那可以將更新的任務統一交給db層,每次資料庫更新資料的同時會自動去更新ms中的資料,這樣就可以進一步減少app層的邏輯複雜度。如:

  不過每次我們如果沒有從cache讀到資料,都不得不麻煩資料庫。為了最小化資料庫的負載壓力,我們可以部署資料庫複寫,用slave資料庫來完成讀取操作,而master資料庫永遠只負責三件事:1.更新資料;2.同步slave資料庫;3.更新cache。如:

  以上這些緩衝式web架構在實際應用中被證明是能有效並能極大地降低資料庫的負載同時又能提高web的運行效能。當然這些架構還可以根據具體的應用環境進行變種,以達到不同硬體條件下效能的最佳化。

  未來的憧憬

  Memcached的出現可以說是革命性的,第一次讓我們意識到可以用記憶體作為儲存媒介來大規模的快取資料以提高程式的效能。不過它畢竟還是比較新的東西,還需要很多有待最佳化和改進的地方,例如:

  如何利用memcached實現cache資料庫,讓資料庫跑在記憶體上。這方面,tangentsoftware開發的memcached_engine已經做了不少工作,不過現在的版本還只是處於實驗室階段。

  如何能方便有效進行批量key清理。因為現在key是散列在不同的server上的,所以對某類key進行大批量清理是很麻煩的。因為memcached本身是一個大hash表,是不具備key的檢索功能的。所以memcached是壓根不知道某一類的key到底存了多少個,都存在哪些server上。而這類功能在實際應用中卻是經常用到。

利用Memcache解決資料庫高並發訪問的瓶頸問題【轉】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.