Nano Hash - криптовалюты, майнинг, программирование

Мой процессор перегревается, когда я использую хвостовой курсор монго с .stream()

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

const listStream = ListsSub.find()
  .tailable({
    await_data: true,
    numberOfRetries: -1,
  })
  .stream();

мой процессор перегревается.

Монитор активности, когда код активен

введите здесь описание изображения

Комментируя .stream(), сервер снова работает отлично.

Монитор активности, когда код закомментирован

введите здесь описание изображения

Я вообще не знаю, как без этого. Это что-то с моим кодом? Кто-нибудь сталкивался с такой же проблемой?

ИЗМЕНИТЬ:

  • мангуст: 4.11.3
  • монгодб: 3.4.6
  • узел: 8.1.2
  • Сервер и mongodb на одной машине
04.08.2017

  • Вполне вероятно, что клиент опрашивает, а не ожидает событий эффективным способом. Версия мангуста? И подключаемая версия MongoDB, пожалуйста. Также я предполагаю, что и клиент, и сервер работают на одной машине? 04.08.2017
  • Извините, я забыл также попросить версию node. Но на самом деле это больше указывает на mongod, чем на что-либо еще, а также, в частности, на OSX. 04.08.2017
  • У нас такая же проблема при работе на Ubuntu. В Ubuntu он не так высок, и он не перегревается, но mongod использует ~ 80% ЦП. 04.08.2017
  • Можете ли вы уточнить, что вы на самом деле делаете с хвостовым курсором? Много ли считывается новых данных? Или он в основном простаивает из-за высокой загрузки ЦП? 04.08.2017
  • Он в основном бездействует, новых документов для чтения нет, и мы больше ничего с ним не делаем. 04.08.2017
  • Ну, на самом деле я вижу значительное (в основном до 0) падение на холостом ходу, просто используя .cursor() вместо .stream(). На самом деле предупреждение об устаревании выдается как DeprecationWarning: Mongoose: Query.prototype.stream() is deprecated in mongoose >= 4.5.0, use Query.prototype.cursor() instead 04.08.2017
  • Действительно, в потоке есть предупреждение об устаревании, но у нас все еще высокий процент использования ЦП в двух ОС с курсором. Мы пытались сбросить коллекцию ListSub непосредственно перед запуском сервера, и происходит то же самое. Если мы добавим listStream .pause() сразу после создания listStream, процессор останется в порядке. 04.08.2017
  • Вероятно, я должен добавить, что с момента отправки ответа этот код все еще работает, и даже не потеет, не говоря уже о перегрузке ЦП. Так что это более 30 минут спустя. 04.08.2017

Ответы:


1

На самом деле здесь нужно сделать несколько вещей. Первое, что следует отметить, это использование метода .cursor() вместо .stream() как фактически указано в предупреждении об устаревании, выдаваемом при ином использовании:

Предупреждение об устаревании: Mongoose: Query.prototype.stream() устарел в mongoose >= 4.5.0, вместо этого используйте Query.prototype.cursor()

Второе примечательное обстоятельство заключается в том, что, как указано в документации .cursor(), теперь возвращается Интерфейс «обернутого потока» непосредственно из базового драйвера. Поэтому рекомендуется использовать современный .addCursorFlag() вместо метода .tailable() из mongoose Query.

После того, как обе эти меры приняты, я вижу, что простаивающий ЦП для процессов mongod и node падает до 0% между интервалами обновления.

Это лучше всего моделируется с помощью следующего листинга.

const mongoose = require('mongoose'),
      Schema = mongoose.Schema;

mongoose.Promise = global.Promise;
mongoose.set('debug',true);

const uri = 'mongodb://localhost/tailing',
      options = { useMongoClient: true };

const subSchema = new Schema({
  name: String
},{
  capped: { size: 1024, max: 1000 }
});

const Sub = mongoose.model('Sub', subSchema);

function log(data) {
  console.log(JSON.stringify(data, undefined, 2))
}

(async function() {

  try {

    const conn = await mongoose.connect(uri,options);

    //await Sub.remove({});

    await Sub.insertMany(Array(50).fill(1).map((e,i) => ({ name: i+1 })));

    let stream = Sub.find()
      .cursor()
      .addCursorFlag('tailable',true)
      .addCursorFlag('awaitData',true);
      /*
      .tailable({
        await_data: true,
        numberOfRetries: -1
      })
      .cursor();
      */

    stream.on('data',function(data) {
      log(data);
    });

    let counter = 50;


    setInterval(async function() {
      counter++;
      await Sub.insertMany({ name: counter });
    },10000);

  } catch(e) {
    console.log(e);
  } finally {
    //mongoose.disconnect();
  }

})();

Обычный старый верхний вывод, захваченный во время фактической записи:

top - 21:38:29 up 12 days,  1:23,  3 users,  load average: 0.06, 0.03, 0.04
Tasks: 116 total,   2 running, 114 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 98.6 id,  0.7 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2045968 total,   207452 free,   813908 used,  1024608 buff/cache
KiB Swap:  2097148 total,  2097124 free,       24 used.  1028156 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 1257 mongodb   20   0 1946896 487336  34892 S  0.7 23.8 130:37.67 mongod
28233 neillunn  20   0 1021460  41920  22996 S  0.3  2.0   0:00.67 node
30956 neillunn  20   0  101472   4384   3352 S  0.3  0.2   0:20.95 sshd
04.08.2017
  • Этот ответ также относится к собственному драйверу mongodb, за исключением того, что find() уже возвращает курсор, поэтому вам не нужно вызывать cursor(). 19.03.2018

  • 2

    Я использую mongooseV5.9.2, и мне нужно было добавить ниже способ решения проблемы.

    let options = { tailable: true, 
                    awaitData: true, 
                    numberOfRetries: -1, 
                    tailableRetryInterval: 200
                  };
        collection.find().cursor(options);
    
    08.04.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..