mackerel-plugin-varnishのグラフを読めるようになりたい
Varnishをやっていて悩むことがよくあって
mackerel-plugin-varnishを使ってみようと思い立ってすぐ入れたけど
あまりリファレンスややってみた記事がヒットしなかったのでざっくりまとめました😁
キャッシュサーバやVarnishを自分で構築するのも監視するのも初めてなので
お手柔らかにお願いします...🙏
今回使った環境
- CentOS7.5
- mackerel-agent 0.56.0
- Varnish 6.0
- プロキシ先は同ホストに立てたPHPのWebアプリケーション
- 今回はあまり重要ではないので詳細は割愛します
Varnishとは?
Varnish HTTP Cache — Varnish HTTP Cache
キャッシュするHTTPリバースプロキシ(直訳)で
6.0.0は2018年3月にリリースされたものです
語り始めると長いのでVarnishについては気が向いたら別で書きます
mackerel-plugin-varnish
VarnishにはvarnishstatというVarnishのパフォーマンスを見れる便利ツールがあり
mackerel-plugin-varnishはvarnishstatの出力した結果をMackerelへ投稿してくれます
varnishstatはVarnishをインストールすると一緒にインストールされます
varnishstatを実行するとこのような画面になります
引数に-1で今の瞬間のデータ表示、つけない場合は最新のものが常に表示されます
※長いので関係する箇所だけ抜粋しました
# varnishstat -1 MAIN.client_req 103036 10.97 Good client requests received MAIN.backend_req 10 0.00 Backend requests made MAIN.backend_conn 4 0.00 Backend conn. success MAIN.backend_unhealthy 0 0.00 Backend conn. not attempted MAIN.backend_busy 0 0.00 Backend conn. too many MAIN.backend_fail 0 0.00 Backend conn. failures MAIN.backend_reuse 6 0.00 Backend conn. reuses MAIN.backend_recycle 10 0.00 Backend conn. recycles MAIN.backend_retry 0 0.00 Backend conn. retry MAIN.client_req 103036 10.97 Good client requests received MAIN.cache_hit 103025 10.97 Cache hits MAIN.cache_hit_grace 0 0.00 Cache grace hits MAIN.cache_hitpass 0 0.00 Cache hits for pass. MAIN.cache_hitmiss 0 0.00 Cache hits for miss. MAIN.n_object 3 . object structs made MAIN.n_objectcore 153 . objectcore structs made MAIN.n_objecthead 153 . objecthead structs made MAIN.n_expired 7 . Number of expired objects SMA.s0.c_req 30 0.00 Allocator requests SMA.s0.c_fail 0 0.00 Allocator failures SMA.s0.c_bytes 368834 39.28 Bytes allocated SMA.s0.c_freed 196382 20.92 Bytes freed SMA.s0.g_alloc 15 . Allocations outstanding SMA.s0.g_bytes 172452 . Bytes outstanding SMA.s0.g_space 268263004 . Bytes available
これを目で追うのが大変だけど、
Mackerelを使うとデータを蓄積して
見やすく表示して監視してくれるのが本当にありがたいです
プラグインを実行すると上記の出力がこうなります
# mackerel-plugin-varnish [SMA.s0.g_alloc s0 g_alloc] varnish.requests.requests 13020.000000 1534141634 varnish.requests.cache_hits 13020.000000 1534141634 varnish.backend.backend_req 0.000000 1534141634 varnish.backend.backend_conn 0.000000 1534141634 varnish.backend.backend_fail 0.000000 1534141634 varnish.objects.n_object 1.000000 1534141634 varnish.objects.n_objectcore 151.000000 1534141634 varnish.objects.n_objecthead 151.000000 1534141634 varnish.objects_expire.n_expired 0.000000 1534141634 varnish.busy_requests.busy_sleep 0.000000 1534141634 varnish.busy_requests.busy_wakeup 0.000000 1534141634 varnish.sma.g_alloc.s0.g_alloc 5.000000 1534141634 varnish.sma.memory.s0.allocated 57231.000000 1534141634 varnish.sma.memory.s0.available 268378225.000000 1534141634
カスタムメトリック
pluginを読み込ませるだけで7個のグラフが生成されます
対象のvarnishstatのフィールド名と合わせて表にしました
Varnish Backend
BackendはVarnishがリクエストを受け取ったあとの転送先です
今回用意した環境で言うと「PHPのWebアプリケーション」がそれにあたります
Metrics | 説明 | varnishstatのフィールド名 |
---|---|---|
Conn fail | Backendとのコネクション失敗数 | MAIN.backend_fail |
Conn Success | Backendとのコネクション成功数 | MAIN.backend_conn |
Requests | Backendへのリクエスト数 | MAIN.backend_req |
このRequestsはアクセス数ではなくBackendへのアクセス数なので
サイトのアクセス数とは一致しません
クライアントのリクエスト数はMAIN.client_reqです
MAIN.backend_failが上がってくるようだと、
BackendのアプリケーションかVarnishとアプリケーションの疎通に問題がある可能性が高いです
これはキャッシュをオフにしたときのグラフです
キャッシュをオフにするとRequestが増え、Conn Successがすこしだけ増えます
Varnish Busy Requests
Metrics | 説明 | varnishstatのフィールド名 |
---|---|---|
wakeup | sleep listから取り除かれたリクエスト数 | MAIN.busy_wakeup |
sleep | Busy状態のオブジェクトがあるのでsleepさせたリクエスト数 | MAIN.busy_sleep |
Varnishでは、リクエストがバックエンドに到達するとbusyオブジェクトが生成されます
この処理中に新しいリクエストが同じページに来たときに
Varnishがbusyオブジェクトがある(同じページへのアクセスが処理中)と判断すると
そのリクエストを一度Waitingリストへ登録します
そして、最初のリクエストが処理されたときに
Waitingリストに登録されていたリクエストたちにもレスポンスします
つまり、Varnishは同じページへのリクエストがあるときは
最初の1つをBackendへ流し他は待機させておいて、
最初のリクエストが処理された後に、そのキャッシュを待機させていたリクエストに返すという動作をしています
その監視をしているのがBusyとWakeupです
Varnish Client Requests
Metrics | 説明 | varnishstatのフィールド名 |
---|---|---|
Hit | キャッシュヒット数 | MAIN.cache_hit |
Requests | リクエスト数 | 結果 MAIN.cache_hit ? |
HitがRequestsに近ければ
Varnishがキャッシュをユーザに返してくれていて
そのリクエストは裏のアプリケーションに到達していないことになります
キャッシュをオフにした状態のグラフです
オフにしてもデフォルトのキャッシュである程度Hitはします
Hit率が低い場合、キャッシュ条件を見直すと高速化する可能性があります
キャッシュ設定してこれくらいでした
特定ページへのabなのでHitsとRequestsが一致しちゃっておもしろくないですが
Hit率が高いので調子は良さそうですね😅
cache_hitpass(キャッシュしないキャッシュ)も見れるとうれしいけど
Mackerelのメトリックとしてないってことは見なくていいのかな?🤔
Varnish Objects
Metrics | 説明 | varnishstatのフィールド名 |
---|---|---|
objecthead | キャッシュ内でハッシュが異なるものの数 | MAIN.n_objecthead |
objectcore | キャッシュ内のメタデータの数 | MAIN.n_objectcore |
object | キャッシュしたオブジェクト数 | MAIN.n_object |
hashはここではキャッシュのKeyです
Varnishで"オブジェクト"というといろんな種類があり
その中のobjectcore, objectheadがモニタリングされています
キャッシュをオフにした状態でのグラフです
Varnish Objects Expire
Metrics | 説明 | varnishstatのフィールド名 |
---|---|---|
expire | 期限切れしたオブジェクト数 | MAIN.n_expired |
これはキャッシュをオフにして30秒おきにアクセスしたグラフです
キャッシュを作ってもすぐexpiredになっていまうので上がって下がってを繰り返します
MAIN.n_lru_nuked(新しいキャッシュのために強制削除されたキャッシュ)が
カスタムメトリックにはないのはなぜなのかが気になった
n_lru_nukedが起こるということはキャッシュ用メモリサイズがあっていないのかも?っていう監視は不要なものなのかな
Varnish SMA Allocations
SMAとはキャッシュのために確保したメモリ(MAlloc Stevedore counters)のことです
SMFやSMUなどがあるのですが
ここではMackerelが収集対象としているSMAのみにフォーカスします
端的にいうとキャッシュを何に保存しているか?です
Varnishの起動時に指定します
今回は検証なので
VARNISH_STORAGE="malloc,256M"
RAM使用の256MiBとしました
256MのMはmebibytesです
またオブジェクトごとに1 KiBを内部構造用に使用します
指定はMiBなのにvarnishstat -1したときはByteで表示される罠があります😂
Metrics | 説明 | varnishstatのフィールド名 |
---|---|---|
num | 未処理のストレージ割り当て数 | SMA.s0.g_alloc |
キャッシュをオンにしてアクセスして放置すると
このように増えたり減ったりしてました
Varnish SMA Memory
Metrics | 説明 | varnishstatのフィールド名 |
---|---|---|
Available | ストレージの残りバイト数 | SMA.s0.g_space |
Allocated | 割り当て済みバイト数 | SMA.s0.g_bytes |
使われれば使われるほどAvailableが減っていって
Allocatedが上限になります
グラフはByte表示されます
キャッシュ対象が少ないため全然使われてないですが
きっとこれからAvailableとAllocatedが戦いを繰り広げてくれるでしょう!
参考サイト
- varnish-counters — Varnish version trunk documentation
- What is hit-for-pass in Varnish Cache?
- Storage backends — Varnish version trunk documentation
Varnishと戦い始めての感想は、6系は特に実践記事は少なく、
数年前の記事にVarnishは対応していないので・・って書いてあっても
実はもうその機能実装されてたりするので、ひたすらリファレンス見てTryErrorしてます
その合間もMackerelが見ててくれるのはモチベーションにもなりますね💪
はてなブログ映えのために何度かabコマンド叩いてるけど怒られないといいなぁ😅