2013/06/27

memcached

#memcachedの特徴
・シンプルなプロトコル(バイナリプロトコル)
 よくわからない。
・libeventによるイベントハンドリング
 an event notification library.??
 http://libevent.org/
・内蔵のオンメモリストレージ
・memcached同士での通信は行わない分散方式

#起動オプション
-p 利用するTCPのポート。デフォルトは11211
-m 最大のメモリーサイズ。デフォルトは64MB
-vv very verboseモードで起動してデバックメッセージやエラーをコンソールへ出力
-d memcachedをデーモンとしてバックグラウンドで起動

#memcachedを利用するためのクライアントライブラリー
クライアントライブラリーよりmemcachedの分散を実現する
キーごとに異なるサーバへ保存することでmemcachedの分散は実現される
分散方法:
・剰余分散:
 Cache::Memcached:キーの整数のハッシュ値(CRC)を求め,
 その数値をサーバの台数で割った余りでサーバを決定する。
 memcachedサーバの追加や削除を行ったときのキャッシュの組み替えのコストが非常に大きい
・Consistent Hashing:http://www.hyuki.com/yukiwiki/wiki.cgi?ConsistentHashing
 memcachedのサーバ(ノード)のハッシュ値を求め,0から232までの円(continuum)の中に配置する。
 そして格納するデータのキーも同じようにハッシュ値を求め,円の上にマッピングする。
 データはマッピングされた地点から時計回りで最初に見つかるサーバに保存される


#メモリー管理策:
・memcachedはデフォルトでSlab Allocatorというメカニズムを使ってメモリの確保・管理を行う
Slab Allocatorの基本は確保したメモリをあらかじめ決められたクラスサイズに応じた固定長の固まりに分けて,
フラグメンテーション問題を完全に克服する
・memcachedは受けとったデータのサイズを参照し,データサイズにもっとも適したslabを選ぶ
memcachedはslab内の使用可能なchunkのフリーリストを保持しているので,
このリストを基にchunkを選び,そこにキャッシュする
・固定長なメモリ確保のアプローチにより,確保したメモリを有効活用できない。
The most efficient way to reduce the waste is to
 use a list of size classes that closely matches (if that's at all possible) common sizes of objects
 that the clients of this particular installation of memcached are likely to store.
=>ある程度の見通しが必要
・Growth Factorを使ったチューニング
memcached -f 2 -vv
slab class   1: chunk size    128 perslab  8192
slab class   2: chunk size    256 perslab  4096
slab class   3: chunk size    512 perslab  2048
slab class   4: chunk size   1024 perslab  1024
slab class   5: chunk size   2048 perslab   512
slab class   6: chunk size   4096 perslab   256
slab class   7: chunk size   8192 perslab   128
slab class   8: chunk size  16384 perslab    64
slab class   9: chunk size  32768 perslab    32
slab class  10: chunk size  65536 perslab    16
slab class  11: chunk size 131072 perslab     8
slab class  12: chunk size 262144 perslab     4
slab class  13: chunk size 524288 perslab     2
浪費が大きいので、f = 1.25に設定する
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   4: chunk size    184 perslab  5698
slab class   5: chunk size    232 perslab  4519
slab class   6: chunk size    296 perslab  3542
slab class   7: chunk size    376 perslab  2788
slab class   8: chunk size    472 perslab  2221
slab class   9: chunk size    592 perslab  1771
slab class  10: chunk size    744 perslab  1409

・memcachedの生みの親であるBradが書いたmemcached-toolというPerlスクリプトを使うと,slabたちの使用状況を簡単に把握することが可能


・memcachedは内部的にレコードがexpireしたかの監視を行わない。
替わりにgetする際にレコードのtimestampを見ることで,そのレコードがexpireしたかをチェックする。
このテクニックをlazy(なまけた)expirationと呼ぶ。
したがって,memcachedはexpireの監視にCPUタイムを消費しない
Least Recently Used(LRU)という仕組みを使う

・外部エンジン対応

・運用
200台規模のmemcachedのサーバを1つのpoolとして扱う。
1サーバあたり3GBの容量で,全体として600GB近いサイズの巨大なメモリデータベースになる


・プログラミング
get:
function get_foo (int userid) {
    result = memcached_fetch("userrow:" + userid);
    if (!result) {
        result = db_select("SELECT * FROM users WHERE userid = ?", userid);
        ●●memcached_add("userrow:" + userid, result);
    }
    return result;
}
set:
function update_foo(int userid, string dbUpdateString) {
    result = db_execute(dbUpdateString);
    if (result) {
        data = createUserDataFromDBString(dbUpdateString);
        ●●memcached_set("userrow:" + userid, data);
    }
}


What's memcached's maximum key expiration time?
If I don't provide an expiration time and the cache gets full, what happens?

ー>If you don't provide expiration and cache gets full then the oldest key-values are expired first.