mongodb низкая производительность запросов и оценки профилировщика очень высоки - PullRequest
1 голос
/ 05 марта 2020

Моя база данных mongodb имеет размер около 50 Ги. Есть приблизительно 45K коллекций, варьирующихся по размеру. самый большой имеет порядка <1 миллиона документов. </p>

Я использую версию mongodb 3.6.8 в AWS на r5.xlarge (32 Ги памяти, 4 vCPU) с SSD-диском 500Gi gp2, установленным в качестве постоянного тома. Он не огражден, но реплицируется с 1 основным и 2 вторичными узлами.

Большую часть времени запросы выполняются достаточно хорошо. Тем не менее, очень часто запросы (вставки, обновления, выборки - это не имеет значения) занимает «очень много времени» для завершения. Я пытаюсь выяснить, что является причиной этого.

Я включил профилирование для запросов, которые занимают более 10 секунд.

Вот пример, который поражает воображение. Это обновление коллекции с 5 документами, где квалификация находится в свойстве _id. Требуется 20 секунд, чтобы бежать. Профилировщик показывает:

{
    "op" : "update",
    "ns" : "bar.PumpStatus__PumpEventDrivenAppNS",
    "command" : {
        "q" : {
            "_id" : ObjectId("5e43f4b9aae591154193999a")
        },
        "u" : {
            "$inc" : {
                "foo_version" : 1
            },
            "$set" : {
                "PumpId" : "Pump1",
                "Temp" : NumberLong(197),
                "RPMS" : NumberLong(3885),
                "Time" : ISODate("2020-03-04T20:39:11.065Z"),
                "foo_modifiedAt" : ISODate("2020-03-04T20:39:11.946Z"),
                "foo_modifiedBy" : "439b96af-558e-4372-a7b9-d245f48d3d3d"
            }
        },
        "multi" : true,
        "upsert" : false
    },
    "keysExamined" : 1,
    "docsExamined" : 1,
    "nMatched" : 1,
    "nModified" : 1,
    "writeConflicts" : 1,
    "numYield" : 1,
    "locks" : {
        "Global" : {
            "acquireCount" : {
                "r" : NumberLong(3),
                "w" : NumberLong(3)
            }
        },
        "Database" : {
            "acquireCount" : {
                "w" : NumberLong(3)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "w" : NumberLong(2)
            }
        },
        "oplog" : {
            "acquireCount" : {
                "w" : NumberLong(1)
            }
        }
    },
    "millis" : 20001,
    "planSummary" : "IDHACK",
    "execStats" : {
        "stage" : "UPDATE",
        "nReturned" : 0,
        "executionTimeMillisEstimate" : 20008,
        "works" : 3,
        "advanced" : 0,
        "needTime" : 1,
        "needYield" : 1,
        "saveState" : 1,
        "restoreState" : 1,
        "isEOF" : 1,
        "invalidates" : 0,
        "nMatched" : 1,
        "nWouldModify" : 1,
        "nInvalidateSkips" : 0,
        "wouldInsert" : false,
        "fastmodinsert" : false,
        "inputStage" : {
            "stage" : "IDHACK",
            "nReturned" : 1,
            "executionTimeMillisEstimate" : 18351,
            "works" : 1,
            "advanced" : 1,
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 3,
            "restoreState" : 2,
            "isEOF" : 1,
            "invalidates" : 0,
            "keysExamined" : 1,
            "docsExamined" : 1
        }
    },
    "ts" : ISODate("2020-03-04T20:39:31.948Z"),
    "client" : "10.10.158.164",
    "appName" : "io.myorg.mongodb",
    "allUsers" : [
        {
            "user" : "foo",
            "db" : "bar"
        }
    ],
    "user" : "foo@bar"
}

mongodb оценка того, что для поиска документа с помощью IDHACK потребуется 18,351 секунды и что общее выполнение займет 20,008 секунды. И вот, время казни наступило в 20.001.

Мне трудно поверить в эти цифры. можно ли им доверять? и если так, что могло бы произойти, чтобы вызвать такое медленное время выполнения?

коллекция очень мала, ожидаемое время ожидания блокировки отсутствует, если я запускаю эквивалентный поиск вручную, он мгновенно возвращается. насколько я могу судить, метрики CloudWatch для тома не указывают на очень медленные операции чтения или записи. задержки минимальны, и количество операций ввода-вывода в секунду не достигает предела.

области, которые, как я знаю, могут быть улучшены:

  • позволяют directoryForIndexes разделять коллекции и индексы на 2 тома
  • используйте XFS на томе
  • убедитесь, что огромные страницы отключены (я думаю, что они есть)

Я скептически отношусь к тому, что любое из вышеперечисленного уменьшит боль. я подозреваю, что я делаю что-то (еще) совершенно неправильно c.

есть мысли о том, что здесь может происходить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...