@vitland

Большая нагрузка на процессор, что оптимизировать?

Здравствуйте.

Пишу телеграм бот на nodejs + mongodb. Он посылает сообщения с картинками и описанием по запросу, есть фильтры и сообщения не повторяются, пока не закончатся все в одной категории. Фильтры и id просмотренных хранятся в базе, в документе пользователя.

При выполнении этой функции нагрузка на процессор VPS подскакивает до 60% - 70%.

Подозреваю, что не рационально сравниваю массивы, там может быть до 150 объектов в каждом.
Но мне нужно проверять, чтобы в выборке из базы не было повторов и понимать когда пользователь просмотрел все файлы.

spoiler
function sendFilesByQuery(chatId, query) {
  User.findOne({ telegramId: chatId }).then((user) => {
    // фильтры на основе которых формируется запрос
    if (user.filter.time === 1) {
      time = { $gte: 2000 };
    }
    if (user.filter.time === 2) {
      time = { $gte: 2015 };
    }
    if (user.filter.pop === 1) {
      pop = { $lt: 71 };
    }
    if (user.filter.pop === 2) {
      pop = { $gt: 9 };
    }

    if (user.filter.time === 0) {
      delete query.year;
    }
    if (user.filter1.pop === 0) {
      delete query.viewed;
    }

    query = {
      type: query.toString(),
      viewed: pop,
      year: time,
    };

    //Поиск все подходящих документов
    File.find(query).then((files) => {
      //Формируется масссив только _id, чтобы дальше исключить повторы
      let queryfiles = files.map((element) => element._id);

      //Массив со всеми id
      let allfiles;

      //Массив с просмотренными id
      let userfiles;
      
      //Массив с отфильтрованными не просмотренными id
      let rndfile;

      switch (query) {
        case "1":
          userfiles = user.files.type1;
          allfiles = user.allfiles.type1;
          //Исключаем повторы из массива
          rndfile = queryfiles.filter((f) => !userfiles.includes(f));
          bot.sendMessage(chatId, "text");
          break;
      }

      File.findById(rndfile)
        //Восстанавливает целый  рандомный документ из id
        .skip(Math.floor(Math.random() * rndfile.length))
        .then((rndfile) => {
          bot.sendDocument(chatId, rndfile.gif);

          if (!rndfile) {
            bot.sendMessage(chatId, "text");
          }

          if (userfiles.length >= allfiles.length - 1) {
            clearfilesType(user.telegramId, query);
          }
        });
    });
  });
}
  • Вопрос задан
  • 182 просмотра
Решения вопроса 1
@vitland Автор вопроса
Спасибо за советы!
Я пока нуб и без понятия, что такое профайлинг, как логгировать запросы и их интерпритировать. И на данном этапе в таком сложно разобраться.
Пока же решил проблему изменив запрос к базе, убрал сравнение массивов. Производительность значительно подросла.

function sendFilesByQuery(chatId, query) {
  User.findOne({ telegramId: chatId }).then((user) => {
    // фильтры на основе которых формируется запрос
    if (user.filter.time === 1) {
      time = { $gte: 2000 };
    }
    if (user.filter.time === 2) {
      time = { $gte: 2015 };
    }
    if (user.filter.pop === 1) {
      pop = { $lt: 71 };
    }
    if (user.filter.pop === 2) {
      pop = { $gt: 9 };
    }

    if (user.filter.time === 0) {
      delete query.year;
    }
    if (user.filter1.pop === 0) {
      delete query.viewed;
    }

    query = {
      type: query.type.toString(),
      viewed: pop,
      year: time,
//Здесь отсеиваются просмотренные файлы
      _id: {
        $nin: watched, 
      },
    };

    File.find(query).then((file) => {
      rndfile = file[Math.floor(Math.random() * file.length)];
      let allfiles;
      let userfiles;
      switch (query.type) {
        case "1":
          userfiles = user.files1;
          allfiles = user.allfiles;
          break;
      }

      bot.sendDocument(chatId, rndfile.gif);
      if (!rndfile) {
        bot.sendMessage(chatId, "text");
      }
      if (userfiles1.length >= allfiles.length - 1) {
        clearfilesType(user.telegramId, query);
      }
    });
  });
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@mrsaa
ответ будет пальцем в небо, потому что много неизвестных:
но если в реляционных бд реализовывать фильтры, то надо думать про индексы, а как с этим в монгодб?

ну и я бы рекомендовал сначала произвести детальный профайлинг, хотя бы посмотреть какие процессы грузят, сколько ядер задействовано и остальные ресурсы.
Ответ написан
opium
@opium
Просто люблю качественно работать
посмотри кто грузит проц база или нода
если база залоггируй медленые запросы
если нода сделай профайлинг
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
25 мая 2020, в 15:19
10000 руб./за проект
25 мая 2020, в 15:17
3000 руб./за проект
25 мая 2020, в 14:54
50000 руб./за проект