9

約200人のユーザーからの約20種類のドキュメントで構成される単一のデータベース(300MBと42,924のドキュメント)があります。ドキュメントのサイズは、数バイトから数キロバイト(150KB程度)までさまざまです。

サーバーがアンロードされると、次のレプリケーションフィルター機能が完了するまでに約2.5分かかります。サーバーがロードされると、10分以上かかります。

これらの時間が予想されるかどうかについて誰かがコメントできますか?そうでない場合は、パフォーマンスを向上させるためにどのように最適化するかを提案できますか?

function(doc, req) {
    acceptedDate = true;
    if(doc.date) {
        var docDate = new Date();
        var dateKey = doc.date;
        docDate.setFullYear(dateKey[0], dateKey[1], dateKey[2]);

        var reqYear = req.query.year;
        var reqMonth = req.query.month;
        var reqDay = req.query.day;
        var reqDate = new Date();
        reqDate.setFullYear(reqYear, reqMonth, reqDay);

        acceptedDate = docDate.getTime() >= reqDate.getTime();
    }

    return doc.user_id && doc.user_id == req.query.userid && doc._id.indexOf("_design") != 0 && acceptedDate; 
}
4

1 に答える 1

12

フィルタリングされた複製は、フェッチされたドキュメントごとに複雑なロジックを実行して複製するかどうかを決定するため、動作が遅くなります。

  1. CouchDB は次のドキュメントを取得します。
  2. フィルター関数を適用する必要があるため、ドキュメントは JSON に変換されます。
  3. JSON 化されたドキュメントは stdio を介してクエリ サーバーに渡されます。
  4. クエリ サーバーはドキュメントを処理し、JSON からデコードします。
  5. ここで、クエリ サーバーがルックアップを実行し、 CouchDB に値trueまたは値を返すフィルター関数を実行します。false
  6. 結果がtrueドキュメントの場合、複製されます。
  7. p.1 に移動し、すべてのドキュメントをループします。

フィルタリングされていない複製の場合、このリストを取得し、p.2-5 を破棄して、p.6 が常にtrue結果になるようにします。このオーバーヘッドにより、レプリケーション プロセス全体が遅くなります。

フィルタリングされたレプリケーションの速度を大幅に改善するには、 Erlang ネイティブ サーバー経由で Erlang フィルターを使用できます。これらは CouchDB 内で実行され、標準入出力インターフェースを通過せず、JSON デコード/エンコードのオーバーヘッドは適用されません。

注意: Erlang クエリ サーバーは JavaScript のようにサンドボックス内では実行されないため、実行するコードを本当に信頼する必要があります。

別のオプションは、フィルター関数を最適化することです。たとえば、オブジェクトの作成やメソッド呼び出しを減らしますが、実際にはこれではあまり勝ちません。

于 2012-11-02T13:06:15.973 に答える