2013年3月9日土曜日

Webサービスの難しさ

 会社で納品しているシステムで、PostgreSQL からデータを引いてサーバ側で地図を描画して配信しているシステムがあるんです。このシステムの難しさは、5分間隔とかでリアルタイムに大量の軌跡を描画しなければならん所です。しかも、24時間以内の長さで、好きな期間を指定できるのと、軌跡を表示する移動体を自由に選択できるところも難しいです。輪をかけて難易度を上げているのが、軌跡の点の上にマウスを置いとくと、その点の通過時刻を表示するという仕様です。この仕様のおかげで、データを点としてデータベースに保持するよりありません。大抵、負荷のかかる見方をするのが、直近の24時間程度という特性もあります。

 ポリラインとか、ポリゴンで登録されていれば、空間インデックスにかけて関係する部分だけを取り出し描画すれば良いんですが、軌跡の場合は、点と点を結ぶ線の情報が必要なので、空間インデックスで絞るわけにもいきません。なので、指定された期間中のデータを総なめする必要があります。

 さて、閲覧する人数が増えて負荷がかかると、PostgreSQL に対する負荷が膨大になり、ストールを起こします。PostgreSQL のチューニングもパンパンにやってて、1個のクエリー自体は普段、10 から 20 mm sec 程度で、それが移動体分になります。しょうがないんで、MySQL でやれば、もっと速いんじゃないの?と指示してテストさせてみましたが、あまりチューニング無しの MySQL だとスタート時点で、100 mm sec 以上かかっていて、MySQLに変更したからと言ってバラ色の人生が待ち受けている訳でもなく、成果も見込めないので、MySQL は辞めました。まぁ、MySQLがそんなに性能が凄い良いとも思っていなかったのを裏付けした格好になります。

 次に、pgpool-2 を使って、接続イニシャルを減らす方法を試してみました。しかし、pgpool-2 だと、通常接続の 1.2倍のペナルティを受けてしまいました。十分にプール数を確保しても、そうだったので、今時のPostgreSQLは、相当に速いんだなぁと実感できました。

 システム構成上、今のところスケール・アウトができないので、今度は memcached を使って PostgreSQL の負荷を低減させる方策を思いつきました。冒頭に示した要件があるので、キーを [移動体番号]-[日付+時刻] にして、5分間隔に軌跡の点を保存して、そこから引くようにしてみました。ところが、実装して試してみると遅い。はい、冷静に考えると5分刻みデータなので24時間だと12*24= 288回のリクエストを発行する計算になります。これが移動体1台分。今度は socket の往復分のコストが馬鹿にならず、性能が 1/2 に落ちました。これを裏付けるべく、15分間隔にして試してみたところ、性能が 1.5 倍になりました。という訳で、memcached も使いよう。今回のケースでは威力を発揮できない感じです。

 結局、結論としては、いつか NoSQL でやらないと、この部分は破綻すると提言していたように、Redis に置き換えてやってみるよりない感じになりました。

 5分間隔でPostgreSQLのテーブルにポリラインを登録しておいて、そこから引くという構成も考えられます。しかし、更新負荷等のバランスから考えて、NoSQL に置き換えるのが王道かな?と考えている次第であります。

0 件のコメント: