Как организовать передачу данных с сетевого интерфейса приложению на C++ максимально быстро?
Сейчас данные льются по ODBC в БД, а уже оттуда приложение их читает. Наверняка это не самый быстрый путь доставки данных от сетевого интерфейса приложению.
Насколько приемлема такая схема доставки данных: от сетевого интерфейса приложению, а уже потом, во время простоя, приложение складывает данные в БД? Пользователь этих данных и БД только один - это приложение.
Сколько миллисекунд (интересует оценка порядка) можно таким подходом выиграть?
Насколько распространен такой подход и имеет ли он какое-то свое название?
Иван Мельников, это неверный ответ.
Сетевая карта не берет данные из ниоткуда и не генерирует их. Тебе стоит явно обозначить вторую сторону - источник данных, которые приходят по сети.
Евгений Шатунов, меня интересуют любые (отранжированные в порядке убывания профита) возможные сокращения временного лага от момента поступления tcp-пакетов с данными на сетевой интерфейс ПК до момента забора их структурами данных приложения. Что касается оптимизации сети, коммутации пакетов и настроек сервера - это не моя сфера ответственности.
Иван Мельников, так, стоп. Или ты не понимаешь свою задачу, или я не понимаю твое изложение задачи. В любом случае проблема в том, какими словами ты формулируешь свой вопрос.
Твоя задача - это мониторинг сырого трафика сетевого интерфейса? Т.е. ты делаешь аналог WireShark? Или же у тебя есть некоторый бекенд, с которым ты общаешься по сети через ODBC прокладку?
Евгений Шатунов, у меня есть, например, клиент для торговли на фондовой бирже. Задача стоит как можно быстрее доставлять получаемые клиентом данные приложению. Есть мнение, что делать это через посредника в виде БД - это не самый быстрый способ.
Иван Мельников, не стоит зажимать такую чувствительную информацию, от нее зависит вероятность ответа на твой вопрос. Если ты все-таки работаешь с конкретным бекендом по конкретному протоколу, а не занимаешься мониторингом сырого сетевого трафика, то, конечно же, прямая работа твоего кода с трафиком прямо с бекенда является максимально производительным выходом. Экономия там не на миллисекунды будет, а на секунды при достаточных объемах трафика.
Однако, прямое соединение требует исполнения в соответствии с некоторыми критериями качества и надежности ПО. Критерии эти можно выполнить при использовании ряда архитектурных приемов. И вот тут встает вопрос: сможешь ли ты гарантировать качество такого ПО?
Сейчас твоя связка из ODBC и твоего ПО вполне тянет на микроядерную архитектуру, обеспечивающую должное качество. Это медленно, но надежно. Можно сделать быстро и надежно, и довольно дорого по бюджету.
Евгений Шатунов, спасибо! Я понимаю, что прямая работа с сырым трафиком - это самый производительный вариант. Точнее, догодывался, так скажем. Но вопрос был скорее о том, в какую сторону мне копать. Как называется такой подход? Какие библиотеки юзать? Что почитать?
После этого стоит разобраться с протоколом связи твоего бекенда и собрать высокопроизводительный асинхронный фронтенд для связи с твоим бекендом. Фронтенд должен быть максимально тонким и максимально асинхронным, в нем должно быть нечему падать. Именно этот фронтенд будет без задержек передавать сетевой трафик уже в твой клиентский модуль. Так ты сделаешь базовый задел на надежность и расширяемость. Фронтенд потом можно будет научить параллельно писать данные в базу, если это нужно, для большей надежности, на случай если клиентское ПО внезапно упадет или зависнет.
В идеале тебе нужно найти Tech. Lead Network Developer-а. Кого-то вроде Гленна Фидлера[?]. Или стать им. На хабре, кстати, есть много переводов его статей.
У меня довольно большой опыт разработки ММО-проектов, так что я более-менее ориентируюсь в проектировании высоконагруженных и критичных к времени ответа сетевых проектов.
Я утверждаю что это самый быстрый способ, но это только гипотеза. Твёрдо может ответить только профайлер. И да! Не занимайтесь предварительной оптимизацией (с)
А кто льет данные по odbc в БД? Если ваш сервис, и вы можете его изменить, то варианты более быстрого взаимодействия есть. Например, можно использовать разделяемую память (shared memory) или каналы (pipes) для межпроцессного взаимодействия.
Разделяемая память, имхо, будет самым быстрым способом взаимодействия.
Вопрос поставлен неправильно.
Чтоб оптимизировать odbc - надо 100% знать что именно он является узким местом. Я бы начал с анализа исполнения и извлечения данных локально на сервере. ДБА здесь поможет. И если ваша задаче связана с ETL - почитайте про техники. Может экспорт в csv файл с загрузкой в с++ приложение будет быстрее. Может репликация бд или миграция.