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

Поиск:

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


 




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


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

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