はじめに
こんにちは、システム本部新興メディアシステム1部スマイティ担当の山下です。
みなさま、バッチ処理のリソース監視はやっていますか?
今回は「process-exporter」というPrometheusのExporterを使って、スマイティのバッチ処理のリソース状況をGrafanaで可視化した話をしようと思います。
process-exporterとは
process-exporter は時系列データベースであるPrometheusにプロセスのメトリクスを渡すためのExporterです。
PrometheusのExporterはミドルウェアの情報やサーバーのリソース情報を出力するものが多いですが、process-exporterは実行したサーバー内で動くプロセスごとのCPU使用率やメモリ使用量といった情報を出力します。
具体的にはlinuxの/proc
配下の情報を出力しているようです。
環境
今回の環境は以下のようになってます。
- process-exporter 0.7.10
- prometheus 2.7.1
- grafana 8.1.2
- process-exporterを動かすバッチサーバー CentOS 7.2
インストール
公式Github を参考にインストールします。
他の一般的なPrometheusのExporterと同様に情報を渡したい方のサーバーで動作させます。なので今回はスマイティのバッチサーバーにインストールしています。
ここでは releases からlinux-amd64版のパッケージを取得してインストールしています。
/usr/local/prometheus
配下にファイルを置いて/usr/bin/process-exporter
にバイナリファイルへのシンボリックリンクを作成しています。
cd /tmp wget https://github.com/ncabatoff/process-exporter/releases/download/v0.7.10/process-exporter-0.7.10.linux-amd64.tar.gz tar xvzf process-exporter-0.7.10.linux-amd64.tar.gz sudo mkdir -p /usr/local/prometheus sudo cp -r /tmp/process-exporter-0.7.10.linux-amd64 /usr/local/prometheus sudo ln -s /usr/local/prometheus/process-exporter-0.7.10.linux-amd64/process-exporter /usr/bin/process-exporter
設定ファイルとなるconfig.yml
も作成しておきます。
sudo touch /etc/process-exporter/config.yml
インストールしたらService化して常駐させます。
まずService化のために必要なファイルを作成します。
sudo touch /usr/lib/systemd/system/process-exporter.service sudo vi /usr/lib/systemd/system/process-exporter.service sudo touch /etc/sysconfig/process-exporter sudo vi /etc/sysconfig/process-exporter
/usr/lib/systemd/system/process-exporter.service
の中身は以下です。
[Unit] Description=Process Exporter for Prometheus [Service] User=root Type=simple EnvironmentFile=/etc/sysconfig/process-exporter ExecStart=/usr/bin/process-exporter $OPTIONS KillMode=process Restart=always [Install] WantedBy=multi-user.target
/etc/sysconfig/process-exporter
の中身は以下です。
OPTIONS='--config.path /etc/process-exporter/config.yml --web.listen-address=:9256 --web.telemetry-path="/metrics"'
作成したファイルを読み込ませて常駐させます。
sudo systemctl daemon-reload sudo systemctl enable process-exporter.service sudo systemctl start process-exporter
インストールは以上です。
ここでは.service
ファイルなどを自分で作りましたが、 公式リポジトリ内 にもデフォルトのファイルは配置されていますのでそれをベースにしてもいいと思います。
デフォルトの設定ファイル もあり、すべてのプロセスのメトリクスを出力する設定になっています。
設定
config.ymlに書きます。
スマイティでは以下のような設定にしています。
process_names: - name: "php_symfony_batch_{{.Matches.BatchName}}" exe: - php cmdline: - 'php\s+.*\s+(?P<BatchName>batch:\S+).*' - name: "php_batch_{{.Matches.FileName}}" exe: - php cmdline: - 'php\s+.*/(?P<FileName>[^/ ]+\.php).*' - name: "sh_{{.Matches.FileName}}" cmdline: - '.*/(?P<FileName>[^/ ]+\.sh).*'
process-exporterは、例えば物理メモリ使用量であれば次のようなメトリクスを出力します。
namedprocess_namegroup_memory_bytes{groupname="xxx",memtype="resident"} (value)
configのname
は、このgroupname
のxxx
に入る値になります。
すべてのプロセスのメトリクスを出力すると多すぎるので、スマイティでは自分たちで作ったバッチのプロセスに対象を絞っています。
絞る条件は、comm
, exe
, cmdline
の3つの方法のいずれかで指定します。複数指定した場合は全ての条件にマッチしたプロセスに絞られます。
cmdline
は正規表現で抽出します。実行ファイルの引数まで含めて完全一致している必要があります。
正規表現で (?P<name>)
の括弧内にマッチした文字列はname
で {{.Matches.name}}
で参照できます。
exe
は実行ファイル名だけの一致で抽出します。
条件はcmdline
だけで指定するより、exe
やcomm
を先に記述して限定したほうがパフォーマンスがあがるそうです。
スマイティではPHP+Symfonyを採用しており、バッチは例えば以下のようなコマンドで実行しています。
php bin/console batch:batch-name-hogehoge --opt=xxx --env=prod
上記のコマンドは1つ目のname
の条件にマッチします。
- name: "php_symfony_batch_{{.Matches.BatchName}}" exe: - php cmdline: - 'php\s+.*\s+(?P<BatchName>batch:\S+).*'
上記のコマンドのname
は php_symfony_batch_batch:batch-name-hogehoge
となります。
これがメトリクスのgroupname
に入り、次のようなメトリクスが出力されることになります。
namedprocess_namegroup_memory_bytes{groupname="php_symfony_batch_batch:batch-name-hogehoge",memtype="resident"} (value)
※なお、この設定ではコマンドの--opt=xxx --env=prod
の部分はname
に含めていないため、何が指定されていても同じメトリクスとして出力されます。
同様に、2つ目のname
では素のphpのプロセスに、3つ目のname
では.shのプロセスに、それぞれマッチさせる条件を書いています。
もし、動的にファイル名やパスを変えてphpやshを実行するシステムがあるとメトリクスが爆発的に増えてPrometheusが悲鳴をあげるので注意しましょう。その場合はそれらを除外するか同一視するような条件を書けばOKです。
設定ファイルを変えたらprocess-exporterを再起動して読み込ませます。
sudo systemctl restart process-exporter
Prometheusにメトリクスをためる
バッチサーバーでprocess-exporterが出力するメトリクスをPrometheusのスクレイピング対象とします。
方法は他の一般的なPrometheusのexporterと同じなので割愛します。
Grafanaで可視化
以下のようにバッチプロセスごとのCPU使用率やメモリ使用量をグラフ化できました。
※バッチ名は伏せてあります。
色分けされている凡例のところがconfigのname
、すなわち各バッチになります。
グラフをだすためのクエリ(PromQL)は今回詳しく触れませんが例えばメモリ使用量の方だと次のようになっています。
sum(namedprocess_namegroup_memory_bytes{instance="$node:9256",memtype="resident"}) by (groupname) > (50 * 1024 * 1024)
$node
はバッチサーバーのホストが入る変数です。
50MB以上に限定して表示しているのは凡例に表示されるバッチが多すぎると見辛かったからです。メモリ使用量を気にするなら50MB以上使っているバッチを見るだけで十分と判断しました。
何に使えるのか?
バッチリリース後にメモリやCPUのリソースを使いすぎていないか確認できる
バッチごとにメモリ使用量をログに出力して確認するよりは楽なのではないでしょうか?
もちろん本当にサーバーリソースを逼迫するリスクが高いものは本番で動かす前にも検証は必要です。
バッチのリソース消費量の変化をグラフで観察できる
時系列データなので言わずもがなです。
サーバーのリソースが逼迫してきたときに、新サーバーに処理をうつすバッチを吟味できる
サーバー全体のCPUやメモリのリソース状況みるだけでは、どのバッチを…というところまでは検討できませんが、バッチごとに可視化されていれば可能です。
他の時系列データとバッチのグラフを俯瞰することで新たな発見ができるかもしれない
Grafanaは同じタイムスパンで複数のグラフを俯瞰するのに適したUIになっており、バッチプロセスのリソース状況もそこに並べることで他の時系列データとタイムスパンを合わせて眺めることが容易になります。
1つ前の項目と被りますが、サーバー全体のCPU使用率とバッチプロセスごとのCPU使用率を俯瞰すれば、何のバッチがCPUを使っているのか一目瞭然かもしれません。
他には例えば、バッチはDBに書き込む処理を行なっていることも多いと思います。
ならMasterDBのロードアベレージとバッチ処理の時系列データを並べて眺めるとMDB負荷の原因に気づくこともあるかもしれません。
サーバー全体のCPU使用率、メモリ使用量、ロードアベレージといったメトリクスは node_exporter で取得できます。
Grafanaでダッシュボードを作ってグラフを並べておくと良いでしょう。
総括
バッチ処理のリソース状況の可視化はサービスに必須とは言いませんが、調査を楽にしてくれるもの、新しい気づきを提供してくれるもの、だと思います。
また、process-exporterはもちろんプロセスの死活監視にもつかえます。そちらは他のツールですでに行なっていることも多いと思われますので今回は触れませんでした。
カカクコムでは、ともにサービスをつくる仲間を募集しています!
カカクコムのエンジニアリングにご興味のある方は、ぜひこちらをご覧ください!