6

私は現在Nodeアプリを作成しており、スケーリングを先取りすることを考えています。私が理解しているように、水平スケーリングは、より多くの同時リクエストを処理するためにアプリケーションをスケールアップする簡単な方法の1つです。私の作業コピーは現在、バックエンドでMongoDbを使用しています。

したがって、私の質問は次のとおりです。順序を厳密に維持する必要があるリンクリストに似たデータ構造があります。私の(想像上の)懸念は、複数のノードインスタンスを介してデータベースに競合状態が発生した場合、リンクリストの解決が正しくない可能性があることです。

例を挙げると、このリストa->bを持つサーバーを想像してみてください。インスタンス1はオブジェクトcに付属し、インスタンス2はオブジェクトdに付属します。両方のインスタンスがa->bを読み取り、独自のオブジェクトをリストに追加することを決定する競合状態が存在する可能性があります。インスタンス1は、挿入がa-> b-> cであると想定し、インスタンス2は、データベースが実際にa-> b-> c-> dを保持している場合、それがa->b->dであると想定します。

一般に、これは楽観的ロックの仕事のように聞こえますが、私が理解しているように、MongoDBもRedis(私が検討している他のデータベース)もSQL方式でトランザクションを実行しません。

したがって、私は解決策が以下のいずれかであると想像します:

  1. フラグを使用して、MongoDBで独自のトランザクションを実装します。クライアントはロック変数に対してfindAndModifyを実行し、成功した場合は操作を実行します。失敗した場合、クライアントは特定のタイムアウト後に再試行します。

  2. 同じ効果を実現するには、Redisトランザクションとpubsubを使用します。これを行う方法はまだ正確にはわかりませんが、もっともらしいと思われます。

  3. ある種のスマートな負荷分散を実装します。複数のクライアントが同じアイテムを操作している場合は、それらを同じインスタンスにルーティングします。JSはシングルスレッドなので、問題は解決します。残念ながら、私はそれに対する簡単な解決策を見つけられませんでした。

上記を達成するためのより良い、よりエレガントな方法が存在すると確信しており、解決策や提案を聞いてみたいと思います。ありがとうございました!

4

3 に答える 3

0

新しく変更されたドキュメントを返すときにアトミックな変更を保証するmongodbのfindAndModifyコマンドが必要です。変更はシリアルであり、アトミックインスタンス1はa-> b-> cであり、インスタンス2はa-> b->c->dであるため

乾杯

于 2012-05-07T07:41:14.600 に答える
0

リストに新しい要素を追加するだけの場合は、Redisリストを使用して、追加するすべての値に時間を含めることができます。リストはredisでソートされていない可能性がありますが、取得するとすぐにソート可能である必要があります。

于 2012-05-07T15:38:50.190 に答える
0

私が正しく理解していて、リストが1つのドキュメントとして保存されている場合は、行のバージョン管理を検討している可能性があります。したがって、バージョンを処理するプロパティをドキュメントに追加します。更新するときは、バージョンを増やす(または変更する)と、条件付き更新を行います。

// update(condition、value)

update({バージョン:whateverYouReceivedWhenYouDidFind}、newValue)

それが役に立てば幸い。ガス

于 2012-05-24T17:42:05.120 に答える