へぼいいいわけ このページをアンテナに追加 RSSフィード Twitter

2013年11月10日

unkarにNewRelicを導入してみた&Go言語で書きなおした感想

NewRelicとかいうものが便利そうなのでunkarが稼働している鯖に導入してみました。

導入方法は以下を参考にしてスタンダードプランを無料で利用しています。

NewrelicでAWS環境のメトリクスをカジュアルに共有してみる


NewRelicを導入してみた

unkarGo言語で書いている*1ため、NewRelicのプラグインを適当に眺めている時に発見したGo言語プラグインgorelicを組み込んで様子を見てみました。

unkarではAmazon EC2を使っているので、新しくAmazon-Linux201309でインスタンスを立ち上げました。Amazon-Linux201309だとデフォルトrubyが1.8.7なようで、最初にrubyの1.9.2以上を新しく入れないといけないようです。間違えて進めると後から色々なツールのruby1.9版を入れないといけなくなって面倒だったので注意した方がいいです。


ちなみに現在のunkarの規模は一日30〜40万PV、月間1000万PV程度です。


unkar全体の様子

f:id:heiwaboke:20131110203803p:image

Goroutines(スレッドみたいなもの)の数が100〜250くらいの間で動作しているみたいです。

本物のスレッドは28で安定している模様。負荷に応じて段階的に増えて、一度増えたら減らないっぽい?


メモリの様子

f:id:heiwaboke:20131110203804p:image

apache+PHPで動作していた頃と比べるとメモリ使用量が10分の1くらいになった気がする。

今のunkarは200MB程度の空きメモリがあれば十分動作するみたい。


システムメモリ?の様子

f:id:heiwaboke:20131110203805p:image

起動した後の数時間で一気に呼び出している。起動時に一気にメモリ確保して後は使いまわしているということ?


ガベージコレクションの様子

f:id:heiwaboke:20131110203806p:image

右側のグラフが無尽蔵に伸びまくっているのが気になるけど、動作が重くなっている感じはしないので、たぶん大丈夫なんでしょう。


ここまでNewRelicのグラフを色々と貼り付けてみましたが、こうやってグラフで出力されると楽しいですね。正直なところ、今まで鯖監視系のツールを全く使ったことが無かったので、グラフで可視化されるだけでお腹いっぱいです。


unkarをGo言語で書きなおした感想

unkarの利用者からすると非常にどーでもいい話でしかも今更な話だと思いますが、unkarは08月17日頃からGo言語で書いた一つの実行ファイルで動作しています。webサーバ部分から全て書いているので、unkarの動作している鯖ではapacheとかnginxとかは動作していません。

一部URLPHPが残っていますが、中身は全部Go言語になっています。


Go言語を採用した理由としては、元々使っていたPHPに飽きたことと、たまたま自分が書ける言語の中で比較的簡単にサイトが作れそうで、動作させるところまで行けそうだったからです。

Go言語を採用したおかげで、前は普段使っているWindows上にunkarの環境を作るのが面倒で、ちょっと弄る度に本番環境でデバッグしていたのがWindows上でもそのまま動作するようになって捗るようになりました。


Go言語というと、自分にはGoogleが作ったお気楽なコンパイル言語ってイメージがあって、一応コンパイル言語なので、インタプリタ言語なPHPで書いていた時よりも高速に動作してCPU使用率が下がるんだろうなーとか思っていましたが、別に大差ありませんでした。たぶん正規表現を使いまくった作りだったこととか、元々2chとの通信に時間がかかっていたのが原因だと思います。


上でNewRelicのグラフを貼った時に書いていますが、メモリの使用量はたぶん劇的に減少しました。たぶんというのは、PHPで動作していた時の状態をちゃんと測ったことが無いためで、PHPの時はピーク時にapacheが300プロセスくらい動作していたので、かなりのメモリを使用していたと思います。

Go言語で書き直したから簡単にメモリ使用量が減ったわけではなく、書きなおした後の2ヶ月間くらいはメモリリークが酷く、一週間動作するとメモリを3GBくらい(鯖に載っているメモリの半分程)消費していました。そこまでメモリを使うと、GCにアホみたいに時間がかかるみたいで、10秒ごとに1秒くらいプログラムの動作が停止する状態でした。

特定のURLにアクセスするとメモリのプロファイリングを行うようにして、なんとか今のメモリリークしていないように見える状態まで持っていくことが出来ました。pprof.WriteHeapProfile関数がなかなか便利でした。


メモリリークをチマチマ直して様子を見ていたおかげで分かったことですが、なんでもかんでも「defer」を使う作りにするとメモリを食うようなので、Go言語を書く人は気をつけたほうがいいと思います。*2


unkarくらいのAPI叩いてちょっと整形して出力する程度のサイトなら、Go言語で書きなおすのは悪く無いと思います。

でも、webサーバーまでGo言語で書いたのはちょっと失敗だったかなと思っています。パスによるルーティングとか、IPアドレスによるアクセス制限とか、ログの出力など、webサーバが標準で装備している機能を実装するのが、できる限りGo言語の標準ライブラリに任せても大変でした。まあ全部Go言語で書いたからこそ、Windows環境でも手軽に動作させられるので、価値が無いわけではないんですが。


だらだらと色々書いてみましたが、適当にWEBを眺めている感じだと、Go言語でツールを作った、勉強会に参加したという話は結構あるっぽいのに、サイトを作ったという話が妙に少ない気がするので、このどーでもいい感想が何かの役に立てばと思います。

*1:unkar.org以下全て。search.unkar.orgは今のところapachePHP

*2:プロファイルングすると「newdefer」とか言う奴にめちゃくちゃメモリが使われているのが分かります。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/heiwaboke/20131110/1384094163
リンク元