memcached完全剖析–1. memcached的基礎
版權聲明:可以任意轉載,但轉載時必須標明原作者charlee、原始鏈接http://tech.idv2.com/2008/07/10/memcached-001/以及本聲明。
翻譯一篇技術評論社的文章,是講memcached的連載。fcicq同學說這個東西很有用,希望大家喜歡。
發表日:2008/7/2 作者:長野雅廣(Masahiro Nagano) 原文鏈接:http://gihyo.jp/dev/feature/01/memcached/0001
我是mixi株式會社開發部系統運營組的長野。日常負責程序的運營。從今天開始,將分幾次針對最近在Web應用的可擴展性領域的熱門話題memcached,與我公司開發部研究開發組的前坂一起,說明其內部結構和使用。
memcached是什麼?
memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 為首開發的一款軟體。現在已成為 mixi、 hatena、 Facebook、 Vox、LiveJournal等眾多服務中提高Web應用擴展性的重要因素。
許多Web應用都將數據保存到RDBMS中,應用伺服器從中讀取數據並在瀏覽器中顯示。但隨著數據量的增大、訪問的集中,就會出現RDBMS的負擔加重、資料庫響應惡化、網站顯示延遲等重大影響。
這時就該memcached大顯身手了。memcached是高性能的分散式內存緩存伺服器。一般的使用目的是,通過緩存資料庫查詢結果,減少資料庫訪問次數,以提高動態Web應用的速度、提高可擴展性。
圖1 一般情況下memcached的用途
memcached的特徵memcached作為高速運行的分散式緩存伺服器,具有以下的特點。
協議簡單
memcached的伺服器客戶端通信並不使用複雜的XML等格式,而使用簡單的基於文本行的協議。因此,通過telnet 也能在memcached上保存數據、取得數據。下面是例子。
$ telnet localhost 11211Trying 127.0.0.1...Connected to localhost.localdomain (127.0.0.1).Escape character is "^]".set foo 0 0 3 (保存命令)bar (數據)STORED (結果)get foo (取得命令)VALUE foo 0 3 (數據)bar (數據)
協議文檔位於memcached的源代碼內,也可以參考以下的URL。
基於libevent的事件處理
libevent是個程序庫,它將Linux的epoll、BSD類操作系統的kqueue等事件處理功能封裝成統一的介面。即使對伺服器的連接數增加,也能發揮O(1)的性能。 memcached使用這個libevent庫,因此能在Linux、BSD、Solaris等操作系統上發揮其高性能。關於事件處理這裡就不再詳細介紹,可以參考Dan Kegel的The C10K Problem。
內置內存存儲方式
為了提高性能,memcached中保存的數據都存儲在memcached內置的內存存儲空間中。由於數據僅存在於內存中,因此重啟memcached、重啟操作系統會導致全部數據消失。另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)演算法自動刪除不使用的緩存。 memcached本身是為緩存而設計的伺服器,因此並沒有過多考慮數據的永久性問題。關於內存存儲的詳細信息,本連載的第二講以後前坂會進行介紹,請屆時參考。
memcached不互相通信的分散式memcached儘管是「分散式」緩存伺服器,但伺服器端並沒有分散式功能。各個memcached不會互相通信以共享信息。那麼,怎樣進行分散式呢?這完全取決於客戶端的實現。本連載也將介紹memcached的分散式。
圖2 memcached的分散式
接下來簡單介紹一下memcached的使用方法。
安裝memcachedmemcached的安裝比較簡單,這裡稍加說明。
memcached支持許多平台。
另外也能安裝在Windows上。這裡使用Fedora Core 8進行說明。
memcached的安裝運行memcached需要本文開頭介紹的libevent庫。Fedora 8中有現成的rpm包,通過yum命令安裝即可。
$ sudo yum install libevent libevent-devel
memcached的源代碼可以從memcached網站上下載。本文執筆時的最新版本為1.2.5。 Fedora 8雖然也包含了memcached的rpm,但版本比較老。因為源代碼安裝並不困難,這裡就不使用rpm了。
memcached安裝與一般應用程序相同,configure、make、make install就行了。
$ wget http://www.danga.com/memcached/dist/memcached-1.2.5.tar.gz$ tar zxf memcached-1.2.5.tar.gz$ cd memcached-1.2.5$ ./configure$ make$ sudo make install
默認情況下memcached安裝到/usr/local/bin下。
memcached的啟動從終端輸入以下命令,啟動memcached。
$ /usr/local/bin/memcached -p 11211 -m 64m -vvslab class 1: chunk size 88 perslab 11915slab class 2: chunk size 112 perslab 9362slab class 3: chunk size 144 perslab 7281中間省略slab class 38: chunk size 391224 perslab 2slab class 39: chunk size 489032 perslab 2<23 server listening<24 send buffer was 110592, now 268435456<24 server listening (udp)<24 server listening (udp)<24 server listening (udp)<24 server listening (udp)
這裡顯示了調試信息。這樣就在前台啟動了memcached,監聽TCP埠11211 最大內存使用量為64M。調試信息的內容大部分是關於存儲的信息,下次連載時具體說明。
作為daemon後台啟動時,只需
$ /usr/local/bin/memcached -p 11211 -m 64m -d
這裡使用的memcached啟動選項的內容如下。
選項 | 說明 |
-p | 使用的TCP埠。默認為11211 |
-m | 最大內存大小。默認為64M |
-vv | 用very vrebose模式啟動,調試信息和錯誤輸出到控制台 |
-d | 作為daemon在後台啟動 |
上面四個是常用的啟動選項,其他還有很多,通過
$ /usr/local/bin/memcached -h
命令可以顯示。許多選項可以改變memcached的各種行為,推薦讀一讀。
用客戶端連接許多語言都實現了連接memcached的客戶端,其中以Perl、PHP為主。僅僅memcached網站上列出的語言就有
等等。
這裡介紹通過mixi正在使用的Perl庫鏈接memcached的方法。
使用Cache::MemcachedPerl的memcached客戶端有
等幾個CPAN模塊。這裡介紹的Cache::Memcached是memcached的作者Brad Fitzpatric的作品,應該算是memcached的客戶端中應用最為廣泛的模塊了。
使用Cache::Memcached連接memcached
下面的源代碼為通過Cache::Memcached連接剛才啟動的memcached的例子。
#!/usr/bin/perluse strict;use warnings;use Cache::Memcached;my $key = "foo";my $value = "bar";my $expires = 3600; # 1 hourmy $memcached = Cache::Memcached->new({servers => ["127.0.0.1:11211"],compress_threshold => 10_000});$memcached->add($key, $value, $expires);my $ret = $memcached->get($key);print "$ret
";
在這裡,為Cache::Memcached指定了memcached伺服器的IP地址和一個選項,以生成實例。 Cache::Memcached常用的選項如下所示。
選項 | 說明 |
servers | 用數組指定memcached伺服器和埠 |
compress_threshold | 數據壓縮時使用的值 |
namespace | 指定添加到鍵的前綴 |
另外,Cache::Memcached通過Storable模塊可以將Perl的複雜數據序列化之後再保存,因此散列、數組、對象等都可以直接保存到memcached中。
保存數據向memcached保存數據的方法有
它們的使用方法都相同:
my $add = $memcached->add( "鍵", "值", "期限" );my $replace = $memcached->replace( "鍵", "值", "期限" );my $set = $memcached->set( "鍵", "值", "期限" );
向memcached保存數據時可以指定期限(秒)。不指定期限時,memcached按照LRU演算法保存數據。這三個方法的區別如下:
選項 | 說明 |
add | 僅當存儲空間中不存在鍵相同的數據時才保存 |
replace | 僅當存儲空間中存在鍵相同的數據時才保存 |
set | 與add和replace不同,無論何時都保存 |
獲取數據
獲取數據可以使用get和get_multi方法。
my $val = $memcached->get("鍵");my $val = $memcached->get_multi("鍵1", "鍵2", "鍵3", "鍵4", "鍵5");
一次取得多條數據時使用get_multi。get_multi可以非同步地同時取得多個鍵值,其速度要比循環調用get快數十倍。
刪除數據刪除數據使用delete方法,不過它有個獨特的功能。
$memcached->delete("鍵", "阻塞時間(秒)");
刪除第一個參數指定的鍵的數據。第二個參數指定一個時間值,可以禁止使用同樣的鍵保存新數據。此功能可以用於防止緩存數據的不完整。但是要注意,set函數忽視該阻塞,照常保存數據
增一和減一操作可以將memcached上特定的鍵值作為計數器使用。
my $ret = $memcached->incr("鍵");$memcached->add("鍵", 0) unless defined $ret;
增一和減一是原子操作,但未設置初始值時,不會自動賦成0。因此,應當進行錯誤檢查,必要時加入初始化操作。而且,伺服器端也不會對超過2<sup>32</sup>時的行為進行檢查。
總結這次簡單介紹了memcached,以及它的安裝方法、Perl客戶端Cache::Memcached的用法。只要知道,memcached的使用方法十分簡單就足夠了。
下次由前坂來說明memcached的內部結構。了解memcached的內部構造,就能知道如何使用memcached才能使Web應用的速度更上一層樓。歡迎繼續閱讀下一章
推薦閱讀:
※八字2基礎
※少林行樁功--心意把的基礎功法
※[轉載]基礎瑜伽解剖學(九)
※肱三頭肌的基礎進階丨窄距俯卧撐
※學員作品 |基礎填詞班作業:《相見歡》六十三首
TAG:基礎 |