memcached for perl

來源:互聯網
上載者:User

用到memcached,記下

 memcached中儲存的資料都儲存在memcached內建的記憶體儲存空間中。 由於資料僅存在於記憶體中,因此重啟memcached、重啟作業系統會導致全部資料消失。 另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)演算法自動刪除不使用的緩衝。 memcached本身是為緩衝而設計的伺服器,因此並沒有過多考慮資料的永久性問題。

 memcached是“分布式”快取服務器,但伺服器端並沒有分布式功能。 各個memcached不會互相通訊以共用資訊。進行分布式完全取決於用戶端的實現。

memcached需要 libevent庫 #yum install libevent libevent-devel

 

$ wget http://www.danga.com/memcached/dist/memcached-1.×.×.tar.gz
$ tar zxf memcached-1.×.×.tar.gz
$ cd memcached-1.×.×$ ./configure
$ make
$ sudo make install
#/usr/local/bin/memcached -p 11211 -m 64m -d
選項 說明
-p 使用的TCP連接埠。預設為11211
-m 最大記憶體大小。預設為64M
-vv 用very vrebose模式啟動,調試資訊和錯誤輸出到控制台
-d 作為daemon在後台啟動

memcached用戶端API :http://www.danga.com/memcached/apis.bml

Perl的memcached用戶端有 Cache::Memcached Cache::Memcached::Fast Cache::Memcached::libmemcached

等幾個CPAN模組。

  http://search.cpan.org/dist/Cache-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儲存資料的方法有 add replace set 它們的使用方法都相同:

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。因此, 應當進行錯誤檢查,必要時加入初始化操作。 Cache::Memcached的分布式方法

Perl的memcached用戶端函數庫Cache::Memcached是 memcached的作者Brad Fitzpatrick的作品,可以說是原裝的函數庫了。 Cache::Memcached - search.cpan.org

該函數庫實現了分布式功能,是memcached標準的分布式方法。 根據餘數計算分散

Cache::Memcached的分布式方法簡單來說,就是“根據伺服器台數的餘數進行分散”。 求得鍵的整數雜湊值,再除以伺服器台數,根據其餘數來選擇伺服器。

下面將Cache::Memcached簡化成以下的Perl指令碼來進行說明。

use strict;
use warnings;
use String::CRC32;

my @nodes = ('node1','node2','node3');
my @keys = ('tokyo', 'kanagawa', 'chiba', 'saitama', 'gunma');

foreach my $key (@keys) {
my $crc = crc32($key); # CRC値
my $mod = $crc % ( $#nodes + 1 );
my $server = $nodes[ $mod ]; # 根據餘數選擇伺服器
printf "%s => %s/n", $key, $server;
}

Cache::Memcached在求雜湊值時使用了CRC。 String::CRC32 - search.cpan.org

首先求得字串的CRC值,根據該值除以伺服器節點數目得到的餘數決定伺服器。 上面的代碼執行後輸入以下結果:

tokyo       => node2
kanagawa => node3
chiba => node2
saitama => node1
gunma => node1

根據該結果,“tokyo”分散到node2,“kanagawa”分散到node3等。 多說一句,當選擇的伺服器無法串連時,Cache::Memcached會將串連次數 添加到鍵之後,再次計算雜湊值並嘗試串連。這個動作稱為rehash。 不希望rehash時可以在產生Cache::Memcached對象時指定“rehash => 0”選項。 根據餘數計算分散的缺點

餘數計算的方法簡單,資料的分散性也相當優秀,但也有其缺點。 那就是當添加或移除伺服器時,緩衝重組的代價相當巨大。 添加伺服器後,餘數就會產生巨變,這樣就無法擷取與儲存時相同的伺服器, 從而影響緩衝的命中率。用Perl寫段代碼來驗證其代價。

use strict;
use warnings;
use String::CRC32;

my @nodes = @ARGV;
my @keys = ('a'..'z');
my %nodes;

foreach my $key ( @keys ) {
my $hash = crc32($key);
my $mod = $hash % ( $#nodes + 1 );
my $server = $nodes[ $mod ];
push @{ $nodes{ $server } }, $key;
}

foreach my $node ( sort keys %nodes ) {
printf "%s: %s/n", $node, join ",", @{ $nodes{$node} };
}

這段Perl指令碼示範了將“a”到“z”的鍵儲存到memcached並訪問的情況。 將其儲存為mod.pl並執行。

首先,當伺服器只有三台時:

$ mod.pl node1 node2 nod3
node1: a,c,d,e,h,j,n,u,w,x
node2: g,i,k,l,p,r,s,y
node3: b,f,m,o,q,t,v,z

結果如上,node1儲存a、c、d、e……,node2儲存g、i、k……, 每台伺服器都儲存了8個到10個資料。

接下來增加一台memcached伺服器。

$ mod.pl node1 node2 node3 node4
node1: d,f,m,o,t,v
node2: b,i,k,p,r,y
node3: e,g,l,n,u,w
node4: a,c,h,j,q,s,x,z

添加了node4。可見,只有d、i、k、p、r、y命中了。像這樣,添加節點後 鍵分散到的伺服器會發生巨大變化。26個鍵中只有六個在訪問原來的伺服器, 其他的全都移到了其他伺服器。命中率降低到23%。在Web應用程式中使用memcached時, 在添加memcached伺服器的瞬間緩衝效率會大幅度下降,負載會集中到資料庫伺服器上, 有可能會發生無法提供正常服務的情況。

mixi的Web應用程式運用中也有這個問題,導致無法添加memcached伺服器。 但由於使用了新的分布式方法,現在可以輕而易舉地添加memcached伺服器了。 這種分布式方法稱為 Consistent Hashing。 Consistent Hashing

關於Consistent Hashing的思想,mixi株式會社的開發blog等許多地方都介紹過, 這裡只簡單地說明一下。 mixi Engineers' Blog - スマートな分散で快適キャッシュライフ ConsistentHashing - コンシステント ハッシュ法 Consistent Hashing的簡單說明

Consistent Hashing如下所示:首先求出memcached伺服器(節點)的雜湊值, 並將其配置到0~232 的圓(continuum)上。 然後用同樣的方法求出儲存資料的鍵的雜湊值,並映射到圓上。 然後從資料對應到的位置開始順時針尋找,將資料儲存到找到的第一個伺服器上。 如果超過232 仍然找不到伺服器,就會儲存到第一台memcached伺服器上。

圖4 Consistent Hashing:基本原理

從上圖的狀態中添加一台memcached伺服器。餘數分布式演算法由於儲存鍵的伺服器會發生巨大變化 而影響緩衝的命中率,但Consistent Hashing中,只有在continuum上增加伺服器的地點逆時針方向的 第一台伺服器上的鍵會受到影響。

圖5 Consistent Hashing:添加伺服器

因此,Consistent Hashing最大限度地抑制了鍵的重新分配。 而且,有的Consistent Hashing的實現方法還採用了虛擬節點的思想。 使用一般的hash函數的話,伺服器的映射地點的分布非常不均勻。 因此,使用虛擬節點的思想,為每個物理節點(伺服器) 在continuum上分配100~200個點。這樣就能抑制分布不均勻, 最大限度地減小伺服器增減時的緩衝重新分配。

通過下文中介紹的使用Consistent Hashing演算法的memcached用戶端函數庫進行測試的結果是, 由伺服器台數(n)和增加的伺服器台數(m)計算增加伺服器後的命中率計算公式如下:

(1 - n/(n+m)) * 100 支援Consistent Hashing的函數庫

本連載中多次介紹的Cache::Memcached雖然不支援Consistent Hashing, 但已有幾個用戶端函數庫支援了這種新的分布式演算法。 第一個支援Consistent Hashing和虛擬節點的memcached用戶端函數庫是 名為libketama的PHP庫,由last.fm開發。 libketama - a consistent hashing algo for memcache clients – RJ ブログ - Users at Last.fm

至於Perl用戶端,連載的第1次 中介紹過的Cache::Memcached::Fast和Cache::Memcached::libmemcached支援 Consistent Hashing。 Cache::Memcached::Fast - search.cpan.org Cache::Memcached::libmemcached - search.cpan.org

兩者的介面都與Cache::Memcached幾乎相同,如果正在使用Cache::Memcached, 那麼就可以方便地替換過來。Cache::Memcached::Fast重新實現了libketama, 使用Consistent Hashing建立對象時可以指定ketama_points選項。

my $memcached = Cache::Memcached::Fast->new({
servers => ["192.168.0.1:11211","192.168.0.2:11211"],
ketama_points => 150
});

另外,Cache::Memcached::libmemcached 是一個使用了Brain Aker開發的C函數庫libmemcached的Perl模組。 libmemcached本身支援幾種分布式演算法,也支援Consistent Hashing, 其Perl綁定也支援Consistent Hashing。 Tangent Software: libmemcached
曆史上的今天: 網站安全 2008-07-29
收藏到: Del.icio.us

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.