【问题标题】:MongoDB data schema performanceMongoDB 数据架构性能
【发布时间】:2012-08-27 12:54:17
【问题描述】:

我试图了解 MongoDB 文档中数组和散列(据我的理解是通过数组实现)的内部分配和放置。

在我们的领域中,我们的文档包含数千到数十万个键值对,其逻辑分组深度可达 5-6 级(想想嵌套散列)。

我们用一个点表示键中的嵌套,例如,x.y.z,它在插入 MongoDB 时会自动变为:

{
    "_id" : "whatever",
    "x" : {
        "y" : {
            "z" : 5
        }
    }
}

最常见的操作是增加一个值,我们使用原子$inc 执行此操作,通常使用单个更新命令一次增加 1000+ 个值。随着时间的推移添加新密钥,但并不频繁,例如每天 100 次。

我想到另一种表示方法是不在名称中使用点,而是使用其他分隔符并创建一个平面文档,例如,

{
    "_id" : "whatever",
    "x-y-z" : 5
}

考虑到键值对的数量和$inc 更新和新键插入方面的使用模式,我正在寻找关于在以下方面权衡这两种方法的指导:

  • 磁盘空间开销

  • $inc 更新的性能

  • 新密钥插入的性能

【问题讨论】:

    标签: performance mongodb schema-design


    【解决方案1】:

    MongoDB 中文档的磁盘存储采用 BSON 格式。这里有BSON格式的详细说明: - http://bsonspec.org/#/specification

    虽然使用短键名可以节省一些磁盘空间(因为您可以通过查看规范看到,键名嵌入在文档中),但在我看来几乎没有净差异在使用的磁盘空间方面这两种设计之间 - 您使用分隔符 (-) 使用的额外字节通过不必为单独的键值使用字符串终止符而被买回。

    $inc 更新对于这两种格式应该花费几乎相同的时间,因为它们都将是内存中的操作。与从磁盘读取文档所需的时间相比,内存更新时间的任何改进都将是最小的舍入误差。

    新键插入的性能也应该几乎相同。如果添加新的键/值对使新文档足够小以适合磁盘上的旧位置,那么所发生的就是更新内存版本并写入日志条目。最终,内存版本将被写入磁盘。

    如果文档的增长超出了之前为其分配的空间,则新的键插入会带来更多问题。在这种情况下,服务器必须将文档移动到新位置并更新指向该文档的所有索引。这通常是一个较慢的操作,应该避免。但是,您正在讨论的架构更改不应影响文档移动的频率。再说一次,我认为这是一次洗礼。

    我的建议是使用最适合开发人员生产力的架构。如果您遇到性能问题,那么您可以就如何扩展系统或提高性能或两者兼而有之提出单独的问题。

    【讨论】:

    • 阅读 BSON 规范,看起来数组和文档不能有任何填充以供将来使用。你读它的方式是一样的吗?这似乎有点奇怪:要在 100K 的文档中添加一个键,他们可能需要修改磁盘上的许多块,因为多达 100K 的数据可能需要移动几个字节。
    • 您对规范是正确的。 MongoDB 可以为文档分配超出规范允许的额外空间(填充因子):mongodb.org/display/DOCS/Padding+Factor 此外,您可以在最初创建文档时使用手动填充因子:mongodb.org/display/DOCS/…
    • 在 MongoDB 中,当文档超出其插槽时,仅移动该文档:它周围的文档保持不变。当一个文档被移动时,它被移动到一个新的记录中,该记录足够大以容纳它的新大小(加上任何填充因子)。额外的 I/O 来自重新索引,而不是来自移动其他文档。
    • 所以这是令人恐惧的......我的评论不是关于移动文档,而是修改磁盘上的块。就我而言,文档占用磁盘上的许多块。使用没有内部填充的 BSON 编码格式,当文档更改时,您可能必须更新磁盘上的所有块。从 I/O 的角度来看,这相当昂贵。更好的方法是提出一种编码格式,该格式可以根据存储设备上的块大小进行调整,并且可以偶尔添加填充以最小化多块更新的可能性,例如,当通过以下方式删除数组元素时$拉。
    • 由于大多数应用程序都是读取密集型的,因此 MongoDB 的设计是读取优化的。在 I/O 方面,如果整个文档位于磁盘上的一个连续位置,则读取文档会更快:MongoDB 的设计反映了这一点。这样做的代价是仅执行那些使文档增长的写入时对 I/O 的要求略高。这种设计在实践中似乎运作良好。 CF Amdhal 定律和 Donald Knuth 关于过早优化
    猜你喜欢
    • 2016-02-09
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多