分散Key/Valueストア,Kaiを使ってみよう!

第4回 Kaiの詳細(2)―Kaiの設定をチューニングする

この記事を読むのに必要な時間:およそ 4 分

プロセス数とソケット数の設定

ここでは,Kai設定ファイル内のmemcache_max_processes,rpc_max_processes,max_connectionsについて説明します。

これらの設定値は,クライアントからの最大同時接続数を制限し,ネットワークのトラフィックを調節するために使用します。もし,設定を変更するのであれば,なるべく,以下の条件を守るようにしてください。

  • memcache_max_processes = rpc_max_processes / N
  • rpc_max_processes = クラスタを構成する全ノード数 * memcache_max_processes
  • max_connections = memcache_max_processes * N + α

Kaiは,デフォルトの設定ファイルを変更せずに起動すると,約70個のErlangプロセスを起動します。その内の約40個が,TCP/IP接続を待ち受ける為に待機しているプロセスです。待機中のプロセス数は,設定ファイルの memcache_max_processes,rpc_max_processes で設定を行う事ができます。

それぞれの意味は,以下の通りです。関連項目である,max_connections も共に説明します。

設定名説明
memcache_max_processesmemcachedクライアントからの同時接続数を設定します。
大きい値を設定すると同時接続数は増えますが,ノード間通信が増えるため,クラスタ全体の負荷が上がります。
また,rpc_max_processes,max_connectionsに大きな値を設定する必要があります。
rpc_max_processesクラスタを構成する他のノードからの同時接続数を設定します。
max_connections他のノードへの同時接続数を設定します。
ノード間通信では,Kai の性能を引き出すために,一つのノードに対して複数接続を行う事もあります。
memcache_max_processes,rpc_max_processesとは異なり,ここで設定した値はプロセス数とは関係ありません。

ノードにmemcachedクライアントが1つ接続すると,N個分(Nは,Quorumの設定値)⁠クラスタ内の他のノードへ接続が発生します。さらに,定期的に自動で行なわれるノード間通信や,Erlang VMのコンソールから手動で行なうノード間通信を考慮すると,余分に幾つか接続数を確保しておく必要があります。よって,⁠max_connections = memcache_max_processes * N + α」となります。

また,ノード間通信で接続される側のノードを考慮すると,クラスタを構成する他のノードにmemcachedクライアントが1つ接続すると,自ノードへ1つ接続が発生する可能性があります。よって,⁠rpc_max_processes = クラスタを構成する全ノード数 * memcache_max_processes」となります。

データの取得・保存の際は,N個のノード全てがレスポンスを返す必要はないため,rpc_max_processesに少々低い値を設定しても,それほどレスポンス速度が低下する事はありません。しかし,Kai は,ノード間通信の転送を行なわないので,rpc_max_processes に大きな値を設定したとしても、ネットワーク・トラフィックが増える事はありません。

当たり前の事ですが,クラスタを構成するノードの memcache_max_processes の総数が,クラスタ全体の memcached クライアント同時接続数となります。クラスタにノードを追加する際は,ノード間通信によるネットワーク・トラフィックを軽減するために,ノードごとの memcache_max_processes を減らせないか検討してください。

なお,これらの設定値は,最適な値を見つける事が難しいため,検証環境をご用意いただき,実際に負荷を掛けながら希望するパフォーマンスに達するまでチューニングし続けてください。

例として,ストレージにetsを選んだ際に,以下の設定値で良いパフォーマンスが出たとの報告がありますので参考にしてください。

設定名設定値
memcache_max_processesrpc_max_processes / N
rcp_max_processes120
max_connections256

これらの設定値に大きな値を設定すると,EMFILEエラーが発生する事があります。

Erlang VMは,OSからは一つのプロセスとして扱われているため,Kaiが大量にファイル・ディスクリプタを消費すると,OSからは一つのプロセスが大量にファイル・ディスクリプタを消費していると見なされます。

よって,これらの設定値に大きな値を指定する際は,limitコマンドやsysctlコマンド,OSの設定ファイルを編集するなどして,一つのプロセスが扱えるファイル・ディスクリプタの数を増やす必要があります。

設定方法は,各プラットフォームごとに異なります。以下に例を挙げておきますが,詳しくは,ご利用のプラットフォームのマニュアルなどをご参照ください。

プラットフォーム設定方法
Linux"/etc/security/limits.conf"を編集し,Kai実行ユーザのnofileに大きな値を設定してください。
必要があれば,"/etc/sysctl.conf"を編集し,fs.file-maxに大きな値を設定してください。
*BSD"/etc/login.conf"を編集し,Kai実行ユーザのログインクラスのopenfilesに大きな値を設定してください。
必要があれば,"/etc/sysctl.conf"を編集し,kern.maxfilesとkern.maxfilesperprocに大きな値を設定してください。

また,スループットが高くなる事が予想される場合は,ソケットバッファのサイズを増やす事で,Kaiの性能を引き出す事ができます。

こちらも,設定方法が各プラットフォームごとに異なります。以下に例を挙げておきますが,詳しくは,ご利用のプラットフォームのマニュアルなどをご参照ください。

プラットフォーム設定方法
Linux"/etc/sysctl.conf"を編集し,net.core.rmem_max,net.core.wmem_max,net.core.optmem_maxに大きな値を設定してください。
*BSD"/etc/sysctl.conf"を編集し,net.inet.tcp.sendspace,net.inet.tcp.recvspace,kern.ipc.maxsockbufに大きな値を設定してください。

前述で,ネットワーク・トラフィックに関してのみ説明しましたが,プロセスを大量にSpawnする事で発生する負荷には触れませんでした。

ご存知の方も多いかとは思いますが,Erlangにはプロセスを大量にSpawnしても負荷が低いという利点があります。このため(だけではありませんが)⁠Erlangで作られたサーバは,プログラムの設計やチューニング次第で,C10K問題を比較的簡単に回避する事が可能です。

Kaiでプロセス数を調節しているのは,プロセス負荷を下げる事が目的ではなく,ネットワークトラフィックを下げる事が目的です。

なお,ErlangプロセスやC10K問題のより詳しい内容については以下をご参照ください。

著者プロフィール

幾田雅仁(いくたまさひと)

酪農,ゴルフのキャディさん,某大手パソコン通信の下請け,某大手ポータルサイトなどを経て,決済代行を生業とする株式会社ゼロに入社。

p2p?なにそれ?美味しいの?の状態で,Erlang 分散処理勉強会に参加し,Kai のプレゼンを見て感銘を受け,無理矢理開発に参加し,現在に至る。