OberonCore https://forum.oberoncore.ru/ |
|
Особенности работы TCP-сокетов https://forum.oberoncore.ru/viewtopic.php?f=27&t=2151 |
Страница 1 из 2 |
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 12:45 ] |
Заголовок сообщения: | Особенности работы TCP-сокетов |
Занялся вот в образовавшийся день оптимизацией ![]() Коллеги, кто-нибудь может строго объяснить такие моменты: 1) Когда сервер работает под большой нагрузкой (обслуживается много параллельно открытых сокетов - запросов), то статистически прилично шустрее работает при разбитии на мелкие порции FOR i := 1 TO 4 WriteBytes(..., 256) END по сравнению с WriteBytes(..., 1024). Алгоритм Нагля при большой нагрузке начинает пулять более мелкими пакетами и оно быстрее уходит? Тогда: насколько эти параметры будут зависеть от машины (т.е. не окажется ли совсем наоборот на технике другой производительности, в разных ОС)? 2) Тогда уж до кучи вопрос... Была такая история. В ситуации, когда последним sendbytes записывается малый "хвостик" данных (< 40 байт), был сильный протормоз их отправки (фактически, скорость обслуживания падала примерно в 100 раз). Решилось-то просто (не оставлять такие хвостики), но вот внятного объяснения нет. Это проявлялось и в случае ненагруженного сервера. Потому что если это алгоритм Нагла, то а) в ненагруженной ситуации порог кэширования для него должен быть порядка сотен байт (т.е. и со 128-байт куском должна быть такая же задержка, а тут только < 40); б) тормоза-то не должно быть, ибо ответ о доставке должен быстро приходить (клиент интенсивно читает). |
Автор: | Ihor [ Четверг, 03 Декабрь, 2009 13:16 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Ответа о доставки прикладное ПО не получает, стек сразу рапортирует что все ок, ТСР не гарантирует доставку. Данные попадают в "окно" и там лежать пока стек не соизволит отправить. Команда push не поможет, она другим занята. Если в момент передачи выдернуть шнур то вы потеряете забуфиризированные данные, даже потеряете если окно выставите в 0, и не узнаете что доставлено а что потеряно, только обратная связь помогает выяснить ситуацию. Примечание, под стеком я имею ввиду реализацию протокола. Алгоритм Нагля наоборот, собирает мелкие данные и отправляет их минимальным ТСР пакетом, что бы не слать по одному байту: Код: if there is new data to send if the window size >= MSS and available data is >= MSS send complete MSS segment now else if there is unconfirmed data still in the pipe enqueue data in the buffer until an acknowledge is received else send data immediately end if end if end if Вот ваш пункт 2 и демонстрирует работу Алгоритма Нагля. http://www.stuartcheshire.org/papers/NagleDelayedAck/ Под нагрузкой увеличивается число коллизий/задержек и большие пакеты приходится снова отсылать, что в свою очередь увеличивает нагрузку ![]() Разбиение на мелкие пакеты позволяет минимизировать повторные отсылки но в свою очередь увеличиваются затраты на опроси. Тут главное найти баланс. |
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 14:11 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Спасибо, в общем, понятно! А под ответом о доставке я имел в виду подтверждение прохождения предыдущих TCP-пакетов, после чего "Нагл" должен посылать новый сразу, забивая на ожидание (по третьей ветке вышеприведённого алгоритма). |
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 14:13 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Вообще, опять ощущение чрезмерной умности нижележащих "чёрных ящиков". И проблем, огребаемых от этого (в виде непредсказуемости поведения). В данном случае, конечно, логика понятна (априори считать программиста идиотом и невзирая ни на что не позволить ему загаживать сеть). Т.е. защита ресурса коллективного пользования от потенциального идиота-вредителя ![]() |
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 14:21 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Да, но в итоге не могу найти информацию: какой размер порций (с т.з. вызова send) можно считать малым, а какой - уже нормальным? Вот реально в вопросе (1) сервер ещё более шустреет, если бить на порции 128; но такой размер уже кажется опасным с т.з. нарывания на того же Нагла. |
Автор: | Ihor [ Четверг, 03 Декабрь, 2009 14:40 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Нагла можно отключить, но надо всегда смотреть на реализацию протокола, можно нарваться на нюансы... Минимальной/оптимальной порции нет. Не забывайте о времени "жизни", о автоматическом разбиение в зависимости от канала передачи. Для определения оптимальных параметров надо привлекать теорию вероятности и анализировать канал в реальном времени... Ещё, в протоколе TCP есть дефект, он и позволяет злоумышленнику выводить систему из рабочего состояния... |
Автор: | Сергей Губанов [ Четверг, 03 Декабрь, 2009 14:43 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Илья Ермаков писал(а): какой размер порций (с т.з. вызова send) можно считать малым, а какой - уже нормальным? Это зависит не от отправителя (не только от него), а в значительной степени от получателя. Если получатель мерзавец и вычитывает из сокета не всё что в нём есть на данный момент, а мелкими порциями выщипывает, то и отправителю тоже придётся посылать мелкими порциями - больше в буфер получателя не влезет пока тот его не соизволит опустошить. По умолчанию размер сокетного буфера равен 128Кб. В современных виндусах размер сокетного буфера можно выставлять самостоятельно, хоть на 10Мб, в линуксах - нельзя.Короче, правильный алгоритм работы: 1) для получателя - как можно быстрее ("со скоростью света") вычитывать из сокета все что там есть и складывать уже в свой "безразмерный" буфер для дальнейшей неспешной обработки. 2) для отправителя - засовывать в socket.Send всё что только есть, а она уже сама разберётся что к чему. 3) Если работаете под виндами (линуксы - в пролёте), то выставить размер сокетного буфера побольше (несколько мегабайтов, но это уже от задачи зависит). Кстати, в Блэкбоксе в CommTCP используются "старые" сокеты, там размер буфера не конфигурируется, надо бы переписать на "новые"... |
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 15:14 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Фишка в том, что мы кроссплатформенно - и под Виндами, и под Линухами. Именно поэтому хочется чего-то средне-хорошего ![]() Над CommStreams ещё слои абстракций есть - и хочется маневрировать политикой записи именно на них, считая, что ниже только этот тупой WriteBytes и больше ничего... |
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 15:17 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Сергей Губанов писал(а): 1) для получателя - как можно быстрее ("со скоростью света") вычитывать из сокета все что там есть и складывать уже в свой "безразмерный" буфер для дальнейшей неспешной обработки. 2) для отправителя - засовывать в socket.Send всё что только есть, а она уже сама разберётся что к чему. Про 1) - ясное дело. А вот про 2) - испытания-то показывают, что лучше не сильно большими кусками. Порциями в 1024 уже замедляет (при сотнях-тысячах запросов в секунду). |
Автор: | Valery Solovey [ Четверг, 03 Декабрь, 2009 15:25 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Илья Ермаков писал(а): Фишка в том, что мы кроссплатформенно - и под Виндами, и под Линухами. Именно поэтому хочется чего-то средне-хорошего ![]() Над CommStreams ещё слои абстракций есть - и хочется маневрировать политикой записи именно на них, считая, что ниже только этот тупой WriteBytes и больше ничего... Сокеты - платформозависимая вещь. Запихнуть Send в подсистему Host. Пусть он и разбирается куда какими порциями. |
Автор: | Ihor [ Четверг, 03 Декабрь, 2009 15:38 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
В тему, протокол TCP не гарантирует достоверность доставленных данных. |
Автор: | Сергей Губанов [ Четверг, 03 Декабрь, 2009 15:54 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Илья Ермаков писал(а): А вот про 2) - испытания-то показывают, что лучше не сильно большими кусками. Порциями в 1024 уже замедляет (при сотнях-тысячах запросов в секунду). Замедляется Блэкбоксовская реализация? Это не удивительно. Блэкбоксовская реализация осуществляя чтение опрашивает сокет периодически (вроде один раз в 50 миллисекунд), а не непрерывно. Быстро вычитывать = вычитывать непрерывно. То есть если хотите получить высокую скорость, то первое что надо сделать - выбросить блэкбоксовскую реализацию и написать свою. Оптимальная по скорости работы реализация такова: Сокет надо сделать блокирующим. Надо создать два потока. Один на чтение, другой на запись. Читающий поток (его приоритет можно поднять до максимального) постоянно спит в функции socket.Receive. Как только в сокет поступили новые данные этот поток (обладающий высоким приоритетом) тотчас же (в туже самую "наносекунду") будится операционкой, вычитывает данные из сокетного буфера, кладёт их в "безразмерный" приёмный буфер приложения и сразу же возвращается в спячку внутри socket.Receive. Вот это и есть вычитывание "со скоростью света" -- надо чтобы приёмный сокетный буфер всё время был пустым. Записывающий поток берёт данные из "безразмерного" отправительного буфера приложения и засовывает их в socket.Send большими порциями - сколько есть. Но слишком часто ему это делать не обязательно и даже вредно. Иногда нужно немного поспать. Если мы сказали функции Send послать много, а она послала мало, значит на приёмной стороне в приёмном сокетном буфере закончилось место, следовательно надо дать время принимающей стороне успеть его опустошить - немножко спим прежде чем вызвать socket.Send в следующий раз. |
Автор: | Ihor [ Четверг, 03 Декабрь, 2009 15:59 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Когда сеть перегружена эта стратегия как мертвому припарка. Я уже писал почему. Про физику нельзя забывать. |
Автор: | Сергей Губанов [ Четверг, 03 Декабрь, 2009 16:02 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Когда сеть перегружена -- это форсмажор. В этом случае пусть заитересованные лица прокладывают "провода потолще". |
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 16:08 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Сергей Губанов писал(а): Замедляется Блэкбоксовская реализация? Это не удивительно. Блэкбоксовская реализация осуществляя чтение опрашивает сокет периодически (вроде один раз в 50 миллисекунд), а не непрерывно. Быстро вычитывать = вычитывать непрерывно. То есть если хотите получить высокую скорость, то первое что надо сделать - выбросить блэкбоксовскую реализацию и написать свою. Оптимальная по скорости работы реализация такова: Сокет надо сделать блокирующим. Ну, Сергей, я же не столь наивен, чтобы использовать Action, графический режим и т.п. ![]() Диспетчеризация задач совершенно другая. На производительность в целом тоже жаловаться грех - уровень Апача (+/- по ситуации) достигается. Просто можно теперь поискать и более мелкие тормоза, потому что раньше в детали работы сокетов не углублялись. Касательно блокирующего режима - это как раз анахронизм, ибо это требует многопоточности уровня ОС, а многопоточность уровня ОС - это тормоза по определению ![]() |
Автор: | Сергей Губанов [ Четверг, 03 Декабрь, 2009 16:23 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
> а многопоточность уровня ОС - это тормоза по определению Во-первых, не по определению... Во-вторых, по сравнению с сокетными тормозами какие-то там тормоза переключения потоков просто стремятся к нулю. И быстрее опустошать приёмный сокетный буфер чем с блокирующим socket.Receive вы не сделаете. Если всё же сделаете, то сообщите пожалуйста, я буду потрясён. |
Автор: | Сергей Губанов [ Четверг, 03 Декабрь, 2009 16:29 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Илья Ермаков писал(а): И проблемы с программированием. Так те потоки не будут объекты создавать, они просто будут копировать байты из одного буфера в другой. То есть стеки тех потоков сборщиком мусора окучивать не надо.
|
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 16:42 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Да, Сергей, а это мысль. Она у меня крутилась как-то, потом как-то не до этого было... Однако и на неблокирующих сокетах приличная скорость выжимается. |
Автор: | Сергей Губанов [ Четверг, 03 Декабрь, 2009 16:49 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
Илья Ермаков писал(а): Порциями в 1024 уже замедляет Размер Ethernet пакета от 72 до 1526 байт. Если работа замедляется при посылке 1024 байт, то с большой вероятностью дело всё же в принимающей стороне - сделайте так чтобы она принимала быстрее.
|
Автор: | Илья Ермаков [ Четверг, 03 Декабрь, 2009 16:50 ] |
Заголовок сообщения: | Re: Особенности работы TCP-сокетов |
И меня пока больше заботил режим "отдающего сервера", т.е. много данных отдаётся, а запросы принимаются маленькие (и большое количество). Так что скорость чтения не очень важна, а вот лёгкая диспетчеризация производительности прибавляет. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |