MongoDB Locking - Очень, очень, медленно, чтобы читать

Это вывод из db.currentOp():

> db.currentOp()
{
    "inprog" : [
        {
            "opid" : 2153,
            "active" : false,
            "op" : "update",
            "ns" : "",
            "query" : {
                "name" : "Run_KPIS",
                "profile" : "totals"
            },
            "client" : ":34140",
            "desc" : "conn127",
            "threadId" : "0x7f1d0f03c700",
            "connectionId" : 127,
            "locks" : {
                "^cached_data" : "W"
            },
            "waitingForLock" : true,
            "numYields" : 0,
            "lockStats" : {
                "timeLockedMicros" : {

                },
                "timeAcquiringMicros" : {

                }
            }
        },
        {
            "opid" : 2154,
            "active" : false,
            "op" : "getmore",
            "ns" : "",
            "query" : {

            },
            "client" : ":34129",
            "desc" : "conn118",
            "threadId" : "0x7f1e32785700",
            "connectionId" : 118,
            "locks" : {
                "^cached_data" : "R"
            },
            "waitingForLock" : true,
            "numYields" : 0,
            "lockStats" : {
                "timeLockedMicros" : {

                },
                "timeAcquiringMicros" : {

                }
            }
        },
        {
            "opid" : 1751,
            "active" : true,
            "secs_running" : 98,
            "op" : "query",
            "ns" : "cached_data.webtraffic",
            "query" : {
                "mapreduce" : "webtraffic",
                "map" : function () {
        if (this.Pages)
            for (var i in this.Pages)
                if (i.match(/(\/blogs\/|\/news\/)/))
                    emit({
                        'page':i,
                        'profile':this.Profile
                    },this.Pages[i]);
    },
                "reduce" : function (k,vals) {
        for(var i=0,sum=0;i<vals.length;sum+=vals[i++]);
        return sum;
    },
                "out" : {
                    "inline" : 1
                },
                "query" : {
                    "$or" : [
                        {
                            "Profile" : "MEMBER"
                        },
                        {
                            "Profile" : "WEB"
                        }
                    ]
                }
            },
            "client" : ":34111",
            "desc" : "conn112",
            "threadId" : "0x7f1d1768d700",
            "connectionId" : 112,
            "locks" : {
                "^" : "r",
                "^cached_data" : "R"
            },
            "waitingForLock" : false,
            "msg" : "m/r: (1/3) emit phase M/R: (1/3) Emit Progress: 801/830 96%",
            "progress" : {
                "done" : 801,
                "total" : 830
            },
            "numYields" : 148,
            "lockStats" : {
                "timeLockedMicros" : {
                    "r" : NumberLong(183690739),
                    "w" : NumberLong(0)
                },
                "timeAcquiringMicros" : {
                    "r" : NumberLong(92296403),
                    "w" : NumberLong(0)
                }
            }
        }
    ]
}

У меня есть индексы для всех соответствующих коллекций, но все еще существует огромная задержка при чтении из нашей MongoDB, когда выполняются вышеуказанные операции.

Может потребоваться ~5 минут, чтобы база данных снова стала читаемой.

Будет ли приведенная выше функция уменьшения карты вызывать эту блокировку чтения? И если так, как я могу запустить неблокирующую карту уменьшений для коллекции?

Что странно, так это то, что MongoDB все еще принимает соединения, но не позволяет нам делать запросы во время выполнения вышеуказанных операций.

Отредактировано, чтобы сказать, что это - версия 2.4.1 Монго.

1 ответ

Решение

Прежде всего, здесь выполняется запрос. Он использует $or оператор над двумя значениями одного и того же поля. Если это типично, измените это на $in оператор (как рекомендуется здесь). Это должно значительно помочь - когда вы используете $ или тому подобное, вы выполняете два запроса параллельно и объединяете результаты, когда вы используете один запрос.

Далее, поскольку это встроенное задание Map Reduce, я бы порекомендовал запустить его на дополнительном устройстве (если вы этого еще не сделали), а другие приложения с требованиями в реальном времени выполнялись в другом месте. Вы можете сделать это различными способами, но наиболее гибкими являются настройки чтения на основе тегов.

С точки зрения интерпретации currentOp() На выходе заглавные буквы обозначают глобальные блокировки, и это то, что, вероятно, удерживает вещи (хотя они будут пытаться уступить), вы также можете видеть, что они потратили много времени, пытаясь получить блокировку в первую очередь. Я предполагаю, что это представляет собой большой просмотр таблицы данных, о которых идет речь, и что данные не все помещаются в ОЗУ и выгружаются с диска. Отсюда количество выходов для этого запроса (MongoDB будет пытаться выдавать всякий раз, когда обнаружит ошибку на диске).

Взгляните на страницу метрик неисправностей в MMS или mongostat, чтобы увидеть тенденцию, на самом деле MMS будет хорошим местом, чтобы получить представление о том, что происходит с течением времени в этом случае в целом.

Изменения с точки зрения $in выше, должно немного помочь в этом, но может только пнуть банку в будущем. Если вы собираетесь производить агрегацию больших объемов данных, либо они должны находиться в оперативной памяти, где такие вещи выполняются быстро, либо вам нужно перенести их на вторичный компьютер, чтобы медленный доступ к диску не затягивал все Это.

Другие вопросы по тегам