GlimpseによるRedis入出力の可視化とタイムライン表示
- 2013-11-15
空前のGlimpseブーム!Glimpse最高!これ入れてないASP.NET開発はレガシー!というわけで、グラニ a.k.a. 謎社でも激しく使用を開始しています。さて、ではGlimpseとは何ぞやか、という話は今回は、しません(!)。それは誰かがしてくれます(チラッ。今回は本題のRedis周りのGlimpse拡張について。
CloudStructures 0.6
グラニではRedisライブラリとしてBookSleeve + CloudStructuresを利用しています。RedisやBookSleeveについては、C#のRedisライブラリ「BookSleeve」の利用法を読んでね!何故BookSleeveだけじゃないのかというと、BookSleeveだけだと使いづらいからです。例えるなら、BookSleeveはRedisドライバであり、ADO.NETみたいなもの。CloudStructuresはO/R(Object/Redis)マッパーであり、Dapperのようなもの。といった関係性で捉えてもらえればあってます。で、CloudStructuresは私謹製です。
今回Glimpseと連携させて使いやすくログ吐きするのに若干足りてなかったので、出力用のインターフェイス ICommandTracer を破壊的変更かけてがっつし変えちゃってます。というわけでバージョン0.6に更新。破壊的変更、ま、まだ0.xだし……。0.xとはいえ、CloudStructuresはグラニのプロダクション環境下で激しく使われてます。もんのすごい量のメッセージを捌いている(BookSleeve開発元のStackOverflowよりも遥かに捌いているはず)、秒間で数万とか数十万とかのクエリ数を、なので実績は十二分にあると言えるでしょう。
今回からリポジトリにCloudStructures.Demo.Mvcというプロジェクトを入れているので、実環境でどういう風に使えばいいのかとか、Glimpseでどう表示されるのかが分かるようになってますので、使う時は参考にどうぞ。
Glimpseによる表示
今回からCloudStructuresによるRedisアクセスを可視化できるように、Glimpseプラグインが別途インストールできるようになりました。NuGet上で Glimpse.CloudStructures.Redisから入れればおk。インストール後、Glimpseを有効にし、ICommandTracerにGlimpse.CloudStructures.Redis.RedisProfilerを渡してやると(Web.configからの設定の仕方などはCloudStructures.Demo.Mvcを見て下さい)、以下のようになります。
Redisタブが追加され、Redisで、どのコマンドでどのキーで実行したか、何を送って何を受け取れたか、かかった時間。それらが一覧表示されます。また、重複コマンド・キーで発行した場合は警告表記になります(一番下のオレンジの)
とにかく、通信が全部見える。中身含めて。圧倒的に捗ります。これがないなんて、盲目で歩いているに等しかった。ありえない。もう、戻れない。見えるっては、いいことですねぇ、ほんと。
更に、Glimpse標準のTimelineタブに統合されていて、これが超絶最高です。
5つ連なってる部分、これは非同期に並列アクセスされています。コードは
var ids = new[] { 12, 3124, 51, 636, 6714 };
var rand = new Random();
await Task.WhenAll(ids.Select(async x =>
{
await RedisGroups.Demo.String<int>("TestInc.Id." + x).Increment(rand.Next(1, 10));
}).ToArray());
のようになっているわけですが、これ、もし同期アクセスだったら、同時に動くことなく、この分だけタイムラインが右に長くなるわけです。可視化されることで全て非同期!全てパイプライン!効率的に、高速に、というのがとてもわかりやすく見えます。実際、グラニではこういった一気に叩いてWhenAllというパターンを多用して高速なレスポンスを実現しています。ここまでASP.NET MVCの非同期コントローラーを死ぬほど使い倒している企業は、世界でも稀なのではないか、というレベルで非同期祭りやってます。(そして時に地雷踏みつつ前進してます)。
Glimpseについてもうちょっとだけ
実際のところGlimpse、ただ入れただけだとあんまり嬉しいことはないでしょう。色々なサーバーの情報が見えると言ったって、そんなの一度だけ見れば十分だしー、で終わってしまったり。ただ情報がありゃあいいってものじゃなくて、何の情報が必要か、が大事。でも、Glimpseってカスタマイズが容易なんですね。だから、その会社にとって、そのアプリケーションにとって大事な情報を流しこむことができる。大事な情報を流しこむようにすることで「頻繁に使うものではない」から「頻繁に使うもの」に変える。そうすることで、手放せないものとなります。
これはグラニで実際に使っているタブですが、Log, PlatformAPI, Redis, SQL Explainは弊社が独自に作成したタブです。以前にHttp, SQL, Redisのロギングと分析・可視化についてという記事を書きましたが、そこで、外部へのアクセスをフックする仕組みは作ってあったので、それぞれでGlimpseにデータ流すように変えただけです。これによりRedis, Http, SQLの全てがタブで全て見えるし、Timelineにも出てくるのでボトルネックが一目瞭然に。過度な通信なども一発で分かる。
SQL Explainはリクエスト中で発行された全てのSQLに対してexplainを発行し結果を表示しています(うちはMySQLを使っているのでexplainです、SQL Serverならそれ用のコマンド打てば同様以上のことが当然可能です)。これにより、将来ボトルネックになるクエリが早期発見できます。
explainとか面倒だから全てに律儀に打ったりしないし、*ms以上遅いクエリは警告するとかやったって、開発環境のデータ量だと無意味だったりするでしょう。だから、全てのクエリに対して自動でexplainをかけてやって、怪しそうなもの(using filesortとか)は最初から警告してあげる。これで、クソクエリの早期撲滅が可能となります。
ちなみにMiniProfilerとの使い分けですが、うちではむしろもうMiniProfilerイラナクね?の方向で進んでます。ちょっとまだGlimpse、足りてないところもあるのですが、割と直ぐに解決しそうだし、むしろMiniProfiler動かしてるとHistoryが汚れるのでGlimpseにとって邪魔なのですよね。
まとめ
といったように、グラニではより開発しやすい環境を作ることに全力を注いでいます。なんと今だとアプリケーションエンジニア・インフラエンジニア・フロントエンドエンジニアを募集中だそうですよ!←求人広告記事ダッタノカー、イヤソンナコトナイデスケドネ。なんか敷居高杉と思われてるかもですが、アプリエンジニアに関しては割とそんなことなく、基準は最低限LINQ to Objects知ってる程度からなので気楽にどうぞ。最近、オフィスを六本木ヒルズに移転しまして、ハードウェア環境も充実しているので、そちらの面でも開発しやすいかな、と。モニタも27インチ(2560x1440)をトリプルですしドリンク無料飲み放題ですし。
ソフトウェア側も良さそうならどんどんバシバシ変えてます。Glimpseも最初は導入されてませんでしたが、後から入れていますしね。ASP.NET MVCも早速5へ。この辺の姿勢は初期の文化が大事だと思っているので、絶対緩めないのを信条にしています。
なお、Glimpseの導入や独自タブの作成、ならびにGlimpse.CloudStructures.Redisの作成は、私がやったわけではありません!私がやったのはSQL Explainタブの作成とICommandTracerの改変、Glimpse.CloudStructures.Redisを社外に出せるよう依存部分の除去しただけでして。そんなわけで皆で一岩となって改革してるんですよー、とっても刺激的でいい職場です。私にとっても。←ヤッパリ求人広告記事ダッタノカー、イヤソンナコトナイデスヨ。