【问题标题】:Should I increase the size of my MongoDB oplog file?我应该增加我的 MongoDB oplog 文件的大小吗?
【发布时间】:2012-11-06 00:41:55
【问题描述】:

我知道 oplog 文件会将多个更新拆分为单个更新,但是批量插入呢?那些也分成单独的插入物吗?

如果我有一个写入密集型集合,大约每 30 秒插入约 20K 文档批次,我/我是否应该考虑将我的 oplog 大小增加到超出默认值?我有一个 3 成员副本集,mongod 在 64 位 Ubuntu 服务器上运行,Mongodb 数据位于 100GB 卷上。

这里有一些可能有用也可能没用的数据:

    gs_rset:PRIMARY> db.getReplicationInfo()
    {
        "logSizeMB" : 4591.3134765625,
        "usedMB" : 3434.63,
        "timeDiff" : 68064,
        "timeDiffHours" : 18.91,
        "tFirst" : "Wed Oct 24 2012 22:35:10 GMT+0000 (UTC)",
        "tLast" : "Thu Oct 25 2012 17:29:34 GMT+0000 (UTC)",
        "now" : "Fri Oct 26 2012 19:42:19 GMT+0000 (UTC)"
    }
    gs_rset:PRIMARY> rs.status()
    {
        "set" : "gs_rset",
        "date" : ISODate("2012-10-26T19:44:00Z"),
        "myState" : 1,
        "members" : [
            {
                "_id" : 0,
                "name" : "xxxx:27017",
                "health" : 1,
                "state" : 1,
                "stateStr" : "PRIMARY",
                "uptime" : 77531,
                "optime" : Timestamp(1351186174000, 1470),
                "optimeDate" : ISODate("2012-10-25T17:29:34Z"),
                "self" : true
            },
            {
                "_id" : 1,
                "name" : "xxxx:27017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 76112,
                "optime" : Timestamp(1351186174000, 1470),
                "optimeDate" : ISODate("2012-10-25T17:29:34Z"),
                "lastHeartbeat" : ISODate("2012-10-26T19:44:00Z"),
                "pingMs" : 1
            },
            {
                "_id" : 2,
                "name" : "xxxx:27017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 61301,
                "optime" : Timestamp(1351186174000, 1470),
                "optimeDate" : ISODate("2012-10-25T17:29:34Z"),
                "lastHeartbeat" : ISODate("2012-10-26T19:43:59Z"),
                "pingMs" : 1
            }
        ],
        "ok" : 1
    }

gs_rset:PRIMARY> db.printCollectionStats()
dev_fbinsights
{
    "ns" : "dev_stats.dev_fbinsights",
    "count" : 6556181,
    "size" : 3117699832,
    "avgObjSize" : 475.53596095043747,
    "storageSize" : 3918532608,
    "numExtents" : 22,
    "nindexes" : 2,
    "lastExtentSize" : 1021419520,
    "paddingFactor" : 1,
    "systemFlags" : 0,
    "userFlags" : 0,
    "totalIndexSize" : 1150346848,
    "indexSizes" : {
        "_id_" : 212723168,
        "fbfanpage_id_1_date_1_data.id_1" : 937623680
    },
    "ok" : 1
}

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    当前主节点的 oplog 越大,副本集成员能够保持离线状态而不会落后于主节点的时间窗口就越长。如果确实落后太多,则需要完全重新同步。

    db.getReplicationInfo() 返回的字段 timeDiffHours 报告 oplog 当前记录了多少小时的数据。在 oplog 填满并开始覆盖旧条目后,开始监视此值。尤其是在写负载很重的情况下(其中值会降低)。如果您假设它永远不会低于 N 小时,那么 N 是您可以容忍副本集成员暂时离线的最大小时数(例如,用于定期维护,或进行离线备份,或在硬件情况下)失败)而不执行完全重新同步。然后,该成员将能够在重新联机后自动赶上主节点。

    如果您对 N 有多低不满意,那么您应该增加 oplog 的大小。这完全取决于您的维护窗口时间长短,或者您或您的运营团队对灾难场景的响应速度。为它分配多少磁盘空间,除非您对该空间有迫切的需求。

    我在这里假设您在所有副本集成员上保持 oplog 的大小不变,这是合理的做法。如果没有,那么就规划oplog最小的副本集成员被选为primary的场景。

    (回答你的另一个问题:与多次更新类似,批量插入也被扇出到 oplog 中的多个操作中)

    编辑:请注意,数据导入和批量插入/更新将数据写入 oplog 的速度明显快于您的应用程序在典型的高负载下的速度。重申一下:请保守估计填充 oplog 需要多长时间。

    【讨论】:

    • 感谢杰森的回复。此外,我实际上保持所有 oplog 的大小相同。
    • 仅供参考:要查看 oplog 的最大大小,在 mongo js shell 中,执行use local 然后执行db.oplog.rs.stats() 并查找max。上面的logSizeMB 字段是实际分配的存储大小,而不是最大值。请注意,max 不遵守“scale factor”(例如:db.oplog.rs.stats(1024))。这是 mongod 2.0.4 版
    • 更改 oplog 大小是一个HASSLE,所以创建它们足够大,以使用守护进程标志“-oplogSize 4096”或类似数字开始。 注意如果你在一个盒子上有多个分片(就像我一样),oplogsize 的默认值是磁盘大小的 5%(NOT 可用空间,总大小)意味着在您添加任何数据之前,一个盒子上的 20 个分片会填满 100% 的空间。
    猜你喜欢
    • 2020-02-29
    • 2016-07-14
    • 2023-02-09
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多