weblog of key_amb

主にIT関連の技術メモ

Memcached に対話的にコマンドを実行できる "memcached-cli" を作った

Redis*1 には redis-cli というツールがあって、Redis サーバに接続して対話的にコマンドを発行して、結果を得ることができます。

Memcached*2 の場合、いい感じに使えるツールがなくて*3、必要なときはいつも TELNET でつないでコマンドを実行していました。

それもたまにしかやらないので、 set コマンドの打ち方とか、よく忘れて調べていました。(難易度高い)

…というわけで、そういう操作を簡単に対話的に実行できるものを作りました。

github.com

CPAN にも公開していますので、 cpanm App::Memcached::CLI でインストールできます。
これに script/memcached-cli というスクリプトを同梱しています。

まだすべてのコマンドを網羅できたわけではないですが((執筆時点の App-Memcached-CLI のバージョンは v0.5.3))、現時点でも、特にサーバ運用管理者にとってはそこそこ便利なものになっているのではないかと思います。

以下、memcached-cli の使い方の紹介です。

対話モード

接続

接続先を -a|--addr オプションか、第1引数で渡してください。

% memcached-cli memd.foo.local:11211
% memcached-cli -a memd.foo.local    # デフォルト 11211 ポート
% memcached-cli                      # localhost に接続

接続すると下のように対話モードに移行します。

memcached@127.0.0.1:11211> 

get/set

特に違和感なく使えるかと思います。

memcached@127.0.0.1:11211> get foo
Not found - foo
memcached@127.0.0.1:11211> set foo WHAAH!!!
OK
memcached@127.0.0.1:11211> get foo
       key:    foo
     value:    WHAAH!!!
     flags:    0
    length:    8

expire (exptime)を指定する場合、value の後に秒数で渡してください。 デフォルトでは expire 0 で set するので、 expire しません。

memcached@127.0.0.1:11211> set short WRYYY!!! 5
OK
memcached@127.0.0.1:11211> get short
       key:    short
     value:    WRYYY!!!
     flags:    0
    length:    8
# 5秒後
memcached@127.0.0.1:11211> get short
Not found - short

expire の後ろに flags (任意の非負整数)を渡すこともできます。

delete

KEY 指定で delete できます。

memcached@127.0.0.1:11211> delete foo
OK
memcached@127.0.0.1:11211> get foo
Not found - foo

memcached-tool からの移植機能

Memcached 付属の memcached-tool *4はスラブのクラスごとの統計情報表示など、運用管理者にとって便利な機能を備えています。

一部を除いて memcached-cli に移植しましたので、対話的に実行することができます。

memcached@127.0.0.1:11211> display
  #  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
  1      96B         0s       1       0     yes        0        0    0
 18     4.4K         0s       1       0     yes        0        0    0
 20     6.9K         6s       1       2     yes        0        0    0
 22    10.8K         6s       1       1     yes        0        0    0
 24    16.9K         6s       1       1     yes        0        0    0
 26    26.5K         0s       1       0     yes        0        0    0
  :
memcached@127.0.0.1:11211> \d # 同じ

display はよく打ちそうだなと思ったので、 \d というエイリアスを作ってみました。

対話モードの終了

\q または quit または exit で終了します。

その他の機能

help または \h で実装されているコマンドが表示されます。
\h <command> で一部のコマンドは、より詳しい情報が見れます。

memcached@127.0.0.1:11211> \h

[Available Commands]
\h, help                    Show help (this)
\v, version                 Show server version
\q, quit, exit              Exit
\d, display                 Display slabs info
\s, stats                   Show stats
\c, settings, config        Show settings
\cd, cachedump, dump        Show cachedump of specified slab
\dd, detaildump             Show detail dump
detail                      Enable/Disable detail dump
get                         Get data of KEY
set                         Set data with KEY, VALUE
delete                      Delete data of KEY
flush, flush_all            Invalidate whole data

Type \h <command> for each.

memcached@127.0.0.1:11211> \h cachedump
(略)

memcached-tool から移植したのは display に加えて stats, settings あたりですね。

その他、運用管理向けの機能として、cachedump を実装しました。 cachedump <CLASS> [<SIZE>] で特定スラブのアイテムのキーと expire を <SIZE> の個数だけ一覧できます。デフォルトの <SIZE> は20にしました。

また、下の記事で紹介されていたネームスペースごとの統計も detaildump で表示できるようにしました。

Cache::Memcached(::Fast) のネームスペースは最後に区切り文字をいれた方が良い話とネームスペース毎に統計を取る方法 - blog.nomadscafe.jp

この統計情報を起動時に有効化してない場合、有効化するには stats detail on を叩かないといけません。
ので、それも detail on で、できるようにしました。
ついでに detail off で無効化できるようにしました。

バッチモード

更に、これらを対話モードだけでなく、バッチで実行できたら、より便利だなと思ったので、 v0.4 でできるようにしました。
redis-cli もバッチ実行できますし。

これによって、 memcached-tool から移植した機能については memcached-tool と同じようにコマンドラインから実行できるようになりました。

$ memcached-cli localhost display
  #  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
  1      96B         0s       1       0     yes        0        0    0
 18     4.4K       164s       1       1     yes        0        0    0
 24    16.9K       164s       1       2     yes        0        0    0

# ※ `\` で始まるエイリアスは適当にエスケープなりしてあげる必要があります。
$ memcached-cli localhost \\cd 18
ITEM memcached-roaster:random-generate1:data54 [3724 b; 1458806126 s]

flush_all または flush を実行すると、全てのデータが無効化される(次回GET時に expired 扱いになる)ので、気をつけて下さいね。

$ memcached-cli localhost flush_all
OK

実装したコマンドは全て、対話モードでもバッチモードでも、どちらでも実行できます。

今後

もうあまり困ってはいないのですが、Memcached のその他のコマンドも少しずつ追加していこうかなと思っています。

あと、ランダムにデータ生成するようなコマンドも作ろうかなと思っていたりします。*5

何かあれば GitHub 上で Issue や PR をいただければ、歓迎いたします。

余談

もっと早くこれを作っておけば良かったという感はあります。

なんで Perl なのかというと、memcached-tool が Perl で書かれていて、それを参考にしながら移植したからです。*6

脚注

*1:http://redis.io/

*2:http://memcached.org/

*3:最近探したところ、いくつか見つかりましたが、ほしい感じのはなかったです。

*4:memcached/memcached-tool at master · memcached/memcached · GitHub

*5:テスト用に https://github.com/key-amb/perl5-App-Memcached-Roaster というチープなツールを作りました。

*6:https://github.com/key-amb/perl5-App-Memcached-Tool という memcached-tool のポーティングも作りました。