2

圧縮されたhtmlファイルを保存するためにmongodbを使用しています。基本的に、mongod の完全なドキュメントは次のようになります。

{'_id': 1, 'p1': data, 'p2': data2, 'p3': data3}

ここで、data、data1、data3 は次のとおりです。bson.binary.Binary(zlib_compressed_html)

私は 1200 万の ID を持っており、dataX はそれぞれ平均 90KB であるため、各ドキュメントには少なくとも size があり180KB + sizeof(_id) + some_overheadます。

合計データ サイズは少なくとも 2 TB になります。

注目したいの'_id'はインデックスです。

次の方法でmongoに挿入します。

def _save(self, mongo_col, my_id, page, html):
    doc = mongo_col.find_one({'_id': my_id})
    key = 'p%d' % page
    success = False
    if doc is None:
        doc = {'_id': my_id, key: html}
        try:
            mongo_col.save(doc, safe=True)
            success = True
        except:
            log.exception('Exception saving to mongodb')
    else:
        try:
            mongo_col.update({'_id': my_id}, {'$set': {key: html}})
            success = True
        except:
            log.exception('Exception updating  mongodb')
    return success

ご覧のとおり、最初にコレクションを検索して、my_id を持つドキュメントが存在するかどうかを確認します。

存在しない場合は作成してmongoに保存し、そうでない場合は更新します。

上記の問題は、非常に高速でしたが、ある時点で非常に遅くなったことです。

私はあなたにいくつかの数字を与えます:

速いときは 4 時間あたり 1.500.000、その後は 4 時間あたり 300.000 でした。

これが速度に影響すると思われます:

ノート

そのドキュメントに割り当てられたスペースを超えてドキュメントのサイズを増やす更新操作を実行すると、更新操作によってディスク上のドキュメントが再配置され、更新の種類に応じてドキュメント フィールドの順序が変更される場合があります。

As of these driver versions, all write operations will issue a getLastError command to confirm the result of the write operation: { getLastError: 1 } Refer to the documentation on write concern in the Write Operations document for more information.

上記は以下のものです: http://docs.mongodb.org/manual/applications/update/

私が言っているのは、次のようになる可能性があるからです。

{'_id: 1, 'p1': some_data}, ...., {'_id': 10000000, 'p2': some_data2}, ...{'_id': N, 'p1': sd3}

上記の _save メソッドを次のように呼び出しているとします。

_save(my_collection, 1, 2, bin_compressed_html)

次に、ドキュメントを _id 1 で更新する必要があります。しかし、その mongo サイトの場合、ドキュメントにキーを追加しているため、収まらず、ドキュメントを再配置する必要があります。

ドキュメントをコレクションの最後に移動することができますが、これはディスク上で非常に遠くにある可能性があります。これは物事を遅くすることができますか?

または、速度の低下はコレクションのサイズと関係がありますか?

いずれにせよ、私の構造を次のように変更する方が効率的だと思います。

{'_id': ObjectId, 'mid': 1, 'p': 1, 'd': html}

ここで、mid=my_id、p=ページ、d=圧縮された html

挿入のみを行うように _save メソッドを変更しますか?

def _save(self, mongo_col, my_id, page, html):
    doc = {'mid': my_id, 'p': page, 'd': html}
    success = False
    try:
        mongo_col.save(doc, safe=True)
        success = True
    except:
        log.exception('Exception saving to mongodb')
    return success

このようにして、更新(ディスク上の再配置)と1回のルックアップ(find_one)を回避しますが、ドキュメントは3倍になり、2つのインデックス( _id と mid )を持つことになります。

何を指示してるんですか?

4

2 に答える 2

0

新しい属性として html のページを追加し続けると、ドキュメントの再配置が問題になる可能性があります。ページを新しいコレクションに移動して、それぞれに 1 つのレコードを追加するだけで本当に問題になるでしょうか? また、MongoDB があなたのユースケースに適しているとは本当に思いません。たとえば、 Redisの方がはるかに効率的です。もう 1 つ気を付けなければならないことは、_id インデックスに十分な RAMを用意することです。db.mongocol.stats() を使用してインデックス サイズを確認します。

于 2012-11-30T14:47:13.320 に答える
0

新しいドキュメントを MongoDB に挿入すると、ドキュメントは特定のポイントまで移動しなくても大きくなる可能性があります。DB は着信データを分析し、ドキュメントにパディングを追加するためです。したがって、ドキュメントの移動を少なくして、次の 2 つのことを行うことができます。

  1. パディング係数を手動で微調整する

  2. 各ドキュメントにスペース (属性) を事前に割り当てます。

パディング係数の詳細については、パディングに関する記事またはMongoDB ドキュメントを参照してください。

ところで。新しいドキュメントを作成するために保存を使用する代わりに、_id が既に存在する場合は重複キー エラーをスローする .insert() を使用する必要があります (.save() はドキュメントを上書きします)。

于 2012-12-06T10:33:54.797 に答える