2009-04-12 12 views
8

私が働く会社は、Blackberryプラットフォームのアプリケーションを作成します。スケーラブルなヒット/アナリティクスシステムを設計する最良の方法は?

私たちは、アプリケーション内にコードを埋め込み、実行するたびにいくつかの統計情報を中央サーバに返送することを可能にする独自の「分析システム」に取り組んできました。現在、システムは正常に動作します。しかし、それはベータ版では1時間当たり100〜200ヒットしかありません。 「ヒット」は問題なくサーバーに送信されます。ヒットの受け入れと格納を処理するための非常に堅実なAPI(MySQL DB内)を構築しました。私たちは負荷をテストしました。問題なく時間当たり数十万ヒットに対応できるはずです。それは本当に問題ではありません。

問題は統計情報を示しています。 Mint(haveamint.com)に似たディスプレイパネルを作りました。毎時間、過去の日、月、週、年などのヒット数を表示します。最初のバージョンでは、ヒットテーブルからデータを取り出して即座に解釈するストレートクエリが実行されました。それは非常に長く働かなかった。私たちの現在の解決策は、ヒットが処理のために「キューに入れられる」ということです。そして、5分ごとにヒットを取得し、時間、日、週、月、年などの「キャッシュ」に分類します。これは驚くべきことですが、信じられないほどスケーラブルです。ただし、1つのタイムゾーンでのみ動作します。全社でこれにアクセスできるため、さまざまなタイムゾーンで数百人のユーザーを扱っています。私がサンノゼで「今日」と定義しているのは、ロンドンの私の同僚が今日と定義しているものとはまったく異なります。現在のソリューションは1つのタイムゾーンにしかキャッシュされないため、タイムゾーン以外のデータをチェックしている人にとっては悪夢です。

これを修正する現在の計画は、すべてのタイムゾーン(合計40個)のキャッシュを作成することです。しかし、それはデータの量に40を乗じていることを意味します...私にとっては恐ろしいことですが、キャッシュが非常に大きくなる可能性があることを考えると、さらに、キューを処理するときには、40個の異なるキャッシュに入れるのにもっと多くのCPU時間がかかるでしょう。

他にもこの問題を解決する方法がありますか?複数のタイムゾーンに触れたソフトウェアを設計するとき

は(そのような長いquestion..itのため申し訳ありませんが、説明するのは、正確には容易ではありません。おかげですべての!)

+0

具体的な質問は、実際には非常によく似たものを設計しており、ここに入力する予定です。 +1 –

+0

ヒットハンドリング/ストアAPIを見るのは非常に面白いでしょう:) – Jacco

答えて

4

あなたが提案しているソリューションが余りに多くの冗長性を持っています。毎時ではなく少なくとも30分のバケットにデータを格納し、タイムゾーンをUTCに標準化することをお勧めします。

30分バケットの場合、ユーザが-4.5 UTCから1 - 2PMの時間データを要求すると、システムから5:30 - 6:30 PMのデータをフェッチして表示できます。データを1時間単位で保存すると、N + 0.5時間の差異を持つタイムゾーンのユーザーに要求を処理することはできません。

毎日番号の場合は、48時間30分の集計が必要です。選択するスロットは、ユーザーのタイムゾーンによって決まります。

年次データを取得すると、17,520時間半のバケットを集計しなければならないので、面白いことになります。この計算を簡単にするために、UTC時間あたりの事前集計された年間データと、その年の4.5時間の最初の集計データを減算し、翌年の最初の4.5時間の集計データを追加することをお勧めします。これは本質的に1年全体を4.5時間シフトさせ、仕事はそれほどではありません。ここから作業して、システムをさらに微調整することができます。

編集:カトマンズは+5.45 GMTだから、30分バケットの代わりに15分バケットにデータを保存する必要があります。

EDIT 2:もう1つの簡単な改良点は毎年の集計を中心にしているため、毎回17,520個のバケットを追加する必要がなく、国ごとに1つの集計を必要としません。 1月2日から12月30日までの年間データを集計します.2つの国間の最大タイムゾーンの差は23時間ですので、毎年のデータ(Jan 02 - Dec 30)をとり、前と後のバケットを追加できます適切に。たとえば、-5 UTCタイムゾーンの場合、0500以降のすべてのバケットをJan 01に追加し、12月31日にはすべてのバケットを、0500には翌年1月1日にすべてのバケットを追加します。

+1

バケットサイズについての議論のために+1 – lpfavreau

+1

これは最善の選択肢のようです。非常に少量の人しかそのタイムゾーンを占有しないと考えると、15分バケットは価値がないかもしれません。 –

2

、私はいつもとUTCにあなたの日付/時刻を格納するでしょうね元のタイムゾーンの別のフィールドであり、時刻を取得してUTC /タイムゾーンとの間で変換します。日替わり、夏時間の節約、地球の反対側の国からの統計情報を見ている人々などを処理するために、多くの問題を自分で解決します。

あなたの場合、 UTCでキャッシュを使用し、UTCで変換する要求を調整するだけで役立ちます。 statを "今日"として保存しないで、00:00:00UTCから23:59:59UTCまで保管してください。誰かがニューヨークの今日の統計情報を求めたら、変換してください。

+0

アップヴォートの理由はここにはありません。ニューヨークでの日々のデータをどのように取得するかについては、実際には5時間をシフトするだけで済むわけではないので、実際には触れていません。前回の5時間のデータが必要で、私の解決策で示唆したように、最後の5時間を差し引く必要があります。 – aleemb

+0

このソリューションではバケツサイズについて話したことはありません。私は、現地時刻ではなく、UTCでバケツを00:00〜23:59にするように指示しています。ユーザーインターフェイスでどのような統計が提案されているかについての詳細が不十分なため、最終的なバケットサイズを提案することはできません。 – lpfavreau

+0

@aleemb:まったく同じことを提案してバケツサイズについての議論を拡大したので、downvoteの理由はありません。 – lpfavreau

0

私が見る限り、データウェアハウスシステムのストレージ部分を探しています(レポートはフロントエンドになります)。

実際に、商用システムでは、あなたが記述したキャッシュがあります。テーブルを事前に集めてキャッシュを作成します。クエリを高速化する唯一の方法は、データベースシステムをそれらのために少なくすることです。これは少ないデータ量を意味し、データの反復処理に要する時間が短縮され、インデックス内のデータ量が減少します。

私は、「40キャッシュソリューション」(実際には24以上のタイムゾーンがあります)を提案します。データのコピーを作成することによって、ソートキューを並行して並列化できるはずです。

これを行うもう1つの方法は、時単位でキャッシュし、時間を日数に集計することです(タイムゾーンでこれが必要な場合は30分)。これは、毎日のキャッシュより細かい粒度でキャッシュしますが、元のデータより細かい粒度でキャッシュすることを意味します。

関連する問題