Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выбор архитектуры сервера 
V
    Опции темы
drug007
Дата 8.11.2011, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Здравствуйте!
Стоит задача разработать сервер со следующими особенностями:
а) малое число одновременных соединений (десятки)
б) Соединения длительные - часы, а то и сутки
в) Скорость передачи данных ограничена физическим каналом и небольшая до 1 КБ/с, а то и меньше (минимальная, максимальная неограниченая smile ). 
г) Большой пинг (от сотен мс до секунд)
д) Сервер также выполняет тяжёлую обработку данных
е) Объём передаваемых данных незначительный, но частый - много мелких сообщений.
ж) доставка сообщений должна быть гарантированной

Почитав тему про варианты архитектуры ASIO сервера, пришел к выводу что это должен быть:
1) tcp сервер (пункт ж) 
2) с архитектурой типа SEDA (пункты д - разделяем сетевую часть и тяжелую бизнес-логику + пункт е - и там и там сообщения) 
3) с архитектурой поток на сессию (пункт а - будет мало потоков, б -потоки создаются редко, т.е. нет оверхеда на их создание и пункт е -много мелких сообщений приведут к большему числу (системных?) вызовов при асинхронной архитектуре). 
4) Сессии с большим таймаутом?(пункт г)
Пункт В накладывает ограничение скорее на бизнес-логику, чем на сетевую часть.

Может что-то лишнее в моих рассуждениях, а что-то нужно добавить? Прокомментируйте, пожалуйста.

Это сообщение отредактировал(а) drug007 - 10.11.2011, 13:48
PM MAIL   Вверх
boostcoder
Дата 11.11.2011, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
Почитав тему про варианты архитектуры ASIO сервера

эту?: http://forum.vingrad.ru/forum/topic-340251...0%BD%D0%BE.html


Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
3) с архитектурой поток на сессию (пункт а - будет мало потоков, б -потоки создаются редко, т.е. нет оверхеда на их создание

это в реализации сложнее. используй пул(хотя из требований, и одного потока будет достаточно).
я, в одной из задач, применил такое необычное решение:
1. отдельный процесс-сервер. принимает соединения, читает пакеты, отправляет пакеты.
2. отдельный процесс-логика.
общаются друг с другом посредством двух IPC очередей. в одну очередь сервер кладет данные, из второй очереди читает ответы от логики и отправляет клиентам. реализация получилась невероятно простой. это был эксперимент.


Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
много мелких сообщений

сколько? приблизительно. в секунду.


Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
приведут к большему числу (системных?) вызовов при асинхронной архитектуре).

опять же, вопрос выше.
и это прочти: http://forum.vingrad.ru/forum/topic-341403/view-all.html

Это сообщение отредактировал(а) boostcoder - 11.11.2011, 06:19
PM WWW   Вверх
Lols
Дата 11.11.2011, 01:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 21.10.2011

Репутация: нет
Всего: нет



[QUOTE=boostcoder,11.11.2011,  00:15]
Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)



Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
3) с архитектурой поток на сессию (пункт а - будет мало потоков, б -потоки создаются редко, т.е. нет оверхеда на их создание

это в реализации сложнее. используй пул(хотя из требований, и одного потока будет достаточно).
я, в одной из задач, применил такое необычное решение:
1. отдельный процесс-сервер. принимает соединения, читает пакеты, отправляет пакеты.
2. отдельный процесс-логика.
общаются друг с другом посредством двух IPC очереди. в одну очередь сервер кладет данные, из второй очереди читает ответы от логики и отправляет клиентам. реализация получилась невероятно простой. это был эксперимент.




Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
приведут к большему числу (системных?) вызовов при асинхронной архитектуре).

А ваш эксперимент реально будет исполнить на практике с такими требованиями?
PM MAIL   Вверх
boostcoder
Дата 11.11.2011, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



у меня же он работает. хоть это и был эксперимент, но он работает в реальной задаче.
PM WWW   Вверх
drug007
Дата 11.11.2011, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(boostcoder @ 11.11.2011,  00:15)
Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
Почитав тему про варианты архитектуры ASIO сервера

эту?: http://forum.vingrad.ru/forum/topic-340251...0%BD%D0%BE.html

Оно самое

Цитата(boostcoder @ 11.11.2011,  00:15)

Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
много мелких сообщений

сколько? приблизительно. в секунду.


Точных значений сказать не могу - если исходить из ширины канала, точнее из его узости, то в самом худшем варианте десятки сообщений в секунду на одно соединение, не больше. Требование по максимуму же пока можно сформировать только на уровне "чем больше, тем лучше" и "кашу маслом не испортишь", к сожалению. 
За ориентир возьму пока сотни сообщений в среднем размером 50-100 байт (это на уровне приложения), с возможность увеличения количества сообщений до тысяч с тем же размером - это в среднем, периодически (не часто) объем будет возрастать на порядок-два на непродолжительное время.
Бизнес-логика пока смутно выглядит - собственно, для ее исследования и нужен сервер.

Цитата(boostcoder @ 11.11.2011,  00:15)

Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
приведут к большему числу (системных?) вызовов при асинхронной архитектуре).

опять же, вопрос выше.
и это прочти: http://forum.vingrad.ru/forum/topic-341403/view-all.html

Почитал, полезно - я тоже разделял сервер и обработку данных, но, правда, в потоках. Но как то оценить не могу, т.к. опыта не очень много. На тот момент главным было, что работает. Про buffered_stream надо будет почитать, спасибо за ссылку - у меня как раз сначала читается хидер, затем тело - не нравилось уже когда код писал, но пока оставил так.
А вот про большее количество системных вызовов в случае асинхронной архитектуры при небольшом количестве клиентов пока не могу сообразить - вроде согласен в целом, но в деталях в голове не раскладывается, буду думать.

Тут еще нюанс в том, что по сути приложение предназначено для построения распределенной сети по сбору и обработке данных. И по возможности это приложение должно функционировать и на слабых машинах с небольшим объемом памяти. Сразу реализовывать такую возможность нет задачи, но не должно быть принципиальных ограничений на ее реализацию в дальнейшем. Если сервер сможет достойно крутится хотя бы на каком-нить двухядерном Cortex-A8 1.5GHz/512 Мb памяти, это будет заметным плюсом. Ясное дело, что вариант для х86 будет отличаться от варианта на ARM в решении некоторых вопросов, но желательно отличия свести к минимуму. Это я к тому, что закладывать требование в 4Гб на преаллокацию памяти (к примеру) крайне нежелательно.

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

PM MAIL   Вверх
boostcoder
Дата 11.11.2011, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
сотни сообщений в среднем размером 50-100 байт (это на уровне приложения), с возможность увеличения количества сообщений до тысяч с тем же размером - это в среднем, периодически (не часто) объем будет возрастать на порядок-два на непродолжительное время.

 smile 
я в одной из своих реализаций, добился ~470 000 тысяч в сек. а ты переживаешь за несколько тысяч.

Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
Про buffered_stream надо будет почитать

это будет весело, учитывая тот факт что доки к нему почти ноль. читать в этом случае нужно исходники. вот, специально для подобных задач создал: boost.asio.

Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
Тут еще нюанс в том, что по сути приложение предназначено для построения распределенной сети по сбору и обработке данных. И по возможности это приложение должно функционировать и на слабых машинах с небольшим объемом памяти. Сразу реализовывать такую возможность нет задачи, но не должно быть принципиальных ограничений на ее реализацию в дальнейшем. 

т.е. ты говоришь про сервер? если да - то конфиг к нему прикрутить. или заранее создать набор предустановленных значений(кол-во потоков,сессий,размеры буферов, и т.д.).

Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
Если сервер сможет достойно крутится хотя бы на каком-нить двухядерном Cortex-A8 1.5GHz/512 Мb памяти, это будет заметным плюсом.

запросто.

Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
Это я к тому, что закладывать требование в 4Гб на преаллокацию памяти (к примеру) крайне нежелательно.

про конфиг написал несколькими строками выше.

Это сообщение отредактировал(а) boostcoder - 6.8.2012, 11:50
PM WWW   Вверх
drug007
Дата 11.11.2011, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(boostcoder @ 11.11.2011,  09:01)
Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
сотни сообщений в среднем размером 50-100 байт (это на уровне приложения), с возможность увеличения количества сообщений до тысяч с тем же размером - это в среднем, периодически (не часто) объем будет возрастать на порядок-два на непродолжительное время.

 smile 
я в одной из своих реализаций, добился ~470 000 тысяч в сек. а ты переживаешь за несколько тысяч.

Да просто когда я первый раз столкнулся с такой задачей, канал связи был 50 бод (нужна была совместимость с аппаратурой лохматых годов) и сообщение в 20 байт передавалось пару секунд. Запустил как-то на 1200 бод - это был просто восторг smile С тех пор для меня тысяча в сек - это просто ужасно как много smile 
Всегда упирался в минимальную ширину канала, загрузить цпу бизнес-логикой "удалось" только один раз из-за неправильного алгоритма, поэтому сложно оценить потенциальное количество сообщений. Но сотня тысяч это радует. Это имеется в виду скорость чисто сервера без бизнес-логики?

Цитата(boostcoder @ 11.11.2011,  09:01)

Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
Про buffered_stream надо будет почитать

это будет весело, учитывая тот факт что доки к нему почти ноль. читать в этом случае нужно исходники. вот, специально для подобных задач создал: boost.asio.

Исходники буста для меня еще довольно сложная вещь, но почитаю в любом случае.


Цитата(boostcoder @ 11.11.2011,  09:01)
Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
Если сервер сможет достойно крутится хотя бы на каком-нить двухядерном Cortex-A8 1.5GHz/512 Мb памяти, это будет заметным плюсом.

запросто.

Прекрасно. smile

Цитата(boostcoder @ 11.11.2011,  09:01)
Цитата(drug007 @  11.11.2011,  08:41 Найти цитируемый пост)
Это я к тому, что закладывать требование в 4Гб на преаллокацию памяти (к примеру) крайне нежелательно.

про конфиг написал несколькими строками выше.

Т.е. учесть достаточно большое на мой взгляд различие в производительности/области применения/другое вполне можно будет с помощью конфигурации? Это обнадеживает. Главное, чтобы для поддержки конфигурирования не пришлось лишний код писать - выбор между асинхронным сервером с io_service на цпу и синхронным сервером с блокирующими сокетами с потоком на каждого клиента, например,  в конфигурации можно прописать, но фактически же будут запускаться разные куски кода, а не просто буфера с разным размером, а эти куски и поддерживать нужно будет по отдельности, чего не хочется.
Я в связи с этим решил пока остановиться на асинхронном сервере, как более универсальном. То что при небольшом кол-ве клиентов он будет проигрывать серверу с потоком на клиент, будет с лихвой компенсироваться меньшей нагрузкой в целом. А при большом кол-ве клиентов асинхронный уже будет выигрывать. Да и реализован он уже у меня частично, в конце концов. smile
PM MAIL   Вверх
boostcoder
Дата 11.11.2011, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(drug007 @  11.11.2011,  09:43 Найти цитируемый пост)
имеется в виду скорость чисто сервера без бизнес-логики?

да.

Цитата(drug007 @  11.11.2011,  09:43 Найти цитируемый пост)
учесть достаточно большое на мой взгляд различие в производительности/области применения/другое вполне можно будет с помощью конфигурации?

да.

Цитата(drug007 @  11.11.2011,  09:43 Найти цитируемый пост)
выбор между асинхронным сервером с io_service на цпу и синхронным сервером с блокирующими сокетами с потоком на каждого клиента, например,  в конфигурации можно прописать, но фактически же будут запускаться разные куски кода, а не просто буфера с разным размером, а эти куски и поддерживать нужно будет по отдельности, чего не хочется.

не-не-не! это что за зоопарк архитектур? для твоей задачи тебе достаточно одного io_service. а остальное пока не известно.

Цитата(drug007 @  11.11.2011,  09:43 Найти цитируемый пост)
То что при небольшом кол-ве клиентов он будет проигрывать серверу с потоком на клиент

это еще почему? smile 

PM WWW   Вверх
drug007
Дата 11.11.2011, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(boostcoder @ 11.11.2011,  10:11)

Цитата(drug007 @  11.11.2011,  09:43 Найти цитируемый пост)
выбор между асинхронным сервером с io_service на цпу и синхронным сервером с блокирующими сокетами с потоком на каждого клиента, например,  в конфигурации можно прописать, но фактически же будут запускаться разные куски кода, а не просто буфера с разным размером, а эти куски и поддерживать нужно будет по отдельности, чего не хочется.

не-не-не! это что за зоопарк архитектур? для твоей задачи тебе достаточно одного io_service. а остальное пока не известно.

Вот как раз зоопарка я и не хочу.

Цитата(boostcoder @ 11.11.2011,  10:11)
Цитата(drug007 @  11.11.2011,  09:43 Найти цитируемый пост)
То что при небольшом кол-ве клиентов он будет проигрывать серверу с потоком на клиент

это еще почему? smile

Дык вот.
Процитирую, на всякий случай:
Цитата(Lazin @ 21.10.2011,  10:07)

...
Добавлено @ 10:09
вообще, если клиентов не много, то асинхронный сервер будет иметь более низкую пропускную способность, нежели простой thread per client сервер выполняющий все операции ввода/вывода синхронно, ибо во втором случае будет меньше системных вызовов


PM MAIL   Вверх
boostcoder
Дата 11.11.2011, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(drug007 @  11.11.2011,  10:25 Найти цитируемый пост)
Дык вот.

у тебя производительность затребована на столько низкая, что я думаю тебе для всего сервера хватит единственного потока. еще и много будет.
PM WWW   Вверх
drug007
Дата 11.11.2011, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(boostcoder @ 11.11.2011,  11:34)
Цитата(drug007 @  11.11.2011,  10:25 Найти цитируемый пост)
Дык вот.

у тебя производительность затребована на столько низкая, что я думаю тебе для всего сервера хватит единственного потока. еще и много будет.

А я про это и говорил.
Насчет одного потока - у меня сейчас как раз один и в нем и сервер, и клиент, и графика на Qt крутится. Но я его и не нагружал толком, нет возможности пока - бизнес-логику еще надо делать.
В общем, я понял, что для решения моей задачи достаточно простого сервера - я взял за основу пример из asio samples и в принципе, на нем можно и остановится. Пока вопросов больше и нет. Спасибо за ответы. smile
PM MAIL   Вверх
mabrarov
Дата 11.11.2011, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(drug007 @ 11.11.2011,  12:35)
я взял за основу пример из asio samples и в принципе, на нем можно и остановится.

Рекомендую брать из trunk-а SVN-репозитория. Нашел недавно пару неприятных ошибок.
P.S. Если Вы имели в виду asio samples а не asio examples smile

Это сообщение отредактировал(а) mabrarov - 11.11.2011, 15:33
PM MAIL WWW Skype   Вверх
drug007
Дата 15.11.2011, 07:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Марат, Ваш qt_echo_server очень бы подошел к моему проекту, но как выяснилось, требования в моем случае настолько низкие, что я решил обойтись вариантом сервера на основе http::server3 из asio.samples (да, я тут описался), поскольку он заметно проще.
Когда я начал изучать qt_echo_server, я несколько по другому взглянул на C++ и мне стала более понятной точка зрения его противников и его сторонников - когда передо мной стоит задача, которую нужно решить и есть жесткий дедлайн, есть классный пример на boos.asio, который то, что надо, но надо его допилить, но для допиливания мне нужно потратить кучу времени чтобы поднять свой уровень владения языком, то конечно я выберу другой язык попроще и буду кричать на каждом углу, что c++ must die (или вроде того) и приводить аргументы.
Если же передо мной стоит та же задача с тем же дедлайном и мой уровень языка достаточен, чтобы я наслаждался, как тонко я могу выразить термины предметной области в структурах языка c++ и просто восхищался, как богат внутренний мир языка и как другие этого могут не видеть, то я бы быстро допилил найденный пример (и еще сэкономил бы тем время) и на каждом углу кричал бы, что лучше c++ нет и приводил бы аргументы.
И в каждом случае я был бы прав - отношение к языку определяется в первую очередь уровнем владения языком. Имхо, конечно, сорри за оффтоп =)

Спасибо всем, кто выкладывает примеры по использованию boost'а вообще и asio в частности, способствуя их популяризации вы делаете мир лучше! =)
PM MAIL   Вверх
mabrarov
Дата 15.11.2011, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(drug007 @ 15.11.2011,  07:37)
...я решил обойтись вариантом сервера на основе http::server3 из asio.samples (да, я тут описался), поскольку он заметно проще.

В качестве оффтопа (продолжения не будет).

Ну... там вся сложность (я уже писал где-то в комментариях в своем блоге) связана с:
  • Поддержкой и MSVC 9.0 (возможно, MSVC 8) и MSVC 10.0 (т.е. я не могу использовать C++11-лямбды, move-semantic опциональна и разделена на exlicit/implicit move constructor из-за MSVC 10.0/GCC 4.5.x/GCC 4.6.x) - убрать "проклятые" #if и #endif (т.е. заточить под определенную платформу/компилятор) и код сократится в разы.
  • Желанием (осознанным) запихнуть в один "sample" максимум "фич" Asio - можно было обойтись и без custom memory allocation.
  • Желанием реализовать наиболее обобщенный вариант state machine для компонент сервера и наиболее обобщенную схему работы сервера (в примерах Asio нет "нормальной" остановки сервера - вообще эту тему обходят стороной почти все open source проекты, что я видел - везде останов сервера пишется как концовка фильма, на которую не хватило сил/бюджета).
  • Все callback-и выполнены в виде обобщенных функторов C++ - это приводит к засилью (нелюбимых мною из-за усложнения) шаблонов.
Я не придумал ничего нового по сравнению с тем, что есть в документации Asio (в т.ч. примерах). Обобщил в одном месте, немного усовершенствовал - и все.

Многопоточные алгоритмы сложны. На C/C++ особенно. С Asio все же по-легче, но все равно надо четко знать все ограничения и перестаривать логику/мышление/стиль программирования.

Это я о причинах сложности. 

А так - с Вашим мнением я согласен. Где-то на rsdn попадался набор "слайдов" (или как там его), в котором между делом проскакивает, как Бьярн Страуструп оценивает свое владение языком C++ на 8 из 10.  smile  Вообще, я на Java работаю (в смылсе "зарабатываю"), и знания Java даже на 1 из 10 мне пока хватает (что несомненно было бы мало для C++).
PM MAIL WWW Skype   Вверх
Lazin
Дата 15.11.2011, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Я вот не вижу причин использовать асинхронный ввод вывод для решения этой задачи.
Event driven сервер будет иметь более высокую пропускную способность нежели threaded сервер только тогда, когда I/O сильно превалирует над обработкой, да и то, только до тех пор, пока программа не упрется в процессор. Event driven архитектура тупо сложнее в реализации, так как логика "размазывается" по куче callback вызовов. Threaded сервер сильно проще, там вся логика для отдельного соединения это просто последовательность действий, выполняемых в отдельном потоке. Помимо этого, event driven подход требует большего количества системных вызовов. Я экспериментировал с пайпами под windows, для IPC, у меня был простой RPC сервер и клиент (echo сервер). Threaded версия имела более чем вдвое низкую латентность, нежели event driven версия.

Это сообщение отредактировал(а) Lazin - 15.11.2011, 08:54
PM MAIL Skype GTalk   Вверх
mabrarov
Дата 15.11.2011, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(Lazin @ 15.11.2011,  08:52)
Event driven архитектура тупо сложнее в реализации, так как логика "размазывается" по куче callback вызовов. Threaded сервер сильно проще, там вся логика для отдельного соединения это просто последовательность действий, выполняемых в отдельном потоке.

Согласен. Только меня постоянно мучает вопрос: "ну все равно же эти потоки как-то должны "общаться" друг с другом?" Критические секции/мютексы очень похожи в этом случае на вырожденный вариант очереди с размерм в один элемент. 
Как сообщить thread-based объекту session, что пора кхм.. завершиться? Тупо закрыть сокет (на котором thread-based session м/б залочена в блокирующем вводе/выводе) в другом потоке - выглядит как-то криво (я знаю, что так и делают). Использовать Windows-события - форменное извращение. Использовать Windows Event для ожидания окончания ввода-вывода + дополнительный Event и WaitForMultipleObjects - натуральный костыль. Понятно, что есть разница м/у "красивая теория" и "суровая практика", но так хочется чего-то обобщенного.

Это сообщение отредактировал(а) mabrarov - 15.11.2011, 09:17
PM MAIL WWW Skype   Вверх
Lazin
Дата 15.11.2011, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Цитата(mabrarov @  15.11.2011,  09:07 Найти цитируемый пост)
Как сообщить thread-based объекту session, что пора кхм.. завершиться? Тупо закрыть сокет в другом потоке - выглядит как-то криво (я знаю, что так и делают). 

Можно не закрывать а сделать сокету shutdown, если религия не позволяет закрывать сокет, можно использовать pooling, читаем из сокета с таймаутом, при достижении таймаута проверяем не нужно ли завершиться, либо не превышено ли критическое время ожидания ответа и выполняем соответствующие действия, можно и закрыть(в чем проблема просто тупо закрыть сокет я не очень понимаю).

Цитата(mabrarov @  15.11.2011,  09:07 Найти цитируемый пост)
Только меня постоянно мучает вопрос: "ну все равно же эти потоки как-то должны "общаться" друг с другом?" Критические секции/мютексы очень похожи в этом случае на вырожденный вариант очереди с размерм в один элемент.

Мы не знаем какая там происходит обработка данных, может там вообще не потребуется синхронизация или потребуется очень простая синхронизация.

Добавлено через 7 минут и 36 секунд
Цитата(mabrarov @  15.11.2011,  09:07 Найти цитируемый пост)
мютексы очень похожи в этом случае на вырожденный вариант очереди с размерм в один элемент

ты не поверишь! xD
мьютекс (если это fair мьютекс) это и есть очередь, самая настоящая, first in first out smile 
PM MAIL Skype GTalk   Вверх
drug007
Дата 15.11.2011, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(Lazin @ 15.11.2011,  08:52)
Я вот не вижу причин использовать асинхронный ввод вывод для решения этой задачи.
Event driven сервер будет иметь более высокую пропускную способность нежели threaded сервер только тогда, когда I/O сильно превалирует над обработкой, да и то, только до тех пор, пока программа не упрется в процессор. Event driven архитектура тупо сложнее в реализации, так как логика "размазывается" по куче callback вызовов. Threaded сервер сильно проще, там вся логика для отдельного соединения это просто последовательность действий, выполняемых в отдельном потоке. Помимо этого, event driven подход требует большего количества системных вызовов. Я экспериментировал с пайпами под windows, для IPC, у меня был простой RPC сервер и клиент (echo сервер). Threaded версия имела более чем вдвое низкую латентность, нежели event driven версия.

Согласен, но к первому предложению добавлю, что также event driven сервер имеет смысл использовать, когда бизнес-логика тоже event driven, как в моем случае. Т.о. drawback от распределенной логики все равно будет присутствовать, зато архитектура приложения будет единой. Плюс это не конкретное задание на конкретный продукт с конкретными требованиями, это больше исследовательская модель для бизнес-логики, поэтому выбор event driven модели как более универсальной оправдан даже несмотря на больший оверкод и оверхед. А уже при допиливании вполне можно будет сделать конкретные версии.


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

Это сообщение отредактировал(а) drug007 - 15.11.2011, 10:49
PM MAIL   Вверх
mabrarov
Дата 15.11.2011, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(Lazin @ 15.11.2011,  09:24)
Можно не закрывать а сделать сокету shutdown, если религия не позволяет закрывать сокет, можно использовать pooling, читаем из сокета с таймаутом, при достижении таймаута проверяем не нужно ли завершиться, либо не превышено ли критическое время ожидания ответа и выполняем соответствующие действия

Это уже выглядит как костыль. Нет, я понимаю что так делали и делают. Это такой "рабочий" вариант - но все равно костыль, как ни крути.

Добавлено @ 10:44
Цитата(Lazin @ 15.11.2011,  09:24)
в чем проблема просто тупо закрыть сокет я не очень понимаю.

Проблемы особой нет. За исключением логики. Наш класс session получается не простой. Его метод session::close() можно вызывать из любого потока в любое время. Но только, если underlying socket library гарантирует то же самое для socket::close() (shutdown). Плохо, когда классы так сильно связаны с потоками. В случае ma::echo::server::session - session связан с task scheduler (asio::io_service::strand и asio::io_service). А тот - с потоками.

Добавлено @ 10:47
Цитата(Lazin @ 15.11.2011,  09:24)
Мы не знаем какая там происходит обработка данных, может там вообще не потребуется синхронизация или потребуется очень простая синхронизация.

В том-то и дело, что синхронизация в каком-либо виде требуется всегда. Даже если это web-сервер. Хотя бы для того чтобы тот же session_manager мог дать команду "завершиться" всем session.

Добавлено @ 10:49
Цитата(Lazin @ 15.11.2011,  09:24)
ты не поверишь! xD
мьютекс (если это fair мьютекс) это и есть очередь, самая настоящая, first in first out smile

Э, ну это уже нечестно  smile  Совсем не в ту степь и, думаю, мы оба с этим согласны.

Это сообщение отредактировал(а) mabrarov - 15.11.2011, 11:18
PM MAIL WWW Skype   Вверх
mabrarov
Дата 15.11.2011, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



На счет оверкода (что-то без регистрации перестали пускать). 
Вкратце, я понимаю, что "не писать сложный код, потому что (именно) условия задачи позволяют обойтись более простым" в производстве нормально. 
"My personal bias is to try to avoid the complexity side of such tradeoffs, but sometimes its advantages are too compelling to ignore" (Andrew Koenig).

Это сообщение отредактировал(а) mabrarov - 15.11.2011, 11:11
PM MAIL WWW Skype   Вверх
mabrarov
Дата 15.11.2011, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(mabrarov @ 15.11.2011,  09:07)
Критические секции/мютексы очень похожи в этом случае на вырожденный вариант очереди с размерм в один элемент.

Я имел в виду shared data (например, флаги и состояния), защищенные критическими секциями/мютексами.

Это сообщение отредактировал(а) mabrarov - 15.11.2011, 11:31
PM MAIL WWW Skype   Вверх
Lazin
Дата 15.11.2011, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Цитата(drug007 @  15.11.2011,  10:40 Найти цитируемый пост)
 бизнес-логика тоже event driven

ето как? smile 

Цитата(drug007 @  15.11.2011,  10:40 Найти цитируемый пост)
Хотя требования к латентности в моем случае высокие

Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
г) Большой пинг (от сотен мс до секунд)

ничего не понял, где они высокие? высокие, это когда десятки микросекунд, а не сотни миллисекунд smile 

Цитата(drug007 @  15.11.2011,  10:40 Найти цитируемый пост)
отказавшись от асинхронного сервера я просто перенесу латентность с ввода/вывода на логику, а латентность все равно останется

латентность сервера = I/O time + CPU time, оно в любом случае никуда не денется, используя разные архитектуры сервера можно немного менять второе слагаемое, но не первое

Цитата(mabrarov @  15.11.2011,  10:40 Найти цитируемый пост)
Это уже выглядит как костыль. Нет, я понимаю что так делали и делают. Это такой "рабочий" вариант - но все равно костыль, как ни крути.

Неа, не костыль. Close - это когда нужно остановить обмен данными через сокет на одной из сторон без ведома второй. Если нужно быстро остановить сервер, то это как раз тот случай. Не костыль, это когда у нас в протоколе есть возможность остановить сессию выполнив определенные действия. А если серверу действительно нужно просто взять и отвалиться, то нужно именно сделать close и все равно из какого потока, главное что-бы все отвалилось сразу.

Цитата(mabrarov @  15.11.2011,  10:40 Найти цитируемый пост)
В том-то и дело, что синхронизация в каком-либо виде требуется всегда

И в event driven архитектуре в том числе. Мало того, в event driven сервере ее сделать сложнее, ибо нужно синхронизировать не только разные сессии но и внутри сессии. Скажем в рамках одного подключения пришли 2 сообщения, одно начало обрабатываться в одном потоке, второе в другом. Именно поэтому в asio есть strand-ы. Либо у нас будет один io_service на поток, в этом случае вам придется возиться с балансировкой нагрузки. В случае threaded сервера нужно просто синхронизировать доступ к общим данным. Это проще. Можно вообще построить threaded сервер так, что-бы каждый поток крутил что-то вроде цикла обработки сообщений, тобишь был event driven но в рамках одного соединения, в этом случае можно будет отказаться от общей памяти, организовав обмен сообщениями между потоками.

Цитата(mabrarov @  15.11.2011,  10:40 Найти цитируемый пост)
Наш класс session получается не простой. Его метод session::close() можно вызывать из любого потока в любое время. Но только, если underlying socket library гарантирует то же самое для socket::close() (shutdown). Плохо, когда классы так сильно связаны с потоками. В случае ma::echo::server::session - session связан с task scheduler (asio::io_service::strand и asio::io_service). А тот - с потоками.

Это плохо только тогда, когда сессий может быть очень много. В остальных случаях это скорее хорошо, ибо не нужно об этом думать.
PM MAIL Skype GTalk   Вверх
mabrarov
Дата 15.11.2011, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(Lazin @ 15.11.2011,  11:42)
латентность сервера = I/O time + CPU time, оно в любом случае никуда не денется, используя разные архитектуры сервера можно немного менять второе слагаемое, но не первое

Согласен.
PM MAIL WWW Skype   Вверх
Lazin
Дата 15.11.2011, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



вообще, автор писал что у него тяжелая обработка данных происходит, это автоматически означает низкую пропускную способность event driven сервера

max event dirven server throughput = number of CPUs / CPU time per query

для многопоточного сервера:

max threaded server throughput = number of threads / (IO time per query + CPU time per query)

вторая формула справедлива до тех пор, пока мы еще не уперлись в возможности процессора, то есть он не загружен на 100%
отсюда видно, что в том случае, если IO time per query сильно больше чем CPU time per query, то нужно использовать event driven архитектуру, в противном случае(интенсивные вычисления) - нужно использовать threaded архитектуру smile 


PM MAIL Skype GTalk   Вверх
mabrarov
Дата 15.11.2011, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(Lazin @ 15.11.2011,  11:42)
Неа, не костыль. Close - это когда нужно остановить обмен данными через сокет на одной из сторон без ведома второй. Если нужно быстро остановить сервер, то это как раз тот случай. Не костыль, это когда у нас в протоколе есть возможность остановить сессию выполнив определенные действия. А если серверу действительно нужно просто взять и отвалиться, то нужно именно сделать close и все равно из какого потока, главное что-бы все отвалилось сразу.

Все дело в том, что в идеале, хотелось бы иметь по-меньше классов (тот же сокет), которые имели бы thread-safe методы, так как это дается не бесплатно и предполагает, что класс заранее планировался для использования в многопоточной среде. Плохо by-design, но вполне используется, потому как никому не хочется лезть в дебри event driven.

Добавлено @ 11:57
Цитата(Lazin @ 15.11.2011,  11:52)
вообще, автор писал что у него тяжелая обработка данных происходит, это автоматически означает низкую пропускную способность event driven сервера

max event dirven server throughput = number of CPUs / CPU time per query

для многопоточного сервера:

max threaded server throughput = number of threads / (IO time per query + CPU time per query)

вторая формула справедлива до тех пор, пока мы еще не уперлись в возможности процессора, то есть он не загружен на 100%
отсюда видно, что в том случае, если IO time per query сильно больше чем CPU time per query, то нужно использовать event driven архитектуру, в противном случае(интенсивные вычисления) - нужно использовать threaded архитектуру smile

Ну это вроде бы уже "обсосали". Конечно, да. Классика же. Я просто о своем (о наболевшем) начал, как обычно.

Добавлено @ 12:01
Цитата(Lazin @ 15.11.2011,  11:42)
И в event driven архитектуре в том числе. Мало того, в event driven сервере ее сделать сложнее, ибо нужно синхронизировать не только разные сессии но и внутри сессии. Скажем в рамках одного подключения пришли 2 сообщения, одно начало обрабатываться в одном потоке, второе в другом. Именно поэтому в asio есть strand-ы. Либо у нас будет один io_service на поток, в этом случае вам придется возиться с балансировкой нагрузки.

В том-то и дело, что в event driven архитектуре на базе Asio мы (архитектурно) разгружаем класс session от непосредственной синхронизации (и от знания того, что он будет использоваться в многопоточной среде), оставляя синхронизацию strand-ам.

Добавлено @ 12:04
Цитата(Lazin @ 15.11.2011,  11:42)
Можно вообще построить threaded сервер так, что-бы каждый поток крутил что-то вроде цикла обработки сообщений, тобишь был event driven но в рамках одного соединения, в этом случае можно будет отказаться от общей памяти, организовав обмен сообщениями между потоками.

"что-то вроде цикла обработки сообщений" обеспечивает strand.
"в этом случае можно будет отказаться от общей памяти, организовав обмен сообщениями между потоками" - так это и есть очередь - та же общая память, почти тот же strand.

Пора заканчивать. Сплошной оффтоп пошел. Просто приятно обсудить наболевшие вопросы.

Это сообщение отредактировал(а) mabrarov - 15.11.2011, 12:08
PM MAIL WWW Skype   Вверх
Lazin
Дата 15.11.2011, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Цитата(mabrarov @  15.11.2011,  11:55 Найти цитируемый пост)
Все дело в том, что в идеале, хотелось бы иметь по-меньше классов (тот же сокет), которые имели бы thread-safe методы, так как это дается не бесплатно и предполагает, что класс заранее планировался для использования в многопоточной среде. Плохо by-design, но вполне используется, потому как никому не хочется лезть в дебри event driven. 

с каких это пор ф-я WSAClose стала классом? smile
шутка
вам не кажется, что использовать event driven подход для того что-бы остановить event driven систему это как-то не ок? я лично люблю останавливать сервер так, что-бы это произошло за ограниченное время (1), каждая сессия смогла обработать разрыв соединения так, что-бы не испортить что-либо в базе или еще где нибудь (2). Вот close для этого оч. хорошо подходит. В коде потока сессии это все выражается в том, что один из send-ов или recv-ов бросает исключение а какой-нибудь try - catch его ловит. Причем все это происходит в предсказуемом порядке, сначала перестаем принимать новые подключения, потом закрываем первую сессию, первая сессия завершилась, закрываем вторую... 
В случае event driven тоже все просто, только вместо try catch у нас вызывается один из хэндлеров. Проблема этого подхода в том, что нужно явным образом посигналить(установить event или еще что нибудь) о том что сессия - все. Помимо этого, код обработки разрыва соединения приходится дублировать между всеми обработчиками. Помимо этого сокет может быть закрыт не только во время ожидания выпонения операции чтения-записи, но и во время обработки данных, в этом случае следующий вызов send_async/recv_async (или как это там называется) бросит исключение, вот вам еще одна точка обработки ситуации разрыва соединения. В общем, сложнее это. smile

Добавлено через 9 минут и 14 секунд
Цитата(mabrarov @  15.11.2011,  11:55 Найти цитируемый пост)
"что-то вроде цикла обработки сообщений" обеспечивает strand.
"в этом случае можно будет отказаться от общей памяти, организовав обмен сообщениями между потоками" - так это и есть очередь - та же общая память, почти тот же strand.

нужно помнить что у тебя все должно идти через strand, вызовешь случайно метод класса - сессии не через strand и все smile 
хотя я согласен с тем что если мы пришли к тому что-бы городить цикл обработки сообщений внутри каждого потока, то проще просто использовать boost.asio

Цитата(mabrarov @  15.11.2011,  11:55 Найти цитируемый пост)
Пора заканчивать.

у меня - все smile 
PM MAIL Skype GTalk   Вверх
drug007
Дата 15.11.2011, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(Lazin @ 15.11.2011,  11:42)
Цитата(drug007 @  15.11.2011,  10:40 Найти цитируемый пост)
 бизнес-логика тоже event driven

ето как? smile 

В общих чертах бизнес-логика представляет собой набор взаимосвязанных КА (и сама КА тоже). Переход одного КА в другое состояние может являться событием для других. И такая "волна" событий распространяется от источника первоначального события. И таких источников много, и они влияют друг на друга. Более того, КА появляются и удаляются динамически. Плюс есть задача репликации данных между серверами - проще делать репликацию, когда у тебя есть событие, которое говорит, что такие-то данные изменились, линейный алгоритм может означать только периодический обзор всех данных на предмет изменения. 
На данный момент я думаю, что реализовать такую модель линейным алгоритмом будет сложнее, чем с помощью событий. Хотя я могу заблуждаться.

Немного оффтоп, но насколько верны мои предположения о простоте реализации такого способа репликации?

Цитата(Lazin @ 15.11.2011,  11:42)

Цитата(drug007 @  15.11.2011,  10:40 Найти цитируемый пост)
Хотя требования к латентности в моем случае высокие

Цитата(drug007 @  8.11.2011,  13:36 Найти цитируемый пост)
г) Большой пинг (от сотен мс до секунд)

ничего не понял, где они высокие? высокие, это когда десятки микросекунд, а не сотни миллисекунд smile 

Пинг, что я привел, это качество каналов связи. Это не требование иметь такую латентность, а требование сохранять функциональность при таком пинге. Ибо сервер, работоспособный в LAN, при первом же запуске в WAN показал, что такие пинги не для него.
Сам же сервер должен иметь латентность, стремящуюся к нулю.

Цитата(Lazin @ 15.11.2011,  11:42)

Цитата(drug007 @  15.11.2011,  10:40 Найти цитируемый пост)
отказавшись от асинхронного сервера я просто перенесу латентность с ввода/вывода на логику, а латентность все равно останется

латентность сервера = I/O time + CPU time, оно в любом случае никуда не денется, используя разные архитектуры сервера можно немного менять второе слагаемое, но не первое

Вот тут категорически не соглашусь. Вы же сами утверждали, что потоковая версия имела латентность вдвое меньше чем асинхронная? А это как раз первое слагаемое.


PM MAIL   Вверх
Lazin
Дата 15.11.2011, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Цитата(drug007 @  15.11.2011,  12:23 Найти цитируемый пост)
Вот тут категорически не соглашусь. Вы же сами утверждали, что потоковая версия имела латентность вдвое меньше чем асинхронная? А это как раз первое слагаемое.

так то для IPC на одной машине, асинхронная версия делала в 2 раза больше системных вызовов чем синхронная

Цитата(drug007 @  15.11.2011,  12:23 Найти цитируемый пост)
В общих чертах бизнес-логика представляет собой набор взаимосвязанных КА (и сама КА тоже). Переход одного КА в другое состояние может являться событием для других. И такая "волна" событий распространяется от источника первоначального события. И таких источников много, и они влияют друг на друга. Более того, КА появляются и удаляются динамически. Плюс есть задача репликации данных между серверами - проще делать репликацию, когда у тебя есть событие, которое говорит, что такие-то данные изменились, линейный алгоритм может означать только периодический обзор всех данных на предмет изменения. 
На данный момент я думаю, что реализовать такую модель линейным алгоритмом будет сложнее, чем с помощью событий. Хотя я могу заблуждаться.

Немного оффтоп, но насколько верны мои предположения о простоте реализации такого способа репликации?


события != асинхронность, в данном случае все очень даже синхронно, изменилось состояние -> сгенерировалось событие -> изменилось состояние другого КА и тд
вот если бы изменения в разных КА могли происходить с разной скоростью, то это была бы асинхронная модель, но я не вижу в этом смысла
PM MAIL Skype GTalk   Вверх
drug007
Дата 15.11.2011, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(Lazin @ 15.11.2011,  11:52)
вообще, автор писал что у него тяжелая обработка данных происходит, это автоматически означает низкую пропускную способность event driven сервера

max event dirven server throughput = number of CPUs / CPU time per query

для многопоточного сервера:

max threaded server throughput = number of threads / (IO time per query + CPU time per query)

вторая формула справедлива до тех пор, пока мы еще не уперлись в возможности процессора, то есть он не загружен на 100%
отсюда видно, что в том случае, если IO time per query сильно больше чем CPU time per query, то нужно использовать event driven архитектуру, в противном случае(интенсивные вычисления) - нужно использовать threaded архитектуру smile

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

Это сообщение отредактировал(а) drug007 - 15.11.2011, 12:47
PM MAIL   Вверх
mabrarov
Дата 15.11.2011, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(Lazin @ 15.11.2011,  12:09)
вам не кажется, что использовать event driven подход для того что-бы остановить event driven систему это как-то не ок? 

Ну почему же. 

Как раз в event driven системе останов (имеется в виду плановый, а не исключительная ситуация с обрывом всего и вся) - это просто event, который получает сессия. Дальше она уже сама правильно (!) завершит работу. Например, сначала дождется окончания обработки очередного запроса СУБД, отправит подготовленный ответ, а уже потом сделает shutdown + close. 

В случае же прямого вызова socket::close() из другого потока, если поток (thread) сессии был заблокирован на "отправке подготовленного ответа" (блокирующий socket::write()) - мы как раз получим невозможность реализации планового останова.

Конечно, в реальности "прямой вызов socket::close() из другого потока" для планового останова threaded session никто не делает. Просто session в случае, если сокет закрывать нельзя ("отправка подготовленного ответа") через примитивы синхронизации лочит session shared data и устанавливает флаг "не вздумайте закрыть сокет". session::close() так же лочит session shared data, если "разрешено" - закрывает сокет и, наконец, обязательно устанавливает флаг "пора закругляться по такой-то причине" (а ниже основной поток сервера уже ждет а-ля session::join()). threaded session в этом случае должна так же периодически лочить session shared data и проверять флаг останова (ну да, atomic-варианты никто не отменял) - чувствуете, насколько логика такой session связана с потоками в отличие от использования asio::io_service::strand (который, по сути, обычная concurrent очередь функторов)?.

Логика в обоих случаях одна и та же. Просто event driven + threads "разрывает мозг" необходимостью выносить участки кода (те что в threaded session идут м/у проверками флага останова) в отдельные event/task и добавляет накладных расходов (нехило так - как и любой task-based parallelism). В реальном мире - все есть КА. И работает как раз event driven и именно параллельно. Event driven сложнее именно из-за C/C++ - у этих языков все на более низком уровне (и хорошо). Взять тот же Erlang, и, думаю, будет уже не так "больно мозгу".

На этом закончу мое участие в теме (особенно, с учетом того, что я согласен с Lazin и меня просто задевает то, что частенько стараются избавиться от сложности многопоточных асинхронных event-driven серверов лишь потому, что... нет готового решения по типу "просто написать модуль для nginx") и пойду обедать.  smile 

Это сообщение отредактировал(а) mabrarov - 15.11.2011, 13:48
PM MAIL WWW Skype   Вверх
drug007
Дата 15.11.2011, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



В первую очередь хотел бы еще раз поблагодарить за ответы участников. Приятно пообщаться со знающими людьми. (Хотя вы больше между собой, правда  smile  )

Цитата(Lazin @ 15.11.2011,  12:41)
Цитата(drug007 @  15.11.2011,  12:23 Найти цитируемый пост)
Вот тут категорически не соглашусь. Вы же сами утверждали, что потоковая версия имела латентность вдвое меньше чем асинхронная? А это как раз первое слагаемое.

так то для IPC на одной машине, асинхронная версия делала в 2 раза больше системных вызовов чем синхронная

Вы меня все-таки тут путаете...

Цитата(Lazin @ 15.11.2011,  12:41)

Цитата(drug007 @  15.11.2011,  12:23 Найти цитируемый пост)
В общих чертах бизнес-логика представляет собой набор взаимосвязанных КА (и сама КА тоже). Переход одного КА в другое состояние может являться событием для других. И такая "волна" событий распространяется от источника первоначального события. И таких источников много, и они влияют друг на друга. Более того, КА появляются и удаляются динамически. Плюс есть задача репликации данных между серверами - проще делать репликацию, когда у тебя есть событие, которое говорит, что такие-то данные изменились, линейный алгоритм может означать только периодический обзор всех данных на предмет изменения. 
На данный момент я думаю, что реализовать такую модель линейным алгоритмом будет сложнее, чем с помощью событий. Хотя я могу заблуждаться.

Немного оффтоп, но насколько верны мои предположения о простоте реализации такого способа репликации?


события != асинхронность, в данном случае все очень даже синхронно, изменилось состояние -> сгенерировалось событие -> изменилось состояние другого КА и тд
вот если бы изменения в разных КА могли происходить с разной скоростью, то это была бы асинхронная модель, но я не вижу в этом смысла

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

Это сообщение отредактировал(а) drug007 - 15.11.2011, 13:36
PM MAIL   Вверх
Олег2005
Дата 16.11.2011, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(drug007 @  15.11.2011,  12:26 Найти цитируемый пост)
вполне возможно, что я мешаю понятия асинхронного наступления события и асинхронного завершения обработки события. 

Вполне возможно что именно так......
Они разнесены во времени......
PM MAIL WWW MSN   Вверх
drug007
Дата 17.11.2011, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(Олег2005 @ 16.11.2011,  15:51)
Цитата(drug007 @  15.11.2011,  12:26 Найти цитируемый пост)
вполне возможно, что я мешаю понятия асинхронного наступления события и асинхронного завершения обработки события. 

Вполне возможно что именно так......
Они разнесены во времени......

Попробую уточнить свое понимание понятия асинхронности:
события в event driven архитектуре всегда наступают асинхронно по определению — мы никогда не знаем, когда произойдет то или иное событие.
Если получив событие, мы его тут же обрабатываем и пока не обработаем текущий поток не возвращает управление, то у нас синхронная обработка.
Если получив событие, текущий поток тут же возвращает управление, а обработка выполняется ядром или в отдельном потоке/процессе, то у нас асинхронная обработка.

т. е. имея асинхронные события, мы можем реагировать на них синхронно или асинхронно. Правильно?

Возвращаясь к выбору архитектуры, я быстренько накидал простенькую модель асинхронной и синхронной на базе потоков. У меня получилось, что время работы у этих архитектур следующее:
    Ttotal async  = N * 2 * Tsyscall  + N * Tprocessing
    Ttotal thread = (N - 1) * Tcontextswitch + N * Tprocessing, 

    где  Ttotal async – время обработки данных в асинхронной архитектуре,
    Ttotal thread – время обработки данных в потоковой модели
    N – количество событий, подлежащих обработке (т. е. соединений),  
    Tsyscall – время системного вызова (двойка т. к. вызовов два на одно событие), 
    Tcontextswitch – время переключения контекста (N-1 т. к. между 2мя событиями 1 переключение, между 3мя — 2 и т.д.),
    Tprocessing — время обработки события, в обоих вариантах одинаковое. 

Первое слагаемое время работы системы ввода/вывода, второе слагаемое время работы бизнес-логики, считаем, что второе слагаемое одинаковое. Отсюда если Tsyscall меньше чем (примерно) 0.5* Tcontextswitch, выигрыш у асинхронной архитектуры, т. к. (Tcontextswitch – 2*Tsyscall) > 0.
Однако при Tprocessing >> (Tcontextswitch - 2*Tsyscall), выигрыш потеряет значение на фоне общей вычислительной нагрузки, при этом модель thread pool проще в разработке и сопровождении, также формулы не учитывают скорость поступления событий или степень нагрузки цпу, что то же самое.
Если же Tprocessing того же порядка или меньше чем (Tcontextswitch – 2*Tsyscall), то выбор за асинхронной архитектурой.
Мои выводы верны? Если да, то продолжу =)
PM MAIL   Вверх
boostcoder
Дата 17.11.2011, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(drug007 @  17.11.2011,  09:34 Найти цитируемый пост)
Если получив событие, мы его тут же обрабатываем и пока не обработаем текущий поток не возвращает управление, то у нас синхронная обработка.

да.

Цитата(drug007 @  17.11.2011,  09:34 Найти цитируемый пост)
Если получив событие, текущий поток тут же возвращает управление, а обработка выполняется ядром или в отдельном потоке/процессе, то у нас асинхронная обработка.

да.

Цитата(drug007 @  17.11.2011,  09:34 Найти цитируемый пост)
т. е. имея асинхронные события, мы можем реагировать на них синхронно или асинхронно. Правильно?

да.

Цитата(drug007 @  17.11.2011,  09:34 Найти цитируемый пост)
Мои выводы верны?

на мой взгляд - да.
PM WWW   Вверх
drug007
Дата 17.11.2011, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



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

Это сообщение отредактировал(а) drug007 - 17.11.2011, 14:23
PM MAIL   Вверх
boostcoder
Дата 17.11.2011, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



получается так.
но мое ИМХО - мне как-то логически привычней асинхронные реализации.

Добавлено @ 14:10
я пытаюсь отделить ввод/вывод от логики используя disruptor. это позволит абстрагировать логику от ввода/вывода и даст более гибкую и расширяемую структуру.

Это сообщение отредактировал(а) boostcoder - 17.11.2011, 14:22
PM WWW   Вверх
drug007
Дата 17.11.2011, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Ок, буду считать, что с понятием асинхронности я определился.

Тогда опять по выбору архитектуры. Немного повторю предпоследний свой пост, правда.
Получается, что в общем случае мы имеем на входе N событий (это может быть как получение/передача данных, так и соединение/завершение соединения). На обработку каждого события ЦПУ тратит Tprocessing времени. Плюс время на обработку события системой ввода/вывода. Общие затраты времени на обработку N событий равны равны сумме затрат на обработку событий системой ввода/вывода и бизнес-логикой, которые для асинхронной архитектуры складываются из:
Ttotal async = N *2 * Tsyscall + N*Tprocessing,
т. е. затраты будут складываться из стоимости двух системных вызовов (начало и завершение асинхронной операции) на каждое событие плюс время на обработку события бизнес-логикой.
для синхронной:
Ttotal sync = (N-1)*P*Tcontext switch + N*Tprocessing
где P - вероятность переключения контекста, зависит от скорости поступления событий М, времени обработки Tprocessing и числа потоков в пуле k:
    P = 0; при M < 1/Tprocessing - все события обрабатываются одним потоком, нет переключений контекста
    P = M*Tprocessing/k; при M > 1/Tprocessing и M < k/Tprocessing - задействована часть потоков пула, периодически происходит переключение контекста
    P = 1; при M > k/Tprocessing - задействованы все потоки из пула, переключение контекста происходит каждое событие
здесь затраты складываются из времени на переключение контекста плюс время обработки бизнес-логикой. При этом количество переключений контекста меньше чем количество событий минимум на единицу, т. к. необходимость переключения контекста может возникнуть не раньше второго события. Если события поступают со скоростью, позволяющей все события обрабатывать в одном потоке, то количество переключений контекста будет равно нулю. Т.е. если в 1 секунду мы получаем M событий, такое что M <= 1/Tprocessing, то Tcontext switch = 0 (мы понимаем, что цена вызова функции recv и send не зависит от архитектуры, поэтому здесь их не учитываем). Если мы получаем события со скоростью, не позволяющей их обрабатывать одним потоком, то возникают переключения контекста и если мы получаем за 1 секунду М событий, такое, что M > k/Tprocessing, где k – количество потоков в пуле синхронной архитектуры, то контекст будет переключатся N-1 раз на каждые N событий (т.е. начиная со второго события). При M на интервале от 1/Tprocessing до k/Tprocessing вероятность переключения контекста будет соответственно от 0 до 1 (в формуле я взял линейное распределение вероятности для простоты, все равно грубая модель, отражает только мгновенное значение, по идее надо интегрировать, но понятия не имею как smile ). 

Отсюда у меня получилось, что:
1) чем больше событий, тем выгоднее асинхронная архитектура, при малом количестве выигрыш синхронной значителен.
2) время обработки в асинхронной не зависит от скорости поступления событий, как в синхронной, поэтому чем выше скорость поступления событий, тем выгоднее асинхронная архитектура (либо увеличивать число потоков в синхронной)
3) чем больше время обработки, тем больше асинхронная архитектура теряет свои позиции
4) и т. д.
Тут бы графики показать, нагляднее было бы... Как это лучше сделать? Мне кажется, получилось бы хорошее дополнение к вопросу о производительности различных архитектур сервера.


Цитата(boostcoder @ 17.11.2011,  14:05)
получается так.
но мое ИМХО - мне как-то логически привычней асинхронные реализации.

Добавлено @ 14:10
я пытаюсь отделить ввод/вывод от логики используя disruptor. это позволит абстрагировать логику от ввода/вывода и даст более гибкую и расширяемую структуру.

Я тоже склоняюсь к асинхронной в своем проекте, но производительность иногда важна smile
Про disruptor обязательно почитаю, сегодня уже некогда, но вещь интересная, спасибо за ссылку.

Это сообщение отредактировал(а) drug007 - 17.11.2011, 14:31
PM MAIL   Вверх
boostcoder
Дата 17.11.2011, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(drug007 @  17.11.2011,  14:24 Найти цитируемый пост)
но производительность иногда важна

по этому я и решил отделить ввод/вывод от логики при помощи disruptor.

Добавлено через 4 минуты и 6 секунд
Цитата(drug007 @  17.11.2011,  14:24 Найти цитируемый пост)
Тут бы графики показать, нагляднее было бы... Как это лучше сделать?

в следствии этой темы, я сейчас работаю над эталонными тестами. но тут самое сложное(как и с любыми тестами) - эти тесты должны быть действительно эталоном. ну или хотя бы большинство из тестеров должны получить приблизительно одинаковые результаты этих тестов.
PM WWW   Вверх
Lazin
Дата 17.11.2011, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



вот - http://evgeny-lazin.blogspot.com/2011/11/t...ent-driven.html
навеяно в том числе и этим топиком

Добавлено @ 21:57
бесстыдный само-пиар!  smile 

Это сообщение отредактировал(а) Lazin - 17.11.2011, 21:57
PM MAIL Skype GTalk   Вверх
drug007
Дата 18.11.2011, 05:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(boostcoder @ 17.11.2011,  14:35)

Цитата(drug007 @  17.11.2011,  14:24 Найти цитируемый пост)
Тут бы графики показать, нагляднее было бы... Как это лучше сделать?

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

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

Добавлено через 9 минут и 2 секунды
Цитата(Lazin @ 17.11.2011,  21:50)
вот - http://evgeny-lazin.blogspot.com/2011/11/t...ent-driven.html
навеяно в том числе и этим топиком

Добавлено @ 21:57
бесстыдный само-пиар!  smile

Согласен с комментариями Марата - не совсем безупречны ваши выкладки, нужны уточнения. Хотя выводы большей частью верные и я с ними согласен, но обоснование не всегда прозрачно и мне показалось, что вы под свое уже сформировавшееся мнение подогнали матаппарат, вместо того, чтобы сформировать мнение на основе матаппарата. smile

PM MAIL   Вверх
Lazin
Дата 18.11.2011, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Цитата(drug007 @  18.11.2011,  05:24 Найти цитируемый пост)
Согласен с комментариями Марата - не совсем безупречны ваши выкладки, нужны уточнения.

нужны конечно, просто пост итак большим получился, к тому же, большинству эти уточнения читать было-бы не интересно, они довольно очевидны smile

Цитата(drug007 @  18.11.2011,  05:24 Найти цитируемый пост)
Хотя выводы большей частью верные и я с ними согласен, но обоснование не всегда прозрачно и мне показалось, что вы под свое уже сформировавшееся мнение подогнали матаппарат, вместо того, чтобы сформировать мнение на основе матаппарата.

Этому матаппарату в обед сто лет, в смысле ничего я не подгонял и все там достаточно прозрачно. Если не понятно почему именно так и откуда такие выводы, могу объяснить smile

Выкладки, учитывающие время переключения контекста и длительность системных вызовов, на мой взгляд, вообще бесполезны, так как не учитывают главного. Допустим мы пишем под windows и используем IOCP. Вызов GetQueuedCompletionStatus действительно не будет приводить к переключению контекста, но, когда мы вытащим из него очередной completion packet, нам нужно будет восстановить контекст выполнения. Это можно сделать, например прочитав значение указателя на функцию обработчик из OVERLAPPED структуры и вызвав ее с нужными параметрами. Так вот этот overhead тоже нужно учитывать. В случае многопоточного сервера это делать не нужно, так как поток это и есть контекст выполнения и им не нужно явно управлять, адрес обработчика уже находится в IP регистре, а все нужные переменные уже находятся в стеке smile
Помимо этого, event based сервер может быть многопоточным, в этом случае completion packet может быть обработан на любом ядре, что приведет к кэш промаху, а потоки обычно бывают привязаны к одному ядру.
Вообще, на мой взгляд, event based подход к созданию сереверов это костыль. Если подумать, то используя IOCP, epool или kqueue программист создает свои потоки, сам таскает контекст, сам управляет переключением этих контекстов. Все из-за того что потоки плохо масштабируются, в своей текущей реализации.

PM MAIL Skype GTalk   Вверх
drug007
Дата 18.11.2011, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Цитата(Lazin @ 18.11.2011,  09:24)

Этому матаппарату в обед сто лет, в смысле ничего я не подгонял и все там достаточно прозрачно. Если не понятно почему именно так и откуда такие выводы, могу объяснить smile


Объясните.  smile  Например я категорически несогласен когда вы описываете, что производительность многопоточного сервера T = M/(I+C), а производительность асинхронного T = N/C. ИМХО первая формула является частным случаем второй, т.к. вторая описывает производительность идеального сервера с идеальной подсистемой ввода/вывода, а первая описывает идеальный сервер с неидеальной подсистемой ввода/вывода. Ибо знаменатели в них равны, т.к. в любом случае производительность потоков никогда не будет больше, чем производительность ЦПУ. Поэтому сравнение некорректное, а выводы в принципе правильные. smile



Цитата(Lazin @ 18.11.2011,  09:24)

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

Не то, чтобы главного, но многого они не учитывают, это да. Об этом я вчера вечером и подумал, отчего и огорчился немного.

З.Ы. ваша модель этого тоже не учитывает, кстати   smile 
PM MAIL   Вверх
Lazin
Дата 18.11.2011, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Цитата(drug007 @  18.11.2011,  10:13 Найти цитируемый пост)
Например я категорически несогласен когда вы описываете, что производительность многопоточного сервера T = M/(I+C), а производительность асинхронного T = N/C.

там есть оговорка по поводу того, что первая формула верна только до тех пор, пока процессор не будет загружен на 100%
для одного потока справедливо соотношение - время выполнения запроса = время выполнения синхронных операций ввода вывода + время обработки, это очевидно, ибо во время выполнения синхронного ввода/вывода поток простаивает
выглядит это как-то так:
user posted image
красный график - I/O, зеленый - CPU
важное допущение, мы считаем что I/O подсистема у нас - идеальна, обладает бесконечной пропускной способностью и concurrency, а CPU - нет. Теперь, если мы запустим 2 потока, то I/O у нас сможет происходить параллельно, а обработка - нет (считаем что CPU - один)
то бишь, пропускная способность одного потока:
1/(I + C), I - время выполнения I/O операций запроса, С - время обработки, если запустить K потоков, то пропускная способность будет выше в K раз, но только если процессор не полностью загружен. если он загружен полностью, то добавление еще одного потока не приведет к увеличению пропускной способности. При таком K, при котором процессор загружен полностью, пропускная способность сервера максимальная, но при этом, пропускная способность сервера ограничена сверху. В результате зависимость T от K должна быть примерно такой (в реальности она такой будет только при сравнительно небольшом К - десятки, сотни потоков):
user posted image

в случае асинхронного сервера, пропускная способность максимальна тогда, когда процессор загружен полностью, полностью он загружен тогда, когда непрерывно обрабатывает completion handler-ы от завершившихся операций ввода вывода, отсюда очевидна формула:
T = 1/C (для одного ядра)
можно сказать что С - время выполнения всех обработчиков, которые вызываются при обработке запроса. накладные расходы, связанные с работой ОС мы игнорируем, считаем что процессор целиком принадлежит нашему приложению (на самом деле это даст не такую уж и большую погрешность)

если теперь мы приравняем две эти пропускные способности, это можно сделать, ибо макс. пропускная способность сервера в случае идеальной I/O подсистемы с бесконечными ресурсами ограничивается только процессором, то получим:
1/C = K/(I + C), 
откуда можно получить K - число потоков при котором достигается пропускная способность, эквивалентная event driven серверу
если K - десятки/сотни, то возиться с событиями нет никакого смысла
естественно здесь есть погрешности, допущения и неточности, вот только это не мешает оценить порядок K, а именно порядок K нас и интересует

Добавлено через 6 минут и 4 секунды
Цитата(drug007 @  18.11.2011,  10:13 Найти цитируемый пост)
З.Ы. ваша модель этого тоже не учитывает, кстати

я и не пытаюсь считать такие подробности, меня как правило порядок цифры интересует, а не конкретное значение

Это сообщение отредактировал(а) Lazin - 18.11.2011, 11:54
PM MAIL Skype GTalk   Вверх
mabrarov
Дата 18.11.2011, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: нет
Всего: 9



Цитата(Lazin @ 18.11.2011,  09:24)
Вообще, на мой взгляд, event based подход к созданию сереверов это костыль. Если подумать, то используя IOCP, epool или kqueue программист создает свои потоки, сам таскает контекст, сам управляет переключением этих контекстов. Все из-за того что потоки плохо масштабируются, в своей текущей реализации.

Ну это как  сказать.
Надо все же отделить event driven, где каждый event loop (active object, actor) крутится в отдельном потоке ("thread-per-object-loop"), от event driven на базе пула потоков ("event driven with thread-pool").

В данном обсуждении под "event driven" понимается как раз "event driven with thread-pool", что, действительно, похоже на костыль. Хотя... все ресурсы ограничены. В любом случае где-то все равно должно быть сужение N (кол-во обслуживаемых клиентов) -> M (кол-во ядер процессора).

"thread-per-object-loop", кажется, исповедует Erlang. С теоретической точки зрения этот вариант лучше (естественней) описывает процесс "обслуживания" клиента. Ну и, конечно, природа event driven позволяет логике "thread-per-object-loop" плавно перетекать в "event driven with thread-pool" (простота переноса кода сильно зависит от языка/инструментария).

Мой предыдущий пост был как раз про то, что "thread-per-session" тоже "не сахар". Приходится аккуратно работать с shared data. Много логики остается в проверках флагов и синхронизации. Вообще, класс session архитектурно получается сильно связан с понятием thread. Приходится явно выделять shared data и обеспечивать отдельный доступ к этой части session. Так что, чем больше shared data, тем ближе оверкод "thread-per-session" к оверкоду "event-driven" ("thread-per-object-loop" или "event driven with thread-pool").

P.S. Автор темы все еще не определился с архитектурой?


Это сообщение отредактировал(а) mabrarov - 18.11.2011, 16:29
PM MAIL WWW Skype   Вверх
drug007
Дата 21.11.2011, 08:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: 1
Всего: 1



Определился - асинхронная.

Благодаря обсуждению, я пришел к выводу, что для текущих требований оптимальна будет архитектура thread-per-connection и по сложности и по быстродействию, но она плохо масштабируема, а требования могут поменяться и я решил остановится на асинхронной архитектуре, как более универсальной. У нее ИМХО один недостаток - сложность, но в данном случае он приемлем.

PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1139 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.