Mongodb плохая производительность - PullRequest
4 голосов
/ 30 января 2012

В настоящее время я использую mongodb и вижу очень низкую производительность запросов (это может занять несколько секунд).Сценарий выглядит следующим образом:

У меня есть документы структуры:

{_id:"xxx", userId:"yyy", a:1 ,b:2,  counter:1}    

В тесте:

"userId" value could be {1..200,000}
"a" values could be {1..30}
"b" values could be {1}

Таким образом, моя коллекция максимального размера будет6 000 000 В настоящее время для этой коллекции определены два индекса: default _id and useId

Бизнес-логика запрашивает все записи пользователя, а затем обновляет один конкретный, увеличивая счетчик (обновление запроса записывается как "_id").Также, если это новая сущность, есть запрос на вставку.

Я работаю с mongo 1.8.2 в Ubuntu с 8g ram

У меня есть мастер вторичных копий (все прогоны Монгос локальным дисковым хранилищем и в одной подсети с сервером Tomcat).Конечно, все чтения переходят на вторичное и пишут мастеру.Я не проверял шардинг, так как считаю, что 6 000 000 - это не огромная коллекция, не так ли?

Кроме того, я запускаю тест jmetter, который генерирует 500 запросов потоков одновременно с разными идентификаторами пользователя.

Когда я запускаю mongostat, я вижу, что% заблокирован очень высок (около 70%) после примерно5-10 минут загрузки. Я вижу, что qw (очередь на запись) равно 500 (как число моих открытых соединений). Когда я останавливаю сервер, монго занимает около 10-20 минут, чтобы выполнить все поставленные в очередь задачи

Я также запустил db.serverStatus () и объяснил, и результаты выглядят хорошо.когда я запускаю db.currentOp (), я вижу запросы, ожидающие блокировки «записи», у меня не может быть вывода currentOp в файл для полного его анализа, потому что я выполнил запрос из командной строки и имел только буфер окнаразмер.Но оттуда я увидел много обновлений (от _id), которые ожидают блокировки записи.

Буду признателен за любые идеи.

Еще одна вещь: так как каждый запрос может принести 30 документов, я думаю, что может быть различное моделирование следующим образом:

{_id:"xxx", userId:"123", bs: [{b:1, cs[{c:1, cnt:1}, {c:2, cnt:1}}, {{b:2 cs: [{c:1, cnt:1}]}}]

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

db.coll.update({userId:"123", "bs.b":1, "bs.cs.c":1}, {"bs.cs.cnt" : {$inc : 1})

У меня есть ошибка о недопустимой "точке" в запросе

Я уже довольно сложен,В ожидании хороших идей

Большое спасибо
Юлия

Ответы [ 2 ]

5 голосов
/ 30 января 2012

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

Команда db.serverStatus () может помочь вам диагностировать проблемы с глобальной блокировкой записи.

Вот несколько вещей, которые вы можете попробовать:

1) Убедитесь, что вы используете mongodb 2.0. У него лучший параллелизм, чем у старых версий. 2.2 будет иметь лучший параллелизм.

2) Поставьте ваши записи в очередь, чтобы они были асинхронными, и выполните их все, используя один поток. Это может помочь с параллелизмом, потому что обычно только один поток будет пытаться использовать глобальную блокировку записи одновременно.

3) Если вы используете последнюю версию и не можете сделать записи однопоточными, рассмотрите возможность использования шардинга. Осколок для гораздо большего, чем просто размер; это по крайней мере так же важно для параллелизма записи. Если вы осколка, то каждый сегмент будет работать в своем собственном процессе со своей глобальной блокировкой записи. Это позволит всей системе обрабатывать больше записей.

1 голос
/ 30 января 2012

Для получения обновлений проверьте позиционный оператор :

db.coll.update({userId:"123", "bs.b":1, "bs.cs.c":1}, {"bs.$.cs.$.cnt" : {$inc : 1})

Чтобы понять стоимость запроса, используйте объясните и убедитесь, что запросы эффективны.

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