2

我使用 mongodb 来存储压缩的 html 文件。基本上,一个完整的 mongod 文档是这样的:

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

其中数据,数据1,数据3是:bson.binary.Binary(zlib_compressed_html)

我有 1200 万个 id,dataX 每个平均 90KB,所以每个文档至少有 size 180KB + sizeof(_id) + some_overhead

总数据大小至少为 2TB。

我想注意的'_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=page, d=compressed 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

这样我就避免了更新(所以在磁盘上重新排列)和一次查找(find_one),但是文档将是 3x mores,我将有 2 个索引( _id 和 mid )。

你有什么建议?

4

2 回答 2

0

When inserting new Documents into MongoDB, a Document can grow without moving it up to a certain point. Because the DB is analyzing the incoming Data and adds a padding to the Document. So do deal with less Document movements you can do two things:

  1. manually tweaking the padding factor

  2. preallocate space (attributes) for each document.

See Article about Padding or MongoDB Docs for more Information about the padding factor.

Btw. insetad of using save for creating new documents, you should use .insert() which will throw a duplicate key error if the _id is already there (.save() will overwrite your document)

于 2012-12-06T10:33:54.797 回答
0

如果您继续将 html 页面添加为新属性,则文档重定位可能会成为问题。将页面移动到一个新集合中,您可以简单地为它们每个添加一条记录,这真的是一个问题吗?此外,我真的不认为 MongoDB 非常适合您的用例。例如, Redis会更有效率。您应该注意的另一件事是为您的 _id 索引提供足够的内存。使用 db.mongocol.stats() 检查索引大小。

于 2012-11-30T14:47:13.320 回答