memcached全面剖析–5. memcached的應用和兼容程序

版權聲明:能夠任意轉載,但轉載時必須標明原做者charlee、原始連接http://tech.idv2.com/2008/07/31/memcached-005/以及本聲明。html

memcached的連載終於要結束了。 到上次爲止, 咱們介紹了與memcached直接相關的話題,本次介紹一些mixi的案例和 實際應用上的話題,並介紹一些與memcached兼容的程序。ios

mixi案例研究

mixi在提供服務的初期階段就使用了memcached。 隨着網站訪問量的急劇增長,單純爲數據庫添加slave已沒法知足須要,所以引入了memcached。 此外,咱們也從增長可擴展性的方面進行了驗證,證實了memcached的速度和穩定性都能知足須要。 如今,memcached已成爲mixi服務中很是重要的組成部分。算法

圖1 如今的系統組件數據庫

服務器配置和數量

mixi使用了許許多多服務器,如數據庫服務器、應用服務器、圖片服務器、 反向代理服務器等。單單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進程的實際內存分配量要比 指定的容量要大,這一點應當注意。less

mixi保存在memcached中的數據大部分都比較小。這樣,進程的大小要比 指定的容量大不少。所以,咱們反覆改變內存分配量進行驗證, 確認了3GB的大小不會引起swap,這就是如今應用的數值。異步

memcached使用方法和客戶端

如今,mixi的服務將200臺左右的memcached服務器做爲一個pool使用。 每臺服務器的容量爲3GB,那麼全體就有了將近600GB的巨大的內存數據庫。 客戶端程序庫使用了本連載中屢次提到車的Cache::Memcached::Fast, 與服務器進行交互。固然,緩存的分佈式算法使用的是 第4次介紹過的 Consistent Hashing算法。

應用層上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。

總結

到本次爲止,「memcached全面剖析」系列就結束了。咱們介紹了memcached的基礎、內部結構、 分散算法和應用等內容。讀完後若是您能對memcached產生興趣,就是咱們的榮幸。 關於mixi的系統、應用方面的信息,請參考本公司的開發blog。 感謝您的閱讀。

相關文章
相關標籤/搜索