5

多数のユーザートランザクションを分析し、集約された測定値(傾向など)を生成するシステムを設計しています。システムは高速に動作し、堅牢でスケーラブルである必要があります。システムはJavaベースです(Linux上)。

データは、ユーザートランザクションのログファイル(CSVベース)を生成するシステムから到着します。システムは毎分ファイルを生成し、各ファイルにはさまざまなユーザーのトランザクション(時間でソート)が含まれ、各ファイルには数千人のユーザーが含まれる場合があります。

CSVファイルのサンプルデータ構造:

10:30:01、ユーザー1、...
10:30:01、ユーザー1、...
10:30:02、ユーザー78、...
10:30:02、ユーザー2、...
10: 30:03、ユーザー1、...
10:30:04、ユーザー2、
...。。。

私が計画しているシステムは、ファイルを処理し、リアルタイムで分析を実行する必要があります。入力を収集し、それをいくつかのアルゴリズムや他のシステムに送信し、計算結果をデータベースに保存する必要があります。データベースは実際の入力レコードを保持しませんが、トランザクションに関する高レベルの集約分析のみを保持します。たとえば、トレンドなど。

私が使用することを計画している最初のアルゴリズムは、最良の操作のために少なくとも10ユーザーレコードを必要とします。5分後に10レコードが見つからない場合は、利用可能なデータを使用する必要があります。

実装にはStormを使用したいのですが、この議論は可能な限り設計レベルに残したいと思います。

システムコンポーネントのリスト:

  1. 着信ファイルを毎分監視するタスク。

  2. ファイルを読み取り、解析して、他のシステムコンポーネントやアルゴリズムで使用できるようにするタスク。

  3. ユーザーのために10レコードをバッファリングするコンポーネント(5分以内)。10レコードが収集されたとき、または5分が経過したとき、さらに処理するためにデータをアルゴリズムに送信します。アルゴリズムに少なくとも10個のレコードを提供する必要があるため、ストームフィールドグループ化(同じタスクが同じユーザーに対して呼び出されることを意味します)を使用して、タスク内の10個のユーザーのレコードのコレクションを追跡することを考えました。もちろん計画していますこれらのタスクのいくつかを持つために、それぞれがユーザーの一部を処理します。

  4. 単一のトランザクションで機能する他のコンポーネントがあります。それらについては、(他のタスクと並行して)解析されるときに各トランザクションを受け取る他のタスクを作成することを計画しています。

#3であなたの助けが必要です。

そのようなコンポーネントを設計するためのベストプラクティスは何ですか?ユーザーごとに10レコードのデータを維持する必要があることは明らかです。キーバリューマップが役立つ場合があります。マップをタスク自体で管理するか、分散キャッシュを使用する方がよいでしょうか。たとえば、RedisはKey Value Storeです(これまで使用したことはありません)。

ご協力いただきありがとうございます

4

2 に答える 2

5

私はかなりの量のredisを扱っていました。そこで、redis の使用に関するあなたの考えについてコメントします

#3には3つの要件があります

  1. ユーザーごとのバッファ

  2. 10タスクのバッファ

  3. 5分ごとに失効する必要があります

1. ユーザーごとのバッファ: Redis は単なるキー値ストアです。さまざまなデータ型をサポートしていますが、それらは常に STRING キーにマップされた値です。したがって、ユーザーごとのバッファーが必要な場合に備えて、ユーザーを一意に識別する方法を決定する必要があります。redis では、キーの新しい値をオーバーライドしてもエラーが発生しないためです。1つの解決策は、書き込み前に存在を確認することです。

2. 10 個のタスクのバッファ:もちろん、redisでキューを実装できます。ただし、そのサイズを制限するのはあなた次第です。例: LPUSHand LTRIMor usingLLENを使用して長さを確認し、プロセスをトリガーするかどうかを決定します。このキューに関連付けられたキーは、パート 1 で決定したものでなければなりません。

3. バッファが 5 分で期限切れになる:これは最も困難な作業です。redis では、値が持つ基本的なデータ型に関係なく、すべてのキーにexpiry. しかし、有効期限のプロセスは静かです。キーの有効期限が切れても通知されません。したがって、このプロパティを使用すると、暗黙のうちにバッファーが失われます。これを回避する方法の 1 つは、インデックスを作成することです。つまり、インデックスはタイムスタンプを、そのタイムスタンプ値ですべて期限切れにする必要があるキーにマップします。次に、バックグラウンドで毎分インデックスを読み取り、手動で [読み取り後に] キーを redis から削除し、バッファ データを使用して目的のプロセスを呼び出すことができます。このようなインデックスを取得するには、Sorted Setsを参照してください。タイムスタンプはどこscoreに設定されますかmemberそのタイムスタンプで削除したいキー[パート1で決定された、キューにマップされるユーザーごとの一意のキー]になります。zrangebyscore指定されたタイムスタンプを持つすべてのセットメンバーを読み取ることができます

全体:

Redis List を使用してキューを実装します。

LLEN を使用して、10 の制限を超えていないことを確認してください。

新しいリストを作成するときはいつでもCurrent Timestamp + 5 min、リストのキーとして Score と Value を使用して、インデックス [Sorted Set] にエントリを作成します。

LLEN が 10 に達したら、インデックス [ソート済みセット] とデータベース [キーの削除 -> リスト] からキーを読み取り、削除することを忘れないでください。次に、データを使用してプロセスをトリガーします。

1分ごとに現在のタイムスタンプを生成し、インデックスを読み取り、すべてのキーについてデータを読み取り、データベースからキーを削除してプロセスをトリガーします。

これが私の実装方法かもしれません。redis でデータをモデル化するための他のより良い方法があるかもしれません

于 2012-07-25T08:57:35.133 に答える