Подтвердить что ты не робот

Проблемы с производительностью NodeJS + Mongodb

У меня есть приложение nodejs + mongodb, подобное:

var dbConfig = new mongo.Server(config.db.host, config.db.port, {auto_reconnect: true, poolSize: 20});

var db = new mongo.Db(config.db.name, dbConfig);

при бенчмаркинге (с использованием apache ab) обнаружилось, что он борется (время >= 1 с), когда параллельные соединения составляют > 20 (даже два или более параллельных соединения, по-видимому, увеличивают время линейно):

[
    {
        "key": "mongoQuery1",
        "min": 2,
        "max": 598,
        "mean": 387.60683760683764,
        "sd": 134.56045668980255,
        "variance": 18106.51650456823
    },
    {
        "key": "mongoQuery2",
        "min": 8,
        "max": 149,
        "mean": 73.14120370370358,
        "sd": 25.141715811881994,
        "variance": 632.1058739654371
    },
    ...
]

Вышеприведенный результат с сервера профилирования, который я использовал для сбора информации профилирования из приложения node. Итак, в основном, я сделал такие вещи, чтобы профилировать приложение:

var start = new Date().getTime();

db.collection('TheCollection', query, function(err, col) {
  col.find(query).toArray(function(err, items) {
    var elapsed = new Date().getTime() - start;
    profiler.send('mongoQuery1', elapsed);
  });
});

Обратите внимание, что размер коллекции минимален (700 записей), а коллекции все индексируются соответственно запросам.

Я застрял в идеях, у кого есть идея, почему производительность настолько плохая?

EDIT:

для простого запроса типа:

db.user_permission.find({ username: 'a', permission_type: 'vehicle'})

с параметром user_permission, имеющим индекс:

db.user_permission.ensureIndex({username: 1, permission_type: 1});

Время увеличивается линейно с одновременными пользователями

РЕДАКТИРОВАТЬ 2

Пробовал включить профилирование для mongod (--profile = 2 --slowms = 100)

каждый раз, когда я запускаю ab против него, db повреждается, а в журналах mongod следующее:

Wed Nov 21 10:41:54 [conn4] creating profile collection: knightsbridge.system.profile
Wed Nov 21 10:41:54 [FileAllocator] allocating new datafile /Users/dzhu/data/mongodb/knightsbridge.ns, filling with zeroes...
Wed Nov 21 10:41:54 [FileAllocator] creating directory /Users/dzhu/data/mongodb/_tmp
Wed Nov 21 10:41:54 [FileAllocator] done allocating datafile /Users/dzhu/data/mongodb/knightsbridge.ns, size: 16MB,  took 0.018 secs
Wed Nov 21 10:41:54 [FileAllocator] allocating new datafile /Users/dzhu/data/mongodb/knightsbridge.0, filling with zeroes...
Wed Nov 21 10:41:54 [FileAllocator] done allocating datafile /Users/dzhu/data/mongodb/knightsbridge.0, size: 64MB,  took 0.152 secs
Wed Nov 21 10:41:54 [conn5] Assertion: 10334:Invalid BSONObj size: 0 (0x00000000) first element: EOO
0x10037637b 0x1000afc2e 0x1000b005c 0x10001ea53 0x100233529 0x1002a9b0b 0x1001a0a9f 0x10069518b 0x1002a2a4e 0x1005ca15e 0x10064a0ca 0x100018681 0x10019302c 0x1005a7823 0x7fff8a42f8bf 0x7fff8a432b75 
 0   mongod                              0x000000010037637b _ZN5mongo15printStackTraceERSo + 43
 1   mongod                              0x00000001000afc2e _ZN5mongo11msgassertedEiPKc + 206
 2   mongod                              0x00000001000b005c _ZN5mongo11msgassertedEiRKSs + 12
 3   mongod                              0x000000010001ea53 _ZNK5mongo7BSONObj14_assertInvalidEv + 1475
 4   mongod                              0x0000000100233529 _ZN5mongo13unindexRecordEPNS_16NamespaceDetailsEPNS_6RecordERKNS_7DiskLocEb + 265
 5   mongod                              0x00000001002a9b0b _ZN5mongo11DataFileMgr12deleteRecordEPKcPNS_6RecordERKNS_7DiskLocEbbb + 587
 6   mongod                              0x00000001001a0a9f _ZN5mongo16NamespaceDetails11cappedAllocEPKci + 1535
 7   mongod                              0x000000010069518b _ZN5mongo16NamespaceDetails5allocEPKciRNS_7DiskLocE + 123
 8   mongod                              0x00000001002a2a4e _ZN5mongo11DataFileMgr17fast_oplog_insertEPNS_16NamespaceDetailsEPKci + 126
 9   mongod                              0x00000001005ca15e _ZN5mongo7profileERKNS_6ClientERNS_5CurOpE + 3134
 10  mongod                              0x000000010064a0ca _ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE + 4010
 11  mongod                              0x0000000100018681 _ZN5mongo16MyMessageHandler7processERNS_7MessageEPNS_21AbstractMessagingPortEPNS_9LastErrorE + 257
 12  mongod                              0x000000010019302c _ZN5mongo3pms9threadRunEPNS_13MessagingPortE + 1084
 13  mongod                              0x00000001005a7823 thread_proxy + 163
 14  libsystem_c.dylib                   0x00007fff8a42f8bf _pthread_start + 335
 15  libsystem_c.dylib                   0x00007fff8a432b75 thread_start + 13

версия mongod:

mongod --version
db version v2.2.0, pdfile version 4.5
Wed Nov 21 10:47:24 git version: f5e83eae9cfbec7fb7a071321928f00d1b0c5207

И

Помимо установленного по умолчанию узла nodejs poolSize из 1, делает ли mongod ограничение на количество разрешенных параллельных подключений?

4b9b3361

Ответ 1

Джу, Куча вещей:

  • Пробовал ли вы этот запрос из оболочки mongo? Можете ли вы попробовать запустить его в оболочке, а также использовать функцию .explain(), чтобы получить представление о времени выполнения сервера? Это поможет вам проверить правильность вашего индекса и помочь изолировать, если проблема с производительностью на стороне клиента или на стороне сервера.

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

  • Используйте утилиту mongostat (см. документы mongodb) во время выполнения теста. Это даст вам представление о том, что делает сервер в режиме реального времени. В частности, посмотрите на блокировку% и столбцы qr/qw. В столбцах qr/qw указано, сколько операций чтения и записи поставлено в очередь (т.е. Заблокировано и ожидает выполнения).

  • Имейте в виду, что включение профилировщика сервера mongo на уровень 2 (-profile = 2) приведет к тому, что сервер будет регистрировать ВСЕ операции, что сильно влияет на производительность базы данных. Используйте -profile = 1 для регистрации только операций медленнее, чем slowMs. Затем, после завершения теста, просмотрите содержимое файла db.system.profile для получения подробной информации о любых медленных операциях, выполняемых сервером.

Это поможет вам начать работу.