Чувствует себя странно из-за результатов работы `fs.readFile` IO в NodeJS пуле потоков - PullRequest
0 голосов
/ 07 февраля 2020

Я сгенерировал много файлов с одинаковым содержимым и размером 150M. Я использую fs.readFile asyn c API, чтобы читать их следующим образом:

const fs = require('fs');
const COUNT = 16;

for (let i = 1; i <= COUNT; ++i) {
    console.time(i);
    console.log(process.hrtime());
    fs.readFile(`a${i}`, (err, data) => {
        console.log(process.hrtime());
        console.timeEnd(i);
    });
}

Я установил переменную ENV UV_THREADPOOL_SIZE в 1. А затем изменил COUNT на 8, 16, даже до 128. Но обратный вызов кажется сработал почти в то же время. Для 128 время больше 4 с.

Я тестировал только один файл, это будет стоить около 60 мс. И этот снимок экрана является результатом для 8 файлов:

enter image description here

В моей памяти asyn c fs.readFile API обрабатывается пулом потоков , Поэтому я изменил размер пула на 1.

И в NodeJS событие l oop фаза опроса обработает событие IO и выполнит для них обратный вызов. Я забыл, как долго фаза опроса будет блокировать событие l oop. Но я думаю, это меньше, чем 4 с.

Так что для кода выше, мы хотим прочитать файлы asyn c. Они запускаются одновременно, стоят в очереди и ждут, когда их заберут. Поскольку размер опроса равен 1, я думаю, мы будем читать все файлы один за другим, верно? И если один файл прочитал, обратный вызов будет выполнен в какой-то следующей фазе опроса (для 128 файлов время больше 4 с, поэтому я предполагаю, что будет следующая фаза опроса). И тогда мы получим время в консоли.

Но я не понимаю вывод. Кажется, что обратные вызовы запускаются почти одновременно.

Я ошибаюсь в фазе опроса в событии l oop или что-то в пуле потоков?


Обновление: I знаю, что я могу использовать поток для оптимизации чтения больших файлов. Но вопрос в том, что asyn c API кажется параллельным, когда я устанавливаю пул потоков равным 1.


Обновление: спасибо за ответ от @O. Джонс. Он сказал мне, что nodejs чередует эти маленькие кусочки при чтении файлов. Может ли кто-нибудь помочь мне дать мне немного информации об этом? Или кто-нибудь знает другую информацию?

1 Ответ

1 голос
/ 07 февраля 2020

150 мегабайт - это значительный объем данных, поэтому для переноса с вашего диска или SSD в оперативную память требуется время. И вполне вероятно, что на вашем диске или SSD есть какая-то внутренняя очередь запросов на чтение. Когда вы запрашиваете несколько почти одновременных операций чтения, они go попадают в эту очередь и обрабатываются одна за другой.

Чтения больших файлов разбиваются на более мелкие чтения блоков. Похоже, что узел чередует эти чтения блока, поэтому несколько операций readFile выполняются примерно параллельно.

На практике лучше использовать потоки для чтения файлов такого размера. Если вам не нужны все эти данные в ОЗУ сразу, потоки хороши тем, что они генерируют события 'data' для каждого куска данных и события 'close' по завершении. Посмотреть это https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

...