7

どの NoSQL を選択するかについてのさらに別の質問です。ただし、この種の目的、メッセージの保存を求めている人はまだ見つかりません...

私は Erlang チャット サーバーを作成しました。既に MySQL を使用して、フレンド リストと "JOIN が必要" な情報を保存しています。

私はメッセージを保存したいと思います(そのユーザーはオフラインだったので受信していません...)、それらを取得します。

私は NoSQL を事前に選択しました。MongoDB のようなものは RAM 指向のパラダイムであるため使用できず、他のようにクラスター化できません。リストを 3 つの選択肢に絞りました。

  • Hbase
  • リヤク
  • カサンドラ

私は彼らのモデルがまったく異なっていることを知っています.1つはキー/値を使用し、もう1つはSuperColumnsとcoを使用しています.

これまでは、Erlang 用の安定したクライアント ライブラリである Riak を好んで使用していました。

Cassandra を Thrift で使用できることはわかっていますが、Erlang ではあまり安定していないようです (これについてはあまり良い結果が得られていません)。

私は今のところ HBase について何も知りません。HBase が存在し、Cassandra や Riak のような Dynamo をベースにしていることだけは知っています。

だからここに私がする必要があるものがあります:

  • 登録ユーザーごとに 1 ~ X 件のメッセージを保存します。
  • ユーザーごとに保存されたメッセージの数を取得します。
  • ユーザーからのすべてのメッセージを一度に取得します。
  • ユーザーからのすべてのメッセージを一度に削除します。
  • X か月より前のすべてのメッセージを削除する

今のところ、私はこれらの NoSQL DB にまったく慣れていません。私は常に MySQL の愛好家でした。これが、初心者としてこの質問をする理由です。私よりも多くの経験を持っている人が、どちらが優れているかを選択するのを手伝ってくれませんか? 、そして、面倒なことをせずにやりたいことをすべてやらせてくれます...

ありがとう !

4

3 に答える 3

7

Cassandra や Hbase について話すことはできませんが、Riak の部分について話させてください。

はい、Riak はあなたのシナリオに適しています (いくつかの企業やソーシャル ネットワークが同様の目的で Riak を使用しているのを見てきました)。

これを実装するには、単純な Riak キー/値操作と、ある種のインデックス エンジンが必要です。オプションは次のとおりです (大まかな優先順):

  1. CRDT セット。1-N コレクションのサイズが適切なサイズである場合 (たとえば、ユーザーあたりのメッセージが 50 未満であるなど)、子コレクションのキーをCRDT Set Data Typeに格納できます。

  2. リアク検索。コレクションのサイズが大きく、特に任意のフィールドでオブジェクトを検索する必要がある場合は、Riak Searchを使用できます。バックグラウンドで Apache Solr を起動し、定義したスキーマに従ってオブジェクトのインデックスを作成します。非常に優れた検索、集計と統計、地理空間機能などを備えています。

  3. セカンダリ インデックスeLevelDB ストレージ バックエンド上で Riak を実行し、セカンダリ インデックス(2i) 機能を有効にすることができます。

いくつかのパフォーマンス テストを実行して、最速のアプローチを選択します。

スキーマに関しては、ユーザー バケットとメッセージ バケットの 2 つのバケット (説明したセットアップ用) を使用することをお勧めします。

メッセージ バケットにインデックスを付けます。(検索インデックスをそれに関連付けるか、2i を介して user_key を格納することにより)。これにより、必要なすべての操作を実行できます (メッセージ ログがメモリに収まる必要はありません)。

  • 登録ユーザーごとに 1 から X のメッセージを保存 - ユーザー オブジェクトを作成してユーザー キーを取得すると、ユーザーごとに任意の量のメッセージを保存するのは簡単です。それらはメッセージ バケットに直接書き込まれ、各メッセージは適切な user_key を保存します。二次索引として。
  • ユーザーごとに保存されたメッセージの数を取得します- 問題ありません。ユーザーに属するメッセージ キーのリストを取得します (検索クエリを使用するか、キーを保持している Set オブジェクトを取得するか、user_key に対する 2i クエリを使用します)。これにより、クライアント側でカウントを取得できます。
  • ユーザーからのすべてのメッセージを一度に取得する- 前の項目を参照してください。ユーザーに属するすべてのメッセージのキーのリストを取得し (Search、Sets、または 2i を介して)、各キーの値をマルチフェッチすることにより、それらのキーの実際のメッセージを取得します (すべての公式 Riak クライアントにはmultiFetch機能があります。 -側)。
  • ユーザーからのすべてのメッセージを一度に削除する- 非常によく似ています。ユーザーのメッセージ キーのリストを取得し、クライアント側で削除を発行します。
  • X か月より古いすべてのメッセージを削除する- 日付にインデックスを追加できます。次に、X か月より前のすべてのメッセージ キーを (検索または 2i を介して) 取得し、それらに対してクライアント側の削除を発行します。
于 2012-10-21T19:43:13.607 に答える
0

Riakとはまったく話せませんが、Mongoを破棄するというあなたの選択に疑問を投げかけます。ジャーナル処理をオフのままにして、RAMを完全に使い果たしない限り、これは非常に優れています。

私はHBaseについてよく知っていますが、それはあなたのニーズを簡単に満たすように思えます。ユーザーの数によっては、やり過ぎかもしれません。ユーザーごとに多くのメッセージを保存するなどの機能を簡単にサポートし、書き込みの自動有効期限を設定する機能を備えています。スキーマをどのように設計するかによって、アトミックである場合とそうでない場合がありますが、ユースケースでは問題になりません。

欠点は、正しく設定するために多くのオーバーヘッドがあることです。HBaseを立ち上げる前に、Hadoopを理解し、HDFSを実行し、namenodeが信頼できることを確認する必要があります。

于 2012-04-23T18:38:02.193 に答える
0

Riak や Couchbase などの分散キー/値ストアを使用し、各ユーザーのメッセージ ログ全体を (バイナリ erlang 用語または JSON/BSON に) 1 つの値としてシリアル化することをお勧めします。

したがって、ユースケースでは次のようになります。

  • 登録ユーザーごとに 1 ~ X のメッセージを保存します。ユーザーがオンラインになると、ステートフルなgen_serverが生成されます。これは、ストレージから取得し、起動時にメッセージ ログ全体を逆シリアル化し、新しいメッセージを受信し、ログのコピーに追加し、セッションの終了時に終了します。変更されたログをシリアル化し、ストレージに送信します。
  • ユーザーごとに保存されたメッセージの数を取得します - ログアウト、デシリアライズ、カウントを取得します。または、別の k/v ペアでカウントを保存することもできます。
  • ユーザーからすべてのメッセージを一度に取得します。ストレージからプルするだけです。
  • 一度にユーザーからすべてのメッセージを削除します- ストレージから値を削除するだけです。
  • X か月より前のすべてのメッセージを削除します- 取得、フィルター処理、元に戻します。

明らかな制限 - メッセージ ログはメモリに収まる必要があります。

各メッセージを個別に保存することにした場合、取得後に分散データベースからメッセージを並べ替える必要があるため、メモリよりも大きなデータセットを処理することはほとんど役に立ちません。それが必要な場合 - いずれにせよ、よりトリッキーなスキームになってしまいます。

于 2012-04-25T12:08:22.983 に答える