Мне нужно выполнить парсинг больших (5-10 Гб) лог-файлов в Javascript / Node.js (я использую Cube).
Логлайн выглядит примерно так:
10:00:43.343423 I'm a friendly log message. There are 5 cats, and 7 dogs. We are in state "SUCCESS".
Мы должны читать каждую строку, сделать некоторые синтаксический анализ (например , раздеть 5
, 7
а SUCCESS
), а затем накачать эти данные в кубе ( https://github.com/square/cube ) с помощью своего клиента JS.
Во-первых, каков канонический способ чтения файла в Node построчно?
Это довольно распространенный вопрос в сети:
- http://www.quora.com/What-is-the-best-way-to-read-a-file-line-by-line-in-node-js
- Прочитать файл по одной строке в node.js?
Многие ответы, похоже, указывают на кучу сторонних модулей:
- https://github.com/nickewing/line-reader
- https://github.com/jahewson/node-byline
- https://github.com/pkrumins/node-lazy
- https://github.com/Gagle/Node-BufferedReader
Однако это кажется довольно простой задачей - конечно, есть простой способ в stdlib читать текстовый файл построчно?
Во-вторых, мне нужно обработать каждую строку (например, преобразовать метку времени в объект Date и извлечь полезные поля).
Как лучше всего это сделать, увеличив пропускную способность? Есть ли способ, который не блокирует чтение каждой строки или отправку ее в Cube?
В-третьих, я предполагаю, что использую разбиение строк, а JS-эквивалент contains (IndexOf! = -1?) Будет намного быстрее, чем регулярные выражения? Есть ли у кого-нибудь большой опыт анализа огромных объемов текстовых данных в Node.js?
Ура, Виктор
источник
Ответы:
Я искал решение для построчного анализа очень больших файлов (gbs) с использованием потока. Все сторонние библиотеки и примеры мне не подходили, так как они обрабатывали файлы не построчно (например, 1, 2, 3, 4 ..) или считывали весь файл в память
Следующее решение может анализировать очень большие файлы построчно с помощью stream & pipe. Для тестирования я использовал файл размером 2,1 Гб с 17 000 000 записей. Использование оперативной памяти не превышало 60 мб.
Сначала установите пакет event-stream :
Затем:
Пожалуйста, дайте мне знать, как это происходит!
источник
console.log(lineNr)
после последней строки вашего кода, он не покажет окончательное количество строк, потому что файл читается асинхронно.s.end();
readline
модуль - это боль. Он не ставил паузу и каждый раз вызывал сбой после 40-50 миллионов. Потраченный впустую день. Большое спасибо за ответ. Этот работает отличноВы можете использовать встроенный
readline
пакет, см. Документацию здесь . Я использую поток для создания нового потока вывода.Обработка больших файлов займет некоторое время. Скажите, работает ли это.
источник
readline
, можно ли приостановить / возобновить поток чтения для выполнения асинхронных действий в области «делать что-то»?readline
мне много проблем, когда я попытался приостановить / возобновить. Он не приостанавливает поток должным образом, создавая множество проблем, если последующий процесс идет медленнееМне очень понравился ответ @gerard, который на самом деле заслуживает того, чтобы быть здесь правильным. Я сделал некоторые улучшения:
Вот код:
В общем, вот как вы его будете использовать:
Я тестировал это с помощью CSV-файла размером 35 ГБ, и он сработал для меня, и поэтому я решил построить его на ответе @gerard , отзывы приветствуются.
источник
pause()
звонку, не так ли?Я использовал https://www.npmjs.com/package/line-by-line для чтения более 1000000 строк из текстового файла. В этом случае занятый объем оперативной памяти составлял около 50-60 мегабайт.
источник
lr.cancel()
методе. Считывает первые 1000 строк файла размером 5 ГБ за 1 мс. Потрясающие!!!!Помимо чтения большого файла построчно, вы также можете читать его по частям. Подробнее см. В этой статье
источник
if(bytesRead = chunkSize)
:?Документация Node.js предлагает очень элегантный пример использования модуля Readline.
Пример: построчное чтение потока файлов
источник
У меня была такая же проблема. Сравнив несколько модулей, которые вроде бы имеют эту функцию, я решил сделать это сам, это проще, чем я думал.
суть: https://gist.github.com/deemstone/8279565
Он охватывает файл, открытый при закрытии, который
fetchBlock()
возвращается, будет извлекать блок из файла, конец разбивается на массив (будет обрабатывать сегмент из последней выборки).Я установил размер блока 1024 для каждой операции чтения. В этом могут быть ошибки, но логика кода очевидна, попробуйте сами.
источник
node-byline использует потоки, поэтому я бы предпочел его для ваших огромных файлов.
для преобразования даты я бы использовал moment.js .
для увеличения пропускной способности вы можете подумать об использовании программного кластера. есть несколько хороших модулей, которые довольно хорошо обертывают нативный кластерный модуль. Мне нравится cluster-master от isaacs. например, вы можете создать кластер из x рабочих, которые все вычисляют файл.
для сравнения разделов и регулярных выражений используйте benchmark.js . Я не тестировал его до сих пор. benchmark.js доступен как узел-модуль
источник
Основываясь на этом ответе на вопросы, я реализовал класс, который вы можете использовать для синхронного чтения файла построчно
fs.readSync()
. Вы можете сделать эту «паузу» и «возобновить» с помощьюQ
обещания (jQuery
похоже, требуется DOM, поэтому нельзя запускать его с помощьюnodejs
):источник
источник
Я сделал модуль узла для асинхронного чтения большого файла, текста или JSON. Проверено на больших файлах.
Просто сохраните файл как file-reader.js и используйте его так:
источник