Назад | Перейти на главную страницу

Блокировка MongoDB - очень, очень, медленно читается

Это результат 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 все еще принимает соединения, он просто не позволяет нам делать запросы, пока выполняются вышеуказанные операции.

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

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

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

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

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

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