2010/11/01

redis導入後にトラブル発生、そのレポート


こんにちわ、ミツバチワークス stoneです。

今回は、redisシリーズ第3弾、実際にredisをサービスの投入してみて、うまく行かなかった事例についてご紹介します。

redisの使用用途


今回、いくつかあるセッションデータのうち2つをMySQLからredisへ移行させました。
これらのセッションデータ、MySQL上では、セッションIDの他に複数のカラムから構成されているのですが、redis上では、この複数のカラムをserialize()して、
key(string) => value(string)
という形で格納するようにしました。

ちゃんとソースコードで確認はしていないのですが、memcachedでも、TTLが設定できますが、TTLを過ぎたデータを監視してクリアしていないですよね。
また、memcached内部のslabの構成次第では、TTLまでデータが保持されずに、データがクリアされてしまうケースにも遭遇したことがあります。
(まぁ、キャッシュだから当たり前の話なのですが)
反面、redisの場合、TTLまでデータが残っていて、かつ、TTLを過ぎたデータは、定期的にクリアされています。
(これは、ソースコードレベルでも、実際の状態監視でも確認できました。)

運用中の状態


サービスに投入後の、ピークタイムでのredisの状態です。

ロードアベレージ

redisのロードアベレージは、MySQLより低め、memcachedよりは高めで推移します。
こんな風にギザギザのロードアベレージは、初めて見る形です。
瞬間的にロードアベレージが上がるのは、バックグラウンドでのsnapshotの保存によるもののようです。

トラフィック

こちらも、初めて見る形のトラフィックグラフでした。
どうやら、バックグラウンドでsnapshotを保存するタイミングで、リクエストが滞留したり、滞留していたリクエストが一気に解消したり、というのを繰り返しているようです。
コレはこれで問題だったので、後ほど取り上げます

メモリの使用量

このグラフは、時間の尺が12時間なのですが、ピークタイムを過ぎて、TTLを過ぎたデータが、クリアされて行くのが、よくわかります。
最初にグラフを見たときには、とても感動しました。


問題1: リクエストが詰まる


現象

上記のredisのトラフィックが、サイト全体のパフォーマンスにまで、影響していました。
redisのトラフィックが詰まるタイミングで、サイト全体のトラフィックも低下する現象が見られるようになってきたのです。
下のリバースプロキシのグラフで、ざくっと切れ込みの様にトラフィックが下がっている部分は、redisの「詰まっている」タイミングと同じタイミングで起きていました。

対処

少し調べてみたのですが、なかなか原因はつかめません。
ひとまず、わかっているのは、
・snapshotの保存のタイミングで、トラフィックが低下する
・snapshotの保存のタイミングでは、CPUの使用率が上がる
の2点のみ。
そこで、保存の際に少しでもCPUの使用率を下げる為に、
rdbcompression no
(デフォルトはyes)
としてみました。

また、事前に別サーバーで、redisを立ち上げて、
1) "rdbcompression yes"で1万件程度のデータをストア
2) redis-serverをシャットダウン
3) redis.confを"rdbcompression no"に変更
4) redis-serverを起動
としても、データは保全されていることを確認しました。

結果(解決)






上記の問題があった時間帯の翌日のredisとリバースプロキシのトラフィックのグラフです。
ほぼ同じような形で見分けがつきにくいですが。。。。

redis

rev-proxy

問題だった詰まる→解消→詰まる→解消の現象が解消されています。ひとまず、ほっとしました。


問題2: 応答が極端に遅くなる


こちらは、残念ながら、解消できていない問題です。

現象

問題が起きた時間帯のredisのトラフィックのグラフです。
グラフを見ると一目瞭然なのですが、ある瞬間を境にして、トラフィックがかなり乱れているのがわかります。
同じ時間帯のロードアベレージを見てみると。。。。

これらのグラフから見て取るに、問題の現象は、
1) 内部的に「何か」が起きる
2) ロードアベレージがじわじわ上がる
3) その「何か」が分水嶺を超える
4) トラフィックが乱れる
というシナリオのようです。

この状態になると、redis-cliでも、応答が悪くなりました。
それにつれて、サイト全体のパフォーマンスが悪化して行きました。

対処

この現象が起きた場合、redis-serverを再起動すると、すんなりと問題が解消します。
が、TERMシグナルを発行しても、サさってシャットダウンできない場合もあり、実際に人のオペレーションが必要な状況でした。
問題が発覚してから、数日は、夜中まで監視を行い、問題が起きた場合はリスタート、という運用をしていたのですが、さすがに数人で運用してる現状では、無理がかかりすぎるため、MySQLに戻しました。



redis導入後、このトラブルが起きていないケースもあるので、原因の特定がまったくできていない状態です。
問題が起きていないケースでは、トラブルがあったケースに比べて、
・データのTTLが長いため、順次データがクリアされる状態になっていない
・データ件数が1/10程度
となっていて、今後、データのTTLが切れ始めるタイミングが要注意だと考えています。

今回は、トラブルに合いましたが、やはり、redisのスピード感は魅力です。
そのため、今後は、TTLが設定されない、永続的なデータについても、実験をしてみることにしています。

では、また次回に♪