發表日:2008/7/2
原文連結:http://gihyo.jp/dev/feature/01/memcached/0001
這個系列文章的連結在這裡:
- 第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株式會社開發部系統運營組的長野。 日常負責程式的運營。從今天開始,將分幾次針對最近在Web應用的可擴充性領域 的熱門話題memcached,與我公司開發部研究開發組的前阪一起, 說明其內部結構和使用。
- memcached是什嗎?
- memcached的特徵
- 協議簡單
- 基於libevent的事件處理
- 內建記憶體儲存方式
- memcached不互相通訊的分布式
- 安裝memcached
- memcached的安裝
- memcached的啟動
- 用用戶端串連
- 使用Cache::Memcached
- 使用Cache::Memcached串連memcached
- 儲存資料
- 擷取資料
- 刪除資料
- 增一和減一操作
- 總結
memcached是什嗎?
memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 為首開發的一款軟體。現在已成為 mixi、 hatena、 Facebook、 Vox、LiveJournal等眾多服務中 提高Web應用擴充性的重要因素。
許多Web應用都將資料儲存到RDBMS中,應用伺服器從中讀取資料並在瀏覽器中顯示。 但隨著資料量的增大、訪問的集中,就會出現RDBMS的負擔加重、資料庫響應惡化、 網站顯示延遲等重大影響。
這時就該memcached大顯身手了。memcached是高效能的分布式記憶體快取服務器。 一般的使用目的是,通過快取資料庫查詢結果,減少資料庫訪問次數,以提高動態Web應用的速度、 提高可擴充性。
圖1 一般情況下memcached的用途
memcached的特徵
memcached作為高速啟動並執行分布式快取服務器,具有以下的特點。
- 協議簡單
- 基於libevent的事件處理
- 內建記憶體儲存方式
- memcached不互相通訊的分布式
協議簡單
memcached的伺服器用戶端通訊並不使用複雜的XML等格式, 而使用簡單的基於文本行的協議。因此,通過telnet 也能在memcached上儲存資料、取得資料。下面是例子。
$ telnet localhost 11211 Trying 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。
- http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt
基於libevent的事件處理
libevent是個程式庫,它將Linux的epoll、BSD類作業系統的kqueue等事件處理功能 封裝成統一的介面。即使對伺服器的串連數增加,也能發揮O(1)的效能。 memcached使用這個libevent庫,因此能在Linux、BSD、Solaris等作業系統上發揮其高效能。 關於事件處理這裡就不再詳細介紹,可以參考Dan Kegel的The C10K Problem。
- libevent: http://www.monkey.org/~provos/libevent/
- The C10K Problem: http://www.kegel.com/c10k.html
內建記憶體儲存方式
為了提高效能,memcached中儲存的資料都儲存在memcached內建的記憶體儲存空間中。 由於資料僅存在於記憶體中,因此重啟memcached、重啟作業系統會導致全部資料消失。 另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)演算法自動刪除不使用的緩衝。 memcached本身是為緩衝而設計的伺服器,因此並沒有過多考慮資料的永久性問題。 關於記憶體儲存的詳細資料,本連載的第二講以後前阪會進行介紹,請屆時參考。
memcached不互相通訊的分布式
memcached儘管是“分布式”快取服務器,但伺服器端並沒有分布式功能。 各個memcached不會互相通訊以共用資訊。那麼,怎樣進行分布式呢? 這完全取決於用戶端的實現。本連載也將介紹memcached的分布式。
圖2 memcached的分布式
接下來簡單介紹一下memcached的使用方法。
安裝memcached
memcached的安裝比較簡單,這裡稍加說明。
memcached支援許多平台。
- Linux
- FreeBSD
- Solaris (memcached 1.2.5以上版本)
- Mac OS X
另外也能安裝在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:http://www.danga.com/memcached/download.bml
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 -vv slab class 1: chunk size 88 perslab 11915 slab class 2: chunk size 112 perslab 9362 slab class 3: chunk size 144 perslab 7281 中間省略 slab class 38: chunk size 391224 perslab 2 slab 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網站上列出的語言就有
- Perl
- PHP
- Python
- Ruby
- C#
- C/C++
- Lua
等等。
- memcached用戶端API:http://www.danga.com/memcached/apis.bml
這裡介紹通過mixi正在使用的Perl庫連結memcached的方法。
使用Cache::Memcached
Perl的memcached用戶端有
- Cache::Memcached
- Cache::Memcached::Fast
- Cache::Memcached::libmemcached
等幾個CPAN模組。這裡介紹的Cache::Memcached是memcached的作者Brad Fitzpatric的作品, 應該算是memcached的用戶端中應用最為廣泛的模組了。
- Cache::Memcached - search.cpan.org: http://search.cpan.org/dist/Cache-Memcached/
使用Cache::Memcached串連memcached
下面的原始碼為通過Cache::Memcached串連剛才啟動的memcached的例子。
#!/usr/bin/perl use strict; use warnings; use Cache::Memcached; my $key = "foo"; my $value = "bar"; my $expires = 3600; # 1 hour my $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\n";在這裡,為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 32時的行為進行檢查。
總結
這次簡單介紹了memcached,以及它的安裝方法、Perl用戶端Cache::Memcached的用法。 只要知道,memcached的使用方法十分簡單就足夠了。
下次由前阪來說明memcached的內部結構。瞭解memcached的內部構造, 就能知道如何使用memcached才能使Web應用的速度更上一層樓。 歡迎繼續閱讀下一章。
著作權聲明:可以任意轉載,但轉載時必須標明原作者charlee、原始連結以及本聲明。
http://www.bkjia.com/PHPjc/735134.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/735134.htmlTechArticle發表日:2008/7/2 原文連結:http://gihyo.jp/dev/feature/01/memcached/0001 這個系列文章的連結在這裡: 第1次:http://www.phpchina.com/html/29/n-35329.html 第...