Зачем нужен асинхронный ввод-вывод при чтении сокетов для не HTTP-сервера

Я разрабатываю клиентское приложение С++, которое прослушивает несколько портов для потоков коротких сообщений. После изучения ACE, POCO, boost::asio и всех шаблонов проектирования, подобных Proactor, я собираюсь начать с boost::asio.

Одна вещь, которую я заметил, это постоянная тема использования асинхронного ввода-вывода через сокет, но я не читал хорошего описания проблемы, которую решает асинхронный ввод-вывод. Основаны ли все эти шаблоны проектирования на предположении о конструкции веб-сервера HTTP?

Поскольку веб-серверы являются наиболее распространенным приложением для сложного программирования параллельных сокетов, чувствительного к задержке, я начинаю задаваться вопросом, предназначены ли большинство этих шаблонов/идиом для этого одного приложения.

Мое приложение будет прослушивать несколько сокетов для коротких и частых сообщений. Отдельный поток должен будет объединить все сообщения для обработки. Одна вещь, для которой я рассматриваю шаблоны проектирования, — это отделение управления соединениями от обработки данных. Я хочу, чтобы соединения пытались переподключиться после отключения и чтобы поток обработки продолжался, как будто ничего не произошло. Какой шаблон проектирования рекомендуется здесь?

Я не вижу, как async io улучшит производительность в моем случае.


person jaybny    schedule 22.07.2012    source источник


Ответы (2)


Вы на правильном пути. Разумно спросить «почему», особенно со всей шумихой вокруг асинхронности и управления событиями. Есть приложения кроме веба. Подумайте об очередях сообщений и финансовых транзакциях, таких как высокочастотная торговля. По сути, любой случай, когда ожидание стоит денег или теряется возможность обслужить клиента, является кандидатом на асинхронность. Веб — большой пример, потому что сеть намного быстрее, чем база данных. Как всегда, спросите «имеет ли это смысл» для вашего приложения. Асинхронность добавляет много сложности, если вы не получаете от этого пользы.

Ваши короткие, быстрые сообщения на самом деле могут значительно выиграть от асинхронности, если среднее время между сообщениями сравнимо со временем, необходимым для обработки каждого сообщения, особенно если эта обработка включает сохранение. Но вам не нужно торопиться с асинхронностью. Инструментируйте свой код блокировки и посмотрите, действительно ли у вас есть узкое место.

Надеюсь, это поможет.

person Carlos    schedule 22.07.2012
comment
Мое приложение действительно представляет собой высокочастотную торговлю, и да, мне нужно постоянство, но будет отдельный процесс, который будет сохранять данные, которые будут совместно использоваться с использованием некоторой общей памяти или IPC. - person jaybny; 22.07.2012
comment
В порядке. Если вы сможете быстро перенести задачу сохранения на другой уровень неблокирующим способом, вы, вероятно, выиграете. Анализ @lserni (ниже) превосходен. - person Carlos; 23.07.2012
comment
Все еще пытаюсь выяснить, как именно разгрузить постоянство неблокирующим способом. Не могу ли я просто ретранслировать или многоадресно передавать на localhost из нескольких потоков? Не будет ли OS создавать единый поток из одновременных отправок через UDP и делать все это асинхронно? моя ОС пока windows, но ОС не имеет значения. ты - person jaybny; 02.08.2012

Использование шаблона блокировки вызовов повлечет за собой:

1. Listening on a socket vector of size N
2. When a message arrives, you wake up with a start in time K, find and start processing the message, employing a time T (it does not matter if the processing is offloaded to another thread: in this case T becomes your offloading time)
3. You finish examining the vector and GOTO 1

Таким образом, вы можете сказать, что если прибывает M сообщений, а другое сообщение поступает в течение времени отправки K+M*T, то M+1-е сообщение будет ожидать K+M*T времени. Приемлемо ли это для ваших ожидаемых значений K (постоянная), M (функция трафика) и T (функция ресурсов и загрузки системы)?

Асинхронной обработки на самом деле не существует. Всегда будет где-то "синхронный" цикл ввода-вывода, только он будет настолько хорошо интегрирован в ядро ​​(или даже аппаратное обеспечение), что будет работать в 10-100 раз быстрее, чем ваш собственный, и, следовательно, будет вероятно, будет лучше масштабироваться при больших значениях M. Задержка по-прежнему имеет форму K1+M*T1, но на этот раз K1 и T1 намного меньше. Или, может быть, K1 немного выше, а T1 значительно ниже: архитектура «лучше масштабируется» при больших значениях M.

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

Примите во внимание еще один фактор: если количество сообщений становится действительно большим, асинхронность имеет свои преимущества; но если сами сообщения независимы (изменения, вызванные сообщением A, не влияют на обработку сообщения B), то вы можете оставаться синхронными и масштабироваться по горизонтали, подготавливая количество Z «концентраторов сообщений», каждый из которых получает долю M/Z от общий трафик.

Если обработка требует выполнения других вызовов других служб (кэш, постоянство, поиск информации, аутентификация...), увеличения T-фактора, тогда вам лучше обратиться к многопоточности или даже к асинхронности. При многопоточности вы сокращаете T до доли его значения (только время диспетчеризации). Асинхронный в каком-то смысле делает то же самое, но бреет еще больше и заботится о большем количестве шаблонов программирования для вас.

person LSerni    schedule 22.07.2012
comment
пытается следовать, но не уверен, где N вступает в игру. в моем случае N равно 1 или 3, не совсем уверен, что такое вектор сокета ... но снова я думаю, что это недоразумение из-за протокола связи. http против других. У каждого сокета разные данные и только нисходящий поток... я клиент. сообщения имеют некоторую зависимость, но могут использоваться как логически независимые. я думаю, что мой дизайн должен масштабироваться по горизонтали, хотя я понимаю только суть вашего ответа. - person jaybny; 23.07.2012