Автор Тема: Парсер многогигабитных потоков данных  (Прочитано 17265 раз)

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Приятно писать парсер который сам запрашивает следующий символ когда ему это становится нужно...

У меня сейчас задача "обратная", неприятная. Мой парсер сам запрашивать следующий символ не может, а, наоборот, символы в него будут впихивать, а парсер должен как "автомат" помнить своё состояние.

Как это сделать наиболее оптимально?

Самому парсеру запрашивать следующий символ нельзя так как следующего символа ещё может не быть. Символы прилетают из сети толстым многогигабитным потоком. Символы немножко буферировать можно, но без перекопирований. А именно, можно задержать ненадолго немного IP пакетов. Данные из IP пакетов читать можно, но перекопировать их в отдельный буфер нельзя - поток очень многогигабитный и на лишнее перекопирование не хватит скорости контроллера памяти.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #1 : Декабрь 25, 2014, 01:32:19 pm »
Сразу вспомнилась так называемая SWITCH технология в автоматном программировании, которую продвигает Шалыто А.А. в Питерском УНИВЕРСИТЕТе ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ, МЕХАНИКИ И ОПТИКИ. Там события(приход символа к примеру) передаются автомату для обработки, а сам автомат события не запрашивает.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #2 : Декабрь 25, 2014, 01:42:38 pm »
Всплыло ещё в памяти презентация или доклад Р.Пайка по Go и сопрограммам , на примера как раз парсинга или чего-то подобного.  Там  парсер в точках, где  запрашивает новый символ, получает его через канал из другой сопрограммы.  Тут уже в отличии от SWITCH-техн. парсер "постоянно" активен.
« Последнее редактирование: Декабрь 25, 2014, 01:44:46 pm от albobin »

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #3 : Декабрь 25, 2014, 05:14:31 pm »
Да, сопрограммы.
Когда-то очень давно пришлось писать BIOS на ассемблере.
Вывод на экран (посимвольный) должен был отрабатывать ESC-последовательности. Автоматная реализация крайне не наглядна.
Реализовано было с помощью сопрограммы, очень эффективно и очень наглядно. Текст программы - практически описание протокола.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #4 : Декабрь 25, 2014, 05:33:46 pm »
если продолжать про сопрограммы, то справедливее, конечно, вспомнить не Пайка, а Мелвина Конвея и его статью, где он помимо прочего привел пример практического опыта создания компилятора с кобола с применением сопрограмм.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #5 : Декабрь 26, 2014, 11:25:18 am »
символы в него будут впихивать
ээээ, извиняюсь, кто куда и как будет впихивать?

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Парсер многогигабитных потоков данных
« Ответ #6 : Декабрь 26, 2014, 01:39:41 pm »
ээээ, извиняюсь, кто куда и как будет впихивать?
Например, сборщик TCP отдаёт данные в HTML декодер, то есть данные толкаются из нижнего уровня в верхний. А в "обычном" парсере было бы наоборот, верхним уровнем данные запрашивались бы у нижнего уровня.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #7 : Декабрь 26, 2014, 04:55:27 pm »
Что-то типа ленивого парсера получается. Комбинаторы парсеров в помощь (Haskell'ная библиотека Parsec)...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Romiras

  • Sr. Member
  • ****
  • Сообщений: 264
    • Просмотр профиля
    • Romiras Dev Lab
Re: Парсер многогигабитных потоков данных
« Ответ #8 : Декабрь 28, 2014, 12:44:39 pm »
ээээ, извиняюсь, кто куда и как будет впихивать?
Например, сборщик TCP отдаёт данные в HTML декодер, то есть данные толкаются из нижнего уровня в верхний. А в "обычном" парсере было бы наоборот, верхним уровнем данные запрашивались бы у нижнего уровня.
Какая-то странная архитектура. Почему HTML декодер не может "спрашивать" у сборщика TCP необходимое количество через заданного размера буфер?
Надеюсь, эта ссылка поможет: buffering in standard streams

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Парсер многогигабитных потоков данных
« Ответ #9 : Декабрь 29, 2014, 01:47:34 pm »
Какая-то странная архитектура. Почему HTML декодер не может "спрашивать" у сборщика TCP необходимое количество через заданного размера буфер?
Я пояснил это в первом сообщении. Запрашивать новые символы не может потому что их ещё нет. Они ещё не приехали. Да и буфера (в обычном смысле) тоже не может быть из-за строжайшего запрета на лишнее перекопирование (контроллер памяти не справится). Вместо буфера возможен небольшой список IP пакетов.

---

Да, кстати, я немного не то написал в прошлый раз, не HTML, а конечно же HTTP.

---

Сейчас обдумываю "классический" парсер у которого пространство символов дополнено одним специальным символом под названием СЛЕДУЮЩИЙ_СИМВОЛ_ЕЩЁ_НЕ_ПОЛУЧЕН. Работает такой парсер как обычно сам запрашивая следующий символ. В один прекрасный момент он в ответ на свой запрос получает от сканера символ под названием СЛЕДУЮЩИЙ_СИМВОЛ_ЕЩЁ_НЕ_ПОЛУЧЕН. Тогда парсер должен запомнить своё текущее состояние и вернуть управление. Когда будет получен очередной IP пакет управление вновь будет передано парсеру и т.д.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #10 : Декабрь 29, 2014, 02:50:56 pm »
Не придётся ли всё равно перейти к варианту парсера-автомата который будет обрабатывать одно событие (один символ) за один вызов, ведь символ "СЛЕДУЮЩИЙ_СИМВОЛ_ЕЩЁ_НЕ_ПОЛУЧЕН" может быть обнаружен в произвольном месте "классического " парсера ?

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Парсер многогигабитных потоков данных
« Ответ #11 : Декабрь 30, 2014, 12:06:39 pm »
Ну, вероятно, будет некая комбинация того и другого. Пока следующий символ доступен должен бы работать метод рекурсивного спуска. Надо только придумать как запоминать состояние. Хотя, конечно, гибрид ужа с ежом пугает.

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #12 : Декабрь 30, 2014, 02:45:48 pm »
А какие язык/ОС?

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Парсер многогигабитных потоков данных
« Ответ #13 : Декабрь 30, 2014, 03:01:50 pm »
Linux, C++

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Парсер многогигабитных потоков данных
« Ответ #14 : Декабрь 30, 2014, 08:16:04 pm »
Может интересно будет, вот ссылка на блог (метка H2O) http://blog.kazuhooku.com/search/label/H2O , где автор делится опытом создания быстрого веб-сервера и, в том числе, быстрого и к тому же ещё и stateless, http парсера.