メモリ情報が欲しい
Linux でサーバ運用していて、時々トラブルを引き起こすメモリ不足。
ユーザ空間で動作しているプロセスが単にメモリを食いつぶしているだけならば、top コマンド等、様々なコマンドで原因となっているプロセスを特定し、対象のプロセスを中心に処理や実装を見なおせば、状況の改善につなげることができます
しかし、ディスクキャッシュや、カーネル管理配下のメモリブロック等、ユーザ空間からは見えにくいところの利用メモリが肥大化してしまい、
- 時折、ファイルシステムへの書込みが極端に遅くなる
などの事象が起こる場合があります
発生頻度もそれほど高くなく、「時折」というのが厄介で、その前後のメモリ状況が少しでも判れば、原因特定に役立つかもしれません
今回は、各種コマンドを使って得られる情報を、定期的に Zabbix へ登録し、その原因追求の一助としてみます
情報源
メモリに関する情報源として有名なものに、以下のようなモノが挙げられます
- free
- /proc/meminfo
- /proc/slabinfo
free コマンドで得られる情報は、Zabbix エージェントの標準キー [vm.memory.size] で得ることができるので、今回は割愛します
/proc/meminfo
free では得られない、用途別の占有容量情報が得られます。
各項目の意味については、中井さんのブログ記事 (http://d.hatena.ne.jp/enakai00/20110906/1315315488) が非常に解りやすく解説されています。
私自身も、得られた値を解釈するために、多数参考にさせていただきました
/proc/slabinfo
カーネル内管理の極小メモリブロック群 [slab] に関する用途別の情報が得られます。
多数のファイルを読書するサーバの場合、特に ‘inode_cache’ や ‘dentry’ 等が肥大化しやすく、速度に影響を与えることがあるようです
今回の記事では、slabinfo の出力結果を直接扱うのが面倒だったため、’slabtop’ コマンドの実行結果から、slab の情報を得るようにしました
監視・収集用スクリプト
シェルスクリプトと、ruby スクリプトの2枚構成にしました
おおよその流れは以下のような感じとなっています
- UserParameterに、キッカケ用のアイテム設定 [user.memslab.get] を追記
- シェルスクリプトが起動され、中で2重起動回避のチェックを実施後、ruby スクリプトをバックグラウンドで起動。Zabbix 側には、ruby スクリプト起動の成否を返す
- ruby スクリプト内で、メモリ/Slab の情報を収集
- ruby スクリプト内で、メモリ収集結果より、Zabbix のアイテム項目として必要になるものを、「ローレベルディスカバリ用アイテム [user.memslab.discovery]」の結果として、zabbix_sender でサーバへ送信
- Zabbix サーバ側では、ローレベルディスカバリアイテムの結果より、アイテム項目として必要になるものが判定され、各メモリ項目に応じたアイテムが自動生成される
- ruby スクリプト内では、一定時間(120秒)、アイテムの完成を待つ
- ruby スクリプト内で、メモリ収集結果の実値を、「ローレベルディスカバリ側で生成されたアイテム項目 [user.memslab[xxx,yyy]] の結果値として、zabbix_sender でサーバへ送信
- ruby スクリプト終了
スクリプト本体のダウンロードは↓こちら↓
memslab.sh memslab.rb
監視用テンプレート
このアイテムを利用したいホスト用のテンプレートを置いておきます (Zabbix 2.0.x 用)
- キッカケスクリプトを起動するためのアイテム [user.memslab.get]
- メモリ項目に応じたアイテム定義をするためのディスカバリ定義 [user.memslab.discovery]
- メモリ項目に応じたアイテム定義へ展開されるアイテムプロトタイプ [user.memslab[xxx,yyy]]
Zabbix 2.2/2.4 の場合は、xml を参考に、WebUIから設定を登録お願いします
memslab.xml
キッカケ用アイテムの UserParameter 定義
キッカケ用のアイテムのみ、UserParameter 定義が必要です
他の項目は、すべて「Zabbix トラッパー」タイプのアイテムとなっているので、agentd.conf への設定は不要です
UserParameter=user.memslab.get, /bin/sh /usr/share/zabbix/memslab.sh