原文連結:http://gihyo.jp/dev/feature/01/memcached/0005
這個系列文章的連結在這裡:
- 第1次:http://www.phpchina.com/html/29/n-35329.html
- 第2次:http://www.phpchina.com/html/30/n-35330.html
- 第3次:http://www.phpchina.com/html/31/n-35331.html
- 第4次:http://www.phpchina.com/html/32/n-35332.html
- 第5次:http://www.phpchina.com/html/32/n-35333.html
我是Mixi的長野。memcached的連載終於要結束了。 到上次為止, 我們介紹了與memcached直接相關的話題,本次介紹一些mixi的案例和 實際應用上的話題,並介紹一些與memcached相容的程式。
mixi案例研究
- 伺服器配置和數量
- memcached進程
- memcached使用方法和用戶端
- 通過Cache::Memcached::Fast維持串連
- 公用資料的處理和rehash
memcached應用經驗
- 通過daemontools啟動
- 監視
- memcached的效能
相容應用程式
總結
mixi案例研究
mixi在提供服務的初期階段就使用了memcached。 隨著網站訪問量的急劇增加,單純為資料庫添加slave已無法滿足需要,因此引入了memcached。 此外,我們也從增加可擴充性的方面進行了驗證,證明了memcached的速度和穩定性都能滿足需要。 現在,memcached已成為mixi服務中非常重要的組成部分。
圖1 現在的系統組件
伺服器配置和數量
mixi使用了許許多多伺服器,如資料庫伺服器、應用伺服器、圖片伺服器、 反向 Proxy伺服器等。單單memcached就有將近200台伺服器在運行。 memcached伺服器的典型配置如下:
CPU:Intel Pentium 4 2.8GHz
記憶體:4GB
硬碟:146GB SCSI
作業系統:Linux(x86_64)
這些伺服器以前曾用於資料庫伺服器等。隨著CPU效能提升、記憶體價格下降, 我們積極地將資料庫伺服器、應用伺服器等換成了效能更強大、記憶體更多的伺服器。 這樣,可以抑制mixi整體使用的伺服器數量的急劇增加,降低管理成本。 由於memcached伺服器幾乎不佔用CPU,就將換下來的伺服器用作memcached伺服器了。
memcached進程
每台memcached伺服器僅啟動一個memcached進程。分配給memcached的記憶體為3GB, 啟動參數如下:
/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720
由於使用了x86_64的作業系統,因此能分配2GB以上的記憶體。32位作業系統中, 每個進程最多隻能使用2GB記憶體。也曾經考慮過啟動多個分配2GB以下記憶體的進程, 但這樣一台伺服器上的TCP串連數就會成倍增加,管理上也變得複雜, 所以mixi就統一使用了64位作業系統。
另外,雖然伺服器的記憶體為4GB,卻僅分配了3GB,是因為記憶體配置量超過這個值, 就有可能導致記憶體交換(swap)。連載的第2次中 前阪講解過了memcached的記憶體儲存“slab allocator”,當時說過,memcached啟動時 指定的記憶體配置量是memcached用於儲存資料的量,沒有包括“slab allocator”本身佔用的記憶體、 以及為了儲存資料而設定的管理空間。因此,memcached進程的實際記憶體配置量要比 指定的容量要大,這一點應當注意。
mixi儲存在memcached中的資料大部分都比較小。這樣,進程的大小要比 指定的容量大很多。因此,我們反覆改變記憶體配置量進行驗證, 確認了3GB的大小不會引發swap,這就是現在應用的數值。
memcached使用方法和用戶端
現在,mixi的服務將200台左右的memcached伺服器作為一個pool使用。 每台伺服器的容量為3GB,那麼全體就有了將近600GB的巨大的記憶體資料庫。 用戶端程式庫使用了本連載中多次提到車的Cache::Memcached::Fast, 與伺服器進行互動。當然,緩衝的分布式演算法使用的是第4次介紹過的 Consistent Hashing演算法。
- Cache::Memcached::Fast - search.cpan.org
應用程式層上memcached的使用方法由開發應用程式的工程師自行決定並實現。 但是,為了防止車輪再造、防止Cache::Memcached::Fast上的教訓再次發生, 我們提供了Cache::Memcached::Fast的wrap模組並使用。
通過Cache::Memcached::Fast維持串連
Cache::Memcached的情況下,與memcached的串連(檔案控制代碼)儲存在Cache::Memcached包內的類變數中。 在mod_perl和FastCGI等環境下,包內的變數不會像CGI那樣隨時重新啟動, 而是在進程中一直保持。其結果就是不會斷開與memcached的串連, 減少了TCP串連建立時的開銷,同時也能防止短時間內反覆進行TCP串連、斷開 而導致的TCP連接埠資源枯竭。
但是,Cache::Memcached::Fast沒有這個功能,所以需要在模組之外 將Cache::Memcached::Fast對象保持在類變數中,以保證持久串連。
package Gihyo::Memcached; use strict; use warnings; use Cache::Memcached::Fast; my @server_list = qw/192.168.1.1:11211 192.168.1.1:11211/; my $fast; ## 用於保持對象 sub new { my $self = bless {}, shift; if ( !$fast ) { $fast = Cache::Memcached::Fast->new({ servers => \@server_list }); } $self->{_fast} = $fast; return $self; } sub get { my $self = shift; $self->{_fast}->get(@_); }
上面的例子中,Cache::Memcached::Fast對象儲存到類變數$fast中。
公用資料的處理和rehash
諸如mixi的首頁上的新聞這樣的所有使用者共用的快取資料、設定資訊等資料, 會佔用許多頁,訪問次數也非常多。在這種條件下,訪問很容易集中到某台memcached伺服器上。 訪問集中本身並不是問題,但是一旦訪問集中的那台伺服器發生故障導致memcached無法串連, 就會產生巨大的問題。
連載的第4次 中提到,Cache::Memcached擁有rehash功能,即在無法串連儲存資料的伺服器的情況下, 會再次計算hash值,串連其他的伺服器。
但是,Cache::Memcached::Fast沒有這個功能。不過,它能夠在串連伺服器失敗時, 短時間內不再串連該伺服器的功能。
my $fast = Cache::Memcached::Fast->new({ max_failures => 3, failure_timeout => 1 });
在failure_timeout秒內發生max_failures以上次串連失敗,就不再串連該memcached伺服器。 我們的設定是1秒鐘3次以上。
此外,mixi還為所有使用者共用的快取資料的鍵名設定命名規則, 符合命名規則的資料會自動儲存到多台memcached伺服器中, 取得時從中僅選取一台伺服器。建立該函數庫後,就可以使memcached伺服器故障 不再產生其他影響。
memcached應用經驗
到此為止介紹了memcached內部構造和函數庫,接下來介紹一些其他的應用經驗。
通過daemontools啟動
通常情況下memcached運行得相當穩定,但mixi現在使用的最新版1.2.5 曾經發生過幾次memcached進程死掉的情況。架構上保證了即使有幾台memcached故障 也不會影響服務,不過對於memcached進程死掉的伺服器,只要重新啟動memcached, 就可以正常運行,所以採用了監視memcached進程並自動啟動的方法。 於是使用了daemontools。
daemontools是qmail的作者DJB開發的UNIX服務管理工具集, 其中名為supervise的程式可用於服務啟動、停止的服務重啟等。
這裡不介紹daemontools的安裝了。mixi使用了以下的run指令碼來啟動memcached。
#!/bin/sh if [ -f /etc/sysconfig/memcached ];then . /etc/sysconfig/memcached fi exec 2>&1 exec /usr/bin/memcached -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN $OPTIONS
監視
mixi使用了名為“nagios”的開源監視軟體來監視memcached。
在nagios中可以簡單地開發外掛程式,可以詳細地監視memcached的get、add等動作。 不過mixi僅通過stats命令來確認memcached的運行狀態。
define command { command_name check_memcached command_line $USER1$/check_tcp -H $HOSTADDRESS$ -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime' -M crit }
此外,mixi將stats目錄的結果通過rrdtool轉化成圖形,進行效能監控, 並將每天的記憶體使用量量做成報表,通過郵件與開發人員共用。
memcached的效能
連載中已介紹過,memcached的效能十分優秀。我們來看看mixi的實際案例。 這裡介紹的圖表是服務所使用的訪問最為集中的memcached伺服器。
圖2 請求數
圖3 流量
圖4 TCP串連數
從上至下依次為請求數、流量和TCP串連數。請求數最大為15000qps, 流量達到400Mbps,這時的串連數已超過了10000個。 該伺服器沒有特別的硬體,就是開頭介紹的普通的memcached伺服器。 此時的CPU利用率為:
圖5 CPU利用率
可見,仍然有idle的部分。因此,memcached的效能非常高, 可以作為Web應用程式開發人員放心地儲存臨時資料或快取資料的地方。
相容應用程式
memcached的實現和協議都十分簡單,因此有很多與memcached相容的實現。 一些功能強大的擴充可以將memcached的記憶體資料寫到磁碟上,實現資料的持久性和冗餘。 連載第3次介紹過,以後的memcached的儲存層將變成可擴充的(pluggable),逐漸支援這些功能。
這裡介紹幾個與memcached相容的應用程式。
-
repcached
-
為memcached提供複製(replication)功能的patch。
-
Flared
-
儲存到QDBM。同時實現了非同步複製和fail over等功能。
-
memcachedb
-
儲存到BerkleyDB。還實現了message queue。
-
Tokyo Tyrant
-
將資料存放區到Tokyo Cabinet。不僅與memcached協議相容,還能通過HTTP進行訪問。
Tokyo Tyrant案例
mixi使用了上述相容應用程式中的Tokyo Tyrant。Tokyo Tyrant是平林開發的 Tokyo Cabinet DBM的網路介面。它有自己的協議,但也擁有memcached相容協議, 也可以通過HTTP進行資料交換。Tokyo Cabinet雖然是一種將資料寫到磁碟的實現,但速度相當快。
mixi並沒有將Tokyo Tyrant作為快取服務器,而是將它作為儲存索引值對組合的DBMS來使用。 主要作為儲存使用者上次訪問時間的資料庫來使用。它與幾乎所有的mixi服務都有關, 每次使用者訪問頁面時都要更新資料,因此負荷相當高。MySQL的處理十分笨重, 單獨使用memcached儲存資料又有可能會遺失資料,所以引入了Tokyo Tyrant。 但無需重新開發用戶端,只需原封不動地使用Cache::Memcached::Fast即可, 這也是優點之一。關於Tokyo Tyrant的詳細資料,請參考本公司的開發blog。
- mixi Engineers' Blog - Tokyo Tyrantによる耐高負荷DBの構築
- mixi Engineers' Blog - Tokyo (Cabinet|Tyrant)の新機能
總結
到本次為止,“memcached全面剖析”系列就結束了。我們介紹了memcached的基礎、內部結構、 分散演算法和應用等內容。讀完後如果您能對memcached產生興趣,就是我們的榮幸。 關於mixi的系統、應用方面的資訊,請參考本公司的開發blog。 感謝您的閱讀。
著作權聲明:可以任意轉載,但轉載時必須標明原作者charlee、原始連結以及本聲明。
http://www.bkjia.com/PHPjc/735130.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/735130.htmlTechArticle原文連結:http://gihyo.jp/dev/feature/01/memcached/0005 這個系列文章的連結在這裡: 第1次:http://www.phpchina.com/html/29/n-35329.html 第2次:http://www.php...