圧縮された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 )を持つことになります。
何を指示してるんですか?