nc を用いた Memcached のオペレーション方法

nc を用いた Memcached のオペレーション方法についてまとめておきます。

特定のキーのデータを参照、削除する

memcached に接続するためのツールはいくつかあるが、ここでは nc を用いた方法を採用している。

telnet よりも nc(netcat) を使ったほうがいい理由は http://www.terminalinflection.com/use-netcat-not-telnet-to-test-network-connectivity/ が詳しい。

By default it opens a TCP connection to a nominated port, but this flexible port argument is more of a side effect of its function as an interactive console, and not its real function. So from now on, you should be using netcat – which is executed as nc.

また、nc コマンドのオプションの説明と詳しい使い方については http://www.computerhope.com/unix/nc.htm に綺麗にまとめられている。

memd の host が localhost, port が 11211 だとすると、以下のように接続できる。

nc -C localhost 11211

接続できたら後は memd のコマンドでオペレーションできる。 以下はキー views/10watch.jp/products/35030?part=xxx に対してのオペレーション例。 get でデータを取得し、 delete でそれを削除している。

get views/10watch.jp/products/35030?part=xxx
VALUE views/10watch.jp/products/35030?part=xxx 401
{DOMが表示されます}
END
delete views/10watch.jp/products/35030?part=xxx
DELETED

特定のキーの有効期限を知る

オペレーション手順に入る前に Memcached はデータをどのようにキャッシュしているかについて説明する。

Memcached には Slab Allocation というものがある。 メモリの使用量を最適化したり、データが失効したときのメモリの断片化を防いだりする。 これはどういうものかざっくりと説明すると、 memcached は確保したメモリを予め設定された値(Growth Factor)をもとに固定長のchunkに分割していて、 データをキャッシュする際、そのデータサイズに応じて適切な chunk に割り振っている。

(より詳細な Memory Allocation の説明は http://docs.oracle.com/cd/E17952_01/refman-5.6-en/ha-memcached-using-memory.html などを参照のこと)

これを踏まえると、特定のキーを参照するためには、slabs を取得し、そこから各itemをたどっていく必要があることがわかる。

host を localhost, port を 11211 とすると、 slab 一覧を取得するには、stats slabs コマンドを発行する。

$ echo 'stats slabs' | nc localhost 11211
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 4
STAT 1:total_chunks 43688
STAT 1:used_chunks 43687
STAT 1:free_chunks 1
STAT 1:free_chunks_end 0
STAT 1:mem_requested 3898654
STAT 1:get_hits 14208428707
STAT 1:cmd_set 1164771362
STAT 1:delete_hits 1
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
...

次に、一覧の中から chunk size を目安に slabid を絞込、item数を取得する。

$ echo 'stats items' | nc localhost 11211 | grep "9:"
STAT items:9:number 1747
STAT items:9:age 70
STAT items:9:evicted 21194795
STAT items:9:evicted_nonzero 21194795
STAT items:9:evicted_time 69
STAT items:9:outofmemory 0
STAT items:9:tailrepairs 0
STAT items:9:reclaimed 50329
STAT items:9:expired_unfetched 31246
STAT items:9:evicted_unfetched 20696155
STAT items:19:number 8280
STAT items:19:age 3535
STAT items:19:evicted 942789
STAT items:19:evicted_nonzero 942789
STAT items:19:evicted_time 3533
...

item数が 1747 とわかったので、slab 内のキー一覧から目的のキーで grep する。

$ echo 'stats cachedump 9 1747' | nc localhost 11211 | grep "part=xxx"
ITEM views/10watch.jp/products/35030?part=xxx [427 b; 1435060800 s]

このデータは ITEM {key_name} [{cache_size} b; {expires_at} s] であるため、1435060800 が失効日時とわかる。 unixtime を変換して 2015/06/23 21:00:00 とわかる。

ref.