午前2時、スロークエリという名の悪夢
机の上でスマホが激しく震える。システムからのアラートが鳴り止まない。データベースのCPU使用率は98%に達し、レイテンシは50msから3000msへと跳ね上がっている。寝ぼけ眼でログを確認するが、トラフィックが急増したわけではない。しかし、メインのDBは毎秒数千ものクエリを捌こうと悲鳴を上げている。
最初に頭をよぎった疑問はこれだ。「一体、Memcachedは何をしているんだ?」
通常、Memcachedは非常にスムーズに動作し、リード(読み取り)負荷の最大90%を肩代わりしてくれる。しかし、いざトラブルが発生した際、具体的な数値がなければ、暗闇の中を泳いでいるようなものだ。サーバーにSSHでログインしてtelnet経由でstatsを叩くだけでは、その瞬間の数値しか分からない。傾向(トレンド)や、いつから状況が悪化したのかという正確なタイミングを把握することは不可能なのだ。
そこで救世主となるのが、Prometheus + Memcached Exporter + Grafanaという組み合わせだ。私が運用しているシステムでも、この構成のおかげで、ユーザーが「遅い」と不満を漏らす前に、RAM不足によるEvictions(追い出し)の急増を察知することができた。
Memcachedは動いているのに、なぜシステムが重いのか?
Memcachedが役に立たなくなる、注意すべき3つの代表的なシナリオがある:
- Cache Hit Rate(キャッシュヒット率)の低下: データがキャッシュに存在せず、すべてのリクエストがデータベースに直接飛んでしまう。
- Evictions(追い出し)の増加: MemcachedのRAMが不足し、新しいデータを保存するために(期限切れ前であっても)古いキーを強制的に削除している。
- Connection Limit(接続制限): アプリケーションからの接続数が上限(デフォルトは通常1024)に達している。
徹夜を避けるためには、一目でどこに問題があるか分かる直感的なダッシュボードが必要だ。
Memcached Exporterによる監視の導入
手動でコマンドを打つ代わりに、Memcached Exporterを使用する。これはGoで書かれた軽量なサイドカーで、Memcachedに接続してstatsを取得し、Prometheusが読み取れる形式に変換してくれる。
ステップ1:Memcached Exporter의 インストール
Dockerを使用する場合、次の1行を実行するだけで起動できる:
docker run -d \
--name=memcached-exporter \
-p 9150:9150 \
prom/memcached-exporter:v0.13.0 \
--memcached.address=172.17.0.1:11211
注意:IPアドレス 172.17.0.1 は、実際のMemcachedサーバーのアドレスに置き換えてください。
Linux(バイナリ)を使用する場合は、GitHubから最新のリリースをダウンロードして解凍し、安定性を確保するためにsystemdサービスとして実行する:
wget https://github.com/prometheus/memcached_exporter/releases/download/v0.13.0/memcached_exporter-0.13.0.linux-amd64.tar.gz
tar xvf memcached_exporter-0.13.0.linux-amd64.tar.gz
./memcached_exporter --memcached.address="localhost:11211"
http://localhost:9150/metrics にアクセスして素早く確認しよう。memcached_up 1 という行が表示されれば、半分は成功だ。
ステップ2:PrometheusでのScrape Jobの設定
prometheus.yml ファイルを開き、Prometheusが定期的にデータを取得するためのエンドポイントを定義する:
scrape_configs:
- job_name: 'memcached_prod'
static_configs:
- targets: ['<EXPORTER_IP>:9150']
relabel_configs:
- source_labels: [__address__]
target_label: instance
replacement: 'memcached-01'
Prometheusをリロードすると、データが時系列データベース(Time Series Database)に蓄積され始める。
ステップ3:Grafanaダッシュボードの設定
ゼロからチャートを作成する必要はない。コミュニティによって最適化されたプロフェッショナルなテンプレートが公開されている。Grafanaで「Import」を選択し、ID 74 または 3932 を入力するだけで、Hit Rate、Memory、Network Trafficのグラフが即座に表示される。
厳重に監視すべき3つの「黄金」指標
ダッシュボードを見る際は、些細な数値は無視して、以下の3つの極めて重要な指標に集中しよう:
1. Cache Hit Rate(キャッシュヒット率)
計算式:get_hits / (get_hits + get_misses)
健全なシステムでは、通常Hit Rateは90%以上だ。もしこの数値が75%を下回ったら、それは警告のサイン。コードのロジックでキーの指定が不統一だったり、TTL(Time To Live)が短すぎて再利用される前にデータが削除されている可能性がある。
2. Evictions(追い出し数)
理想的な状態では、Evictionsは0であるべきだ。もしグラフに垂直な棒が立ち始めたら、それは RAMが枯渇したことを意味する。Memcachedは新しいデータを保存するために古いデータを「犠牲」にしているのだ。この場合の解決策は、RAMを増設するか、キャッシュ内の不要なゴミオブジェクトを削減することだ。
3. Memory Usage(メモリ使用率)
Memcachedのメモリ使用率が割り当て量の80%を超えないように注意しよう。MemcachedのSlab Allocation(スラブ割り当て)メカニズムにより、見かけ上の空きRAMがあっても、実際には新しいオブジェクトを保存できないことがある。メモリが85%に達した時点でアラートを設定し、早めにスケールアップを検討すべきだ。
実践的なアドバイス:障害が起きてからダッシュボードを見るのでは遅い
アラート(Alerting)システムがなければ、美しいダッシュボードもただの飾りだ。私は通常、Telegramを通じて以下のような閾値でアラートを設定している:
- Critical:
memcached_up == 0(サーバーダウン、即時対応が必要)。 - Warning:
rate(memcached_items_evicted_total[1m]) > 10(明らかなRAM不足の兆候)。 - Warning: Hit Rate < 70% が10分間継続。
これらのルールのおかげで、以前デプロイのミスによってキー構造が変わり、Hit Rateが急落したことに気づくことができた。チームは5分以内にロールバックを行い、深刻なダウンタイムを回避できた。
まとめ
Memcachedの監視は、単にツールを入れることではなく、数字を通してシステムがどのように「呼吸」しているかを理解することだ。PrometheusとGrafanaを組み合わせることで、受動的にトラブル対応に追われるのではなく、能動的に対処できるようになる。皆さんがアラートの音で叩き起こされることなく、安眠できることを願っている。

