読者です 読者をやめる 読者になる 読者になる

ももクロスライダーで測る Redis vs MongoDB on Heroku 第二弾

f:id:yosuke_furukawa:20120504112310p:image

今日はみどりの日らしく、ももクロスライダーも緑の話が活発です。

さてさて、前回に続いてRedisの話です。
危険なほど速いと言われていますが、実際の実力はどうなのか気になるところです。
確かに他の参考記事を見ると、かなり高速なようです。
redis、それは危険なほどのスピード|サイバーエージェント 公式エンジニアブログ
FreeBSDで,mongoDB V.S. Redis - なぜか数学者にはワイン好きが多い

じゃーって事で、RedisとMongoDBをベンチマーク比較してみました。
結論から言うと、Redisはやっぱり鬼のように速いです。

ベンチ方法


RedisとMongoにtwitpicから取得してきた ももクロの画像に関するデータを入れておき、それを取り出す処理がどちらが早いかだけを計測しています。更新系の操作も高速なようですが、ももクロスライダーは今は更新系の操作がないので、これで計測しています。

ももクロスライダーを少し拡張し、

  • /directで実行するとtwitpic API直接呼出してJSON情報取得
  • /redisで実行するとredisからJSON情報取得
  • /mongoで実行するとmongoからJSON情報取得

できるようにしてから計測しています。

一応URLを貼っておきます。アクセスしてみれば、それぞれなんとなく性能の差が分かるかもしれません。
twitpic直接呼出し
redis呼出し
mongo呼出し

このURLに対してローカルサーバーへのアクセス(ホストをlocalhostにして)で計測したものとHeroku上で計測したものの2パターンとさらにアクセス高負荷で計測したものと低負荷なものの4パターンで計測しています。

計測ツールはJmeterを使っています。
低負荷は10秒間以内に10クライアントからのアクセスを測定。
高負荷は10秒間以内に1000クライアントからのアクセスを測定しています。

ベンチマーク結果

■ローカル環境で計測(低負荷:10秒間で10クライアントから接続される)

local(低負荷) direct(twitpic api直) redis mongo
response time 2421ms 3ms 11ms

twitpic APIを直接呼び出ししたときは比較にならないほど遅かったので、省いてグラフ化するとこんな感じです。

ミリ秒なのであまり差はありませんが、redisの方が若干早いですね。圧巻なのはこの次。

■ローカル環境で計測(高負荷:10秒間で1000クライアントから接続される)

local(高負荷) direct(twitpic api直) redis mongo
response time N/A 2ms 3531ms

twitpic APIはもはや受け付けてもらえず、エラーになってしまいました。
Redisはここでも超高速で、ほとんど低負荷の時と速度に差がありません。
mongoは平均3.5秒程度になってしまいました。mongoはメモリ上にデータはないので、ディスクアクセスになってしまい、負荷がかかるとその分、低速になります。

予想をはるかに上回るRedisの速度で、危険なほど速いというのも分かる気がします。

■Heroku環境で計測(低負荷:10秒間で10クライアントから接続される)

heroku(低負荷) direct(twitpic api直) redis mongo
response time 958ms 292ms 252ms

Heroku環境から計測してみると、ネットワークを介しているせいで結構大きな差が生まれています。
twitpicがローカルよりもかなり速いのが気になりますが、とりあえず、置いておきます。(Herokuサーバーに距離が近いのかな?)
redisとmongoだとここではmongoの方が若干早いですね。ただ、双方ネットワークがボトルネックなせいでローカルと比較してかなり遅延している事がわかります。

■Heroku環境で計測(高負荷:10秒間で1000クライアントから接続される)

heroku(高負荷) direct(twitpic api直) redis mongo
response time N/A 4985ms 5664ms

高負荷で計測してみると、ここでもredisの方が早いという結果が出ました。
ただし、ローカルで計測した時よりも全然Redisの恩恵は得られていません。
ネットワークがボトルネックなせいもありますが、Redis to goのコネクション制限がボトルネックになってきていると思われます。Herokuのデータストアとして、add-onであるRedis to goとMongoHQを使用していますが、Redis to goはフリープランでは10コネクションまでしかサポートされていないので、一度に2コネクション使用するももクロスライダーでは5アクセスしか同時に並列で使えません。

それを裏付けるグラフもとれたので紹介します。

この折れ線グラフを見て下さい、青がRedis、赤がMongoです。1000のリクエストを平均するのではなく、1つ1つ描画するとこのグラフになります。横軸がリクエスト発行順番、縦軸がレスポンスタイムです。1〜300番目のリクエストくらいだと早いのが分かります。
500〜600番目のリクエストまではRedisの方が優っていますが、徐々にコネクションがとれなくなり、Redisのレスポンスが下がることが分かります。
最終的な1000番目のリクエストには22秒くらいレスポンスに要していました。
Mongo HQのコネクションに関しては調査不足で分かりませんが、多少安定してレスポンスを返している所から、少なくとも10よりも大きく取られているように感じます。

ここから言えることは、ある程度クライアントが少ない間はRedis To Goの方が良いです。
600クライアント同時接続程度であれば5秒もかからずに返しています。600クライアント以上から同時に接続されるようなケースでは、Redis To Goのプランを見直すかMongo HQの方が良いかも知れません。

まとめ


Redisはやっぱり高速でした。3点まとめです。

  • ローカル環境の単純なアクセスではRedis は爆速。
  • Heroku環境でもネットワークがボトルネックになるもののかなり高速を維持する。
  • クライアントの同時接続数が増えるとRedis To Go アドオンのコネクション数が頭打ちになるため、場合によってはMongoよりも遅くなる。

RedisとMongoだと特質が違うのでもちろん一概に性能だけを比較するものではありませんが、人気を二分するデータストアとしてベンチした甲斐はあったのかと思います。他にもHerokuにはMongo labとかのアドオンもあるので、気になるところです。また、memcached等、他のインメモリKVSと比較するのもいいかも知れませんね。