この記事では、Gotanda.pm #8 でデモをする予定だった内容の手順と結果を紹介します。
勉強会では、発表時間が足りずデモが実施できませんでした。
何かの参考になれば幸いです。
はじめに
memcached-cli は筆者が開発した Perl 製の Memcached クライアントです。
テキストプロトコルでできる操作はすべて実行でき、TELNET よりもユーザーにやさしいインタフェースとなっております。
依存も少なく、Perl 5.8 以上であれば動作するように作ったつもりなので、Memcached をお使いの方はぜひ使ってみてください。
Memcached Slabs Reassign と LRU Crawler について
デモの手順に入る前に、今回触れる Memcached の機能について、かんたんに説明しておきます。
そもそもの話ですが、Memcached はデータをサイズに応じて異なる Slab Class に配置します。
各 Slab Class には 1MB のページ単位でメモリが割当てられます。一度ページが確保されると、通常はたとえ当該 Class のデータ量が減ったとしても、ページが解放されることはありません。1
Slabs Reassign はこの異なる Slab Class 間のページ割当てを変更できる機能です。
次に LRU Crawler ですが、これは Expire したデータをなめてメモリ領域を解放してくれるものです。
こちらも、Expire したデータを get
したり、同じ Slab Class にデータを set
するなりしなければ、通常は解放されません。
デモ手順と結果
環境は MacOSX で、Homebrew で Memcached 1.4.22 をインストールしています。
1. Memcached をメモリ少なめで起動
あふれるところが見たいので、Memcached の -m
オプションを4MBとすごくメモリ少なめで起動します。
同時に、-o
オプションで slab_reassign
と lru_crawler
を有効にしておきます。
また、後で stats detail dump
の結果を見たいので、 -D ":"
でネームスペースごとの統計情報収集機能を有効にしておきます。
% memcached -m 4 -o slab_reassign,lru_crawler -D ":"
2. 2種類のデータサイズでデータを生成し、あふれさせる
まずは memcached-cli で接続します。
さっきの memcached の起動コマンドではフォアグラウンドで立ち上がるので、別窓で操作して下さい。
% memcached-cli localhost
Type '\h' or 'help' to show help.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
サーバは起動したばかりなので、 display
コマンドの結果は空です。
randomset
コマンドでデータを生成して Memcached に set
していきます。
// 500B のデータを "sample1" ネームスペース下に5000個生成
memcached@localhost:11211> randomset 5000 500 500 sample1
Random Generate. [....................]
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 7s 3 5000 yes 0 0 0
// 1kB のデータを "sample2" ネームスペース下に1000個生成
memcached@localhost:11211> randomset 1000 1000 1000 sample2
Random Generate. [....................]
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 29s 3 5000 yes 0 0 0
12 1.2K 8s 1 885 yes 115 1 0
// 1kB のデータを "sample3" ネームスペース下に1000個生成
memcached@localhost:11211> randomset 1000 1000 1000 sample3
Random Generate. [....................]
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 35s 3 5000 yes 0 0 0
12 1.2K 2s 1 885 yes 1115 1 0
Slab Class #9 に3ページのメモリが確保されたので、 #12 には1ページしか確保できません。
#12 には 885 個以上データを set することができず、あふれて eviction してしまいました。
3. データを全て無効化し、LRU Crawler で掃除する
flush_all
コマンドで全てのデータを期限切れにします。
ただし、これだけでは確保されたページが解放されるわけではないので、Slab Class #12 には 885 個以上データを set することができません。
memcached@localhost:11211> flush_all
OK
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 466s 3 5000 yes 0 0 0
12 1.2K 433s 1 885 yes 1115 1 0
memcached@localhost:11211> randomset 1000 1000 1000 sample3
Random Generate. [....................]
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 486s 3 5000 yes 0 0 0
12 1.2K 2s 1 885 yes 1230 1 0
そこで、Slabs Reassign の出番です。
データは無効化したので、このままページ割当てを #9 => #12 に変えて行っても特に問題は無いのですが、今回はその前に LRU Crawler で #9 のデータをクリアしておきます。
// LRU Crawler を Slab Class #9 に対して手動実行する
memcached@localhost:11211> call lru_crawler crawl 9
OK
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 0s 3 0 yes 0 0 0
12 1.2K 18s 1 885 yes 1230 1 0
// Slabs Reassign でページ割当てを #9 => #12 に移していく
memcached@localhost:11211> call slabs reassign 9 12
OK
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 0s 2 0 yes 0 0 0
12 1.2K 38s 2 885 yes 1230 1 0
memcached@localhost:11211> call slabs reassign 9 12
OK
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 0s 1 0 yes 0 0 0
12 1.2K 42s 3 885 yes 1230 1 0
以上、Pages の数が #9 => #12 に移動しているのがおわかりいただけるでしょうか。
これで、 #12 には 3MB 分データを set できるはずです。
やってみましょう。
// ネームスペースを変えながら、1000個ずつ計3000個のデータ set を試みる
memcached@localhost:11211> randomset 1000 1000 1000 sample3
Random Generate. [....................]
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 0s 1 0 yes 0 0 0
12 1.2K 4s 3 1000 yes 1230 1 0
memcached@localhost:11211> randomset 1000 1000 1000 sample4
Random Generate. [....................]
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 0s 1 0 yes 0 0 0
12 1.2K 17s 3 2000 yes 1230 1 0
memcached@localhost:11211> randomset 1000 1000 1000 sample5
Random Generate. [....................]
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
9 600B 0s 1 0 yes 0 0 0
12 1.2K 21s 3 2655 yes 1575 20 0
最後は少々あふれてしまいましたが、1ページしかなかった時と比べて、3倍のデータを格納することができました。
ネームスペースごとの統計を見てみる
今回のデモの主要なところは以上ですが、ついでに memcached/memcached-cli の機能をもう少し紹介していきます。
detaildump
コマンドでは、ネームスペースごとの統計情報を見ることができます。
memcached@localhost:11211> detaildump
PREFIX sample4 get 0 hit 0 set 1000 del 0
PREFIX sample3 get 0 hit 0 set 3000 del 0
PREFIX sample5 get 0 hit 0 set 1000 del 0
PREFIX sample2 get 0 hit 0 set 1000 del 0
PREFIX sample1 get 0 hit 0 set 5000 del 0
もし、Memcached 起動時に統計情報の収集を有効にしていなかった場合、memcached-cli の detail on
コマンドで有効化できます。
逆に、detail off
コマンドで無効化もできます。
データを dump/restore してみる
memcached-cli では今のところ(〜v0.94)、dump をファイル保存する際は、バッチモードで動かす必要があります。
ので、一旦 \q
で対話モードを終えて下さい。
memcached@localhost:11211> \q
// シェル上で memcached-cli の dump_all コマンドを実行し、出力をファイルにリダイレクト
% memcached-cli localhost dump_all > dump-memd.txt
Dumping memcache contents
Number of buckets: 1
Number of items : 2655
Dumping bucket 12 - 2655 total items
% ll -h dump-memd.txt
-rw-r--r-- 1 key-amb 1522739515 2.6M 3 31 01:19 dump-memd.txt
% wc -l dump-memd.txt
5310 dump-memd.txt
dump が取れました。
では、別窓で動かしている Memcached を再起動します。
% memcached -m 4 -o slab_reassign,lru_crawler -D ":"
^CSignal handled: Interrupt: 2.
% memcached -m 4 -o slab_reassign,lru_crawler -D ":"
// 別窓で memcached-cli を立ち上げる
% memcached-cli localhost
Type '\h' or 'help' to show help.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
再起動したので、データが空っぽになっています。
これに、先ほど取った dump データをリストアします。
memcached@localhost:11211> restore_dump dump-memd.txt
...loaded 200 lines
...loaded 400 lines
...loaded 600 lines
...loaded 800 lines
:
...loaded 5000 lines
...loaded 5200 lines
Complete.
memcached@localhost:11211> display
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
12 1.2K 5s 3 2655 yes 0 0 0
無事にデータをリストアすることができました。
終わりに
以上、memcached-cliを用いて Memcached の Slabs Reassign と LRU Crawler の機能を体験してみました。
Memcached をお使いの方は、ぜひ memcached-cli をお試し下さい。
何かありましたら GitHub 上で Issue や Pull Request をお待ちしています。
それでは、Enjoy!
参考
-
memcached/protocol.txt at master · memcached/memcached
- 今回紹介した Memcached の機能の仕様を詳しく知りたい方はこちら。
-
Gotanda.pm #8 で memcached-cli について喋ってきた #gotandapm #memcached - weblog of key_amb
- Gotanda.pm #8 についての筆者のブログ記事です。発表したスライドも掲載しています。
脚注
-
余ったページを自動で開放する Slabs Automove というオプションもあります。 ↩