3

これは当たり前の質問のように聞こえるかもしれませんが、私はCouchDBを初めて使用するので、CouchDBの構造について、私が知らなかった状況を変える何かがあるかどうかを尋ねる価値があると思いました。私の手に負えない理由で、CouchDBからキューのような構造を構築する必要があります。簡単にするために、後で実行するジョブのIDをキューに入れているとしましょう。重複がないことに注意してください。

私はこれを構造化するための最良の方法が何であるかを理解しようとしています。私が現在見ているように、私にはいくつかの選択肢があります:

  1. キューアイテムをqueueIDをとしてデータベースにエントリとして_id保存し、デキューされたアイテムをdequeuedIDをを使用して同様のデータベースに保存します_id_id各データベースの各レコードには、(必須)と。以外の情報は含まれていません_rev
  2. 単一のキューイングデータベースがあり、そのデータベースには、が付いた_id = 'queue'1つのレコードと。が付いた1つのレコードが含まれます_id = 'dequeued'。2つのレコードのそれぞれの中に、任意の数のキーがあり、それぞれが実行される(またはすでに実行された)ジョブのIDになります。データベースでキーに関連付けられている値は無関係であり、ブール値である可能性があります。
  3. 単一のキューイングデータベースがあり、そのデータベース内に、という単一のレコードがありますqueue。そのレコード内に、2つのキーがあります:queuedequeued。これらの各キーには、関連する値として、任意の長さのジョブ実行IDのリストがあります。

1は2つのデータベースを必要とするため、少し望ましくありません。2は、リストアイテムを読み取ったり、変更を加えたりするために、キューまたはデキューされたアイテムのリスト全体をロードする必要があるため、不適切な選択だと思います。ただし、3は、IDのリスト全体をキーと値のペアではなく順序付きリストにすることができるという点で優れています。これにより、リストからランダムなアイテムを選択して、次に実行するジョブにすることが容易になります。キー名を実際に知る必要はありません(キー名がないため)。

最高のパフォーマンスを提供するものを探しています。これについて何か考えはありますか?

アップデート

将来この質問を読む人々のために、私はCouchDBキューイングモジュールを構築しました。これCouchQueueは進行中の作業です。

あなたはそれを得ることができますnpm install couchqueue

ここGithubを見てください(コメント、プルリクエストなどをお願いします) 。

4

2 に答える 2

1

キュー内の要素ごとに1つのドキュメントを使用し、1つのキューデータベースを保持します。

たとえば.created_at、ISO 8601形式のタイムスタンプを使用して、要素を並べ替えるフィールドをお勧めします。

.visibleフラグを使用して要素の表示を切り替えることができます。

このようなマップ/リデュースビューをお勧めします

function(doc) {
  if(doc.visible)
    emit(doc.created_at, doc)
}

これで、このビューをoldest-firstまたはnewest-first(?descending=true)のいずれかでクエリできます。を設定して更新することにより、要素に完了のマークを付けることができますvisible = false

AmazonSQSAPIと同じCouchDBキューCQSを作成しました。これは、チェックアウトされた状態のメッセージがタイムアウト期間キューに表示されない可能性があることを除いて、私が説明したものと似ています。私はCQSを本番環境で約2年間使用しており、何億もの更新があります。

于 2012-09-04T13:48:05.900 に答える
1

キューエントリごとに個別のドキュメントを使用することをお勧めします。これにより、競合を回避できます。

要素を挿入して取得するためのインターフェイス、、のキューが必要な場合、解決策は非常に単純な場合があります(、のリストが必要な場合、またはn番目の要素にアクセスする場合は、より複雑になります)。線形順序のスケジューリングアルゴリズム(FIFO、FILOなど)の場合、新しいドキュメントの挿入として実装できます。push()pop()top()next()push()

{ type: "queue", inserted: CURRENT_TIME, ... }

top()マップとして:

function (doc) {
  if (doc.type == "queue" && doc.inserted) {
    emit(doc.inserted, doc);
  }
}

集計として削減します(たとえば、FILOの場合は最大、FIFOの場合は最小)。のpop()表示を要求してtop()から、ドキュメントを削除できます。Map / Reduceは決定論的である必要があるため、ランダム要素を選択する場合は、(サーバーによって選択された)疑似ランダムに依存するようにreduceを作成できます_id

私は2つの問題を予想しています:

  1. 同時実行性に注意してください。2つのプロセスがで同じドキュメントを要求できますtop()。最初はの一部としてドキュメントを削除し、pop()2番目は削除されたドキュメントをフェッチしようとします。

  2. CouchDBが実際にドキュメントを削除することはなく、削除済みとしてマークするだけです。push()/ごとに追加および削除するとpop()、データベースが拡張されます。どういうわけかドキュメントを再利用する必要があります。おそらく、キューに挿入および削除されたり、並べ替えられたりするタスクのポーリングがあります。queued: true次に、で個別のドキュメントを作成する代わりに、タスクドキュメントに追加できますtype: "queue"

于 2012-08-30T10:13:36.093 に答える