memcachedの活用と運用 実践編

第1回memcachedの起動オプションを把握しよう

はじめに

株式会社ライブドア 開発部 長野です。ライブドアに入社する以前は株式会社ミクシィにてmixiの運用に携わっておりました。また、2年前の2008年には、このgihyo.jp上において、memcachedの基本的な使い方やミクシィでの活用方法について連載させて頂いていました。今回の連載では前回から2年間の間にあったmemcachedのアップデートに関することや、大規模なWebサイトでのmemcachedの運用、実践的な活用方法について解説していきます。

memcachedとは

memcachedは、高性能な分散メモリキャッシュサーバです。データベースへの問い合わせ結果を一時的にmemcachedへキャッシュすることで、データベースへのアクセス回数を減らし、動的なWebアプリケーションの高速化やスケーラビリティの向上を実現できます。memcachedを利用しているWebサイト・サービスとしてはlivedoorやmixi、はてな、Facebook、Twitterなどが挙げられ、また最近盛り上がりを見せるソーシャルアプリケーションでも、サービスの性能を向上させる重要な役割を果たしています。

memcachedは元々、LiveJournalを運営していたDanga Interactive社においてBrad Fitzpatrick氏が中心となって開発されたオープンソースソフトウェアですが、現在ではさまざまな企業からエンジニアが参加するコミュニティで開発が続けられています。

memcachedの概要や基本的な利用方法については以前の連載memcachedを知り尽くすをご覧ください。

メジャーアップデートしたmemcached

前回の連載時、2008年7月のmemcachedの最新バージョンは1.2.5でしたが、2010年8月現在のmemcahedの最新バージョンは1.4.5となり、1.2系から1.4系へのメジャーアップデートが行われています。

 主なmemcachedのバージョンとリリース時期
バージョン年月
1.2.52008年4月
1.2.62008年7月
1.3.2(開発バージョン)2009年4月
1.2.8(1.2系最終アップデート)2009年4月
1.4.02009年7月
1.4.12009年8月
1.4.42009年11月
1.4.52010年4月

1.4系で新しく追加された主な機能しては

  • バイナリプロトコルの導入
  • マルチスレッドの標準化
  • 統計の強化

などが上げられます。この1.4系の機能の詳細については前坂徹氏の連載memcached 1.4の到来が参考となります。ここではバージョン1.2.5と最新の1.4.5の起動オプションを比較しながら、新しく追加された機能や実際の運用で用いられる起動オプションについて説明します。

1.2系と1.4系の起動オプションの違い

まず、memcachedの起動オプションの一覧(ヘルプ)を確認しましょう。memcachedのヘルプを出力するには、⁠-h」オプションを使います。

$ memcached -h
memcached 1.x.x
-p <num>      TCP port number to listen on (default: 11211)
-U <num>      UDP port number to listen on (default: 0, off)
(以下省略)

ヘルプの1行目にバージョンが出力され、2行目以降がオプションとその説明です。では1.2.5と1.4.5のヘルプを表示して比較します。

1.2.5のオプション一覧
memcached 1.2.5
-p <num>      TCP port number to listen on (default: 11211)
-U <num>      UDP port number to listen on (default: 0, off)
-s >file>     unix socket path to listen on (disables network support)
-a <mask>     access mask for unix socket, in octal (default 0700)
-l <ip_addr>  interface to listen on, default is INDRR_ANY
-d            run as a daemon
-r            maximize core file limit
-u <username> assume identity of <username> (only when run as root)
-m <num>      max memory to use for items in megabytes, default is 64 MB
-M            return error on memory exhausted (rather than removing items)
-c <num>      max simultaneous connections, default is 1024
-k            lock down all paged memory.  Note that there is a
             limit on how much memory you may lock.  Trying to
             allocate more than that would fail, so be sure you
             set the limit correctly for the user you started
             the daemon with (not for -u <username> user;
             under sh this is done with 'ulimit -S -l NUM_KB').
-v            verbose (print errors/warnings while in event loop)
-vv           very verbose (also print client commands/reponses)
-h            print this help and exit
-i            print memcached and libevent license
-b            run a managed instanced (mnemonic: buckets)
-P <file>     save PID in <file>, only used with -d option
-f <factor>   chunk size growth factor, default 1.25
-n <bytes>    minimum space allocated for key+value+flags, default 48
1.4.5のオプション一覧
memcached 1.4.5
-p <num>      TCP port number to listen on (default: 11211)
-U <num>      UDP port number to listen on (default: 11211, 0 is off)
-s <file>     UNIX socket path to listen on (disables network support)
(中略)
-vvv          extremely verbose (also print internal state transitions)
-h            print this help and exit
-i            print memcached and libevent license
-P <file>     save PID in <file>, only used with -d option
-f <factor>   chunk size growth factor (default: 1.25)
-n <bytes>    minimum space allocated for key+value+flags (default: 48)
-L            Try to use large memory pages (if available). Increasing
             the memory page size could reduce the number of TLB misses
             and improve the performance. In order to get large pages
             from the OS, memcached will allocate the total item-cache
             in one large chunk.
-D <char>     Use <char> as the delimiter between key prefixes and IDs.
             This is used for per-prefix stats reporting. The default is
             ":" (colon). If this option is specified, stats collection
             is turned on automatically; if not, then it may be turned on
             by sending the "stats detail on" command to the server.
-t <num>      number of threads to use (default: 4)
-R            Maximum number of requests per event, limits the number of
             requests process for a given connection to prevent
             starvation (default: 20)
-C            Disable use of CAS
-b            Set the backlog queue limit (default: 1024)
-B            Binding protocol - one of ascii, binary, or auto (default)
-I            Override the size of each slab page. Adjusts max item size
             (default: 1mb, min: 1k, max: 128m)

memcached 1.2.5がオプションが20個あるのに対して、1.4.5では28個と1.5倍近くに増えています。追加されたオプションは1.4系でサポートされたマルチスレッドや性能に関する設定や、統計、バイナリプトココルに関するものが多くを占めています。

 追加されたオプション
オプション名内容
-vvv詳細ログモードが1段階追加
-Lメモリ確保にラージページを利用する
-Dキャッシュのキーのうちネームスペースを分ける文字列。ネームスペースごとに詳細な統計が取得できる
-tスレッド数
-R1度に行うリクエストの処理の上限値
-CCASを無効にする
-b接続のキュー数
-Bテキスト・バイナリプロトコルの判定
-I最大キャッシュオブジェクトサイズ

実際の運用で利用する主な起動オプションの解説

-p TCPポート

memcachedがListenするTCPのポートを指定します。最も基本的な起動オプションの1つです。指定しない場合デフォルトの11211が利用されます。11211以外を利用する場合、-pに続けてポート番号を入力します。

$ memcached -p 12345

もしTCPを利用しない場合、ポート番号に0を指定します

$ memcached -p 0

-U UDPポート

memcachedはTCPだけではなく、UDPでも利用することができます。デフォルトではTCPと同じポートでUDPもListenします。TCPのポートが指定されていない場合、デフォルトの11211となり、別のポートが指定されていれば、そのポート番号が使われます。

$ memcached -p 12345

上記のように -U を指定しない場合、TCPのポートで指定した12345が利用されます。TCPが11211でUDPが12345をListenする場合、

$ memcached -p 11211 -U 12345

とします。UDPを使わない場合、-U に0を指定するのですが、その際には必ずTCPの -p オプションも指定する必要があります。

$ memcached -p 11211 -U 0

多くの場合、UDPは利用されていないと思いますので、-U に0を指定しUDPを停止することも考えても良いかもしれません。

-m メモリサイズ

キャッシュの最大サイズです。OSが32bitの場合には上限は2GBまでとなりますが、64bit OSの場合では制限はありません。ただし、性能に影響するのでswapしないようにしましょう。

16GBのキャッシュ領域を確保するには

$ memcached -m 16000

とします。もし32bitのOSでメモリを2GB以上使いたい場合は、複数のmemcachedをportを変更して起動するなどの対応が必要となります。

-c 接続数

memcachedに対する最大の接続数を指定します。デフォルトは1024で、1024未満を指定しても1024となります。また、1024よりも大きな値にする場合はroot権限が必要となります。

$ memcached -c 32768

最大の接続数を超えた場合、memcached側に「Too many open connections」などのエラーが出力されます。memcachedに対する接続数は、statsコマンドでも確認ができるので、監視システム等でモニタリングを行うことをお勧めします。

設定した接続数はOSリソースの制限を行うrlimitの値としてのみ使われるので、大きめの値を宣言しても、すぐに多くのリソースを占有することはありません。

-u 実行ユーザ

memcachedの実行ユーザを切り替えます。memcachedの実行に時にroot権限が必要となります。memcachedはroot権限では動作しないように設計されていますので、-c オプションで同時接続数を増やしたときなどはこのオプションで実行ユーザを切り替える必要があります。

$ memcached -c 32768 -u nobody

-f スラブサイズの決定係数

memcachedにキャッシュしたデータは、スラブと呼ばれるデータ格納領域に保存されます。スラブは保存するキャッシュオブジェクトのサイズごとにいくつか作られ、同じサイズのキャッシュデータを同じスラブに保存するように設計されています。このスラブサイズを決定に大きく影響するのが -f オプションです。

デフォルトの値は1.25です。スラブの一覧とそのサイズはmemcachedを -vv オプション付きで起動した際や、統計出力を行うstatsコマンドなので参照することができます。デフォルトの係数のまま -vv オプション付きで起動すると

$ memcached
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       120 perslab    8738
slab class   3: chunk size       152 perslab    6898
slab class   4: chunk size       192 perslab    5461
slab class   5: chunk size       240 perslab    4369
slab class   6: chunk size       304 perslab    3449
slab class   7: chunk size       384 perslab    2730
(省略)

という出力が得られます。最小のスラブが96Byteから始まって、1.25倍の120Byte、さらに1.25倍の152Byteとサイズが大きくなって行くのがわかります。1.25倍より少しサイズが異なるのは、スラブのサイズを8Byteの倍数にあわせているためです。

もし、memcachedに数百Byte程度の小さいキャッシュオブジェクトを中心に入れるのであれば、1.25をもっと小さくすると効率が良くなるかもしれません。次は -f を 1.1で起動した際のスラブサイズです。

$ memcached -f 1.1
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       112 perslab    9362
slab class   3: chunk size       128 perslab    8192
slab class   4: chunk size       144 perslab    7281
slab class   5: chunk size       160 perslab    6553
slab class   6: chunk size       176 perslab    5957
slab class   7: chunk size       200 perslab    5242

スラブサイズの上昇が緩やかになっているため、よりキャッシュオブジェクトのサイズと近いサイズのスラブを選択することができるようになります。結果としてスラブを有効活用できるようになります。

memcachedのメモリストレージについては、⁠memcachedを知り尽くす」の連載の第二回memcachedのメモリストレージを理解するに詳しく説明があるので参考にしてください。

ただし、どのようなサイズのキャッシュオブジェクトが増加して行くのかは予想しにくく、よほどの場合でない限り、-f は指定することはないと考えています。

-t スレッド数

1.4系から追加されたオプションです。1.4.0からマルチスレッドでの動作が前提となっています。そのスレッド数をここで指定します。以下のように -t に 1を指定することでシングルスレッドでの動作も可能です。

$ memcached -t 1

スレッド数のデフォルトは4です。マルチスレッドによって一度のコマンドで複数のキャッシュオブジェクトを取得する際に若干の高速化が期待できるようです。

-C CASの無効化

memcachedはトランザクションのサポートをしていませんが、CASを使うことでキャッシュの更新に一貫性を保つことができます。CASを利用するクライアントは、キャッシュオブジェクトを取得する際に、getsコマンドを使い、ID(CAS値)を取得します。データを更新する際にはクライアントはそのCAS値も送信します。memcached側ではCAS値が変わっていなければデータを保存する処理を行います。

このようにCASを使うことで簡単に一貫性を保つことができますが、 CASを実現するためにmemcachedは64bitのIDを1つ1つのキャッシュオブジェクトにつける必要があり、そのために1つのキャッシュにつき8Byteのデータ領域が確保されます。-C オプションを指定することでCAS機能を無効にし、8ByteのCAS領域もキャッシュのために利用できるようになります。

$ memcached -C

-b 接続のバックログ

OSレベルでのTCP接続の確立はしたが、アプリケーションレベルのmemcachedで処理待ちとなっている接続キューの最大数です。負荷が大きいmemcachedサーバの場合には変更が必要となるかもしれません。デフォルトは1024です。ただし、Linuxでは「/proc/sys/net/core/somaxconn」で定義される値以上に設定することはできません。

Linuxでのsomaxconnのデフォルトは128なので、接続キュー数を増やすには、まずsomaxconnのチューニングが必要となります

$ echo 1024 > /proc/sys/net/core/somaxconn

somaxconnの変更後memcachedの再起動が必要です

-I 最大キャッシュオブジェクトサイズ

長らくmemcachedに格納できるキャッシュのオブジェクトサイズの最大は1MBに固定されていましたが、バージョン1.4.2から変更ができるにようになっています。変更できるサイズの幅は 1024Byteから128MBです

以下は512KBに制限をする例と、2MBに拡張する例です。

$ memcached -I 512k # 512KB
$ memcached -I 2m

設定の確認

memcachedの1.4系からは、起動後に外部からmemcachedがどのようなオプションで起動されているか、⁠stats settings」コマンドを発行することで確認することができます。

$  telnet localhost 11211
stats settings
STAT maxbytes 1073741824
STAT maxconns 1024
STAT tcpport 11211
STAT udpport 0
STAT inter NULL
STAT verbosity 0
STAT oldest 0
STAT evictions on
STAT domain_socket NULL
STAT umask 700
STAT growth_factor 1.10
STAT chunk_size 48
STAT num_threads 4
STAT stat_key_prefix :
STAT detail_enabled no
STAT reqs_per_event 20
STAT cas_enabled no
STAT tcp_backlog 1024
STAT binding_protocol auto-negotiate
STAT auth_enabled_sasl no
STAT item_size_max 1048576
END

バージョン 1.4.5では stats settingsの表示のうち、maxbytesの値が正しくないバグがあるようです。statsコマンドのlimit_maxbytesで正しい値が参照できます。

まとめ

今回は、memcached のバージョン 1.2.5から1.4.5へアップデートで追加されたオプションの紹介、さらにWebアプリケーションの運用でよく利用されるmemcachedのオプションの説明をしました。次回はmemcachedを運用する上で気になる脆弱性やその対策について書く予定です。

おすすめ記事

記事・ニュース一覧