LINUX.ORG.RU

Одновременная запись в несколько сокетов


2

3

Суть задачи: RedHat Linux MRG Realtime Есть структура, содержащая (условно) список сокетов, в которые надо писать одинаковые данные (мультиплексирование). Сокетов достаточно много - сотни и единицы тысяч.

Операции записи должны быть асинхронными, при этом потокобезопасными. Высокие требования к латентности (распространение рыночных данных).

На какие низкоуровневые средства предложите посмотреть и какие высокоуровневые реализации посоветуете посмотреть?

Спасибо заранее.

Ответ на: комментарий от anonymous

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

По условию задачи дан RHEL MRG. Под него есть нетграф?

tailgunner ★★★★★
()
Ответ на: комментарий от ae1234

насчет зеро-копи - еще раз - этот термин употребляеться когда обьем информации передают из сокета в сокет без задействования юзерспейса

а у вас список сокетов и так лежит в юзерспейсе - и ядерный модуль иль еще кто и так имеет до него доступ

Списки сокетов меняются относительно редко, могу это сделать посредством mmap() и в этот системный вызов (для собственного ядерного модуля) передавать индекс в таблице сокетов

при поступление задания - очень очень быстро оно начало раздаваться по клиентам ? с минимальной задержкой ?

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

не буферы передачи приняли - у вас сетевая сразу с сисколе уже пашлет пакет

и куда вы будете девать скажем 25мбайтный поток - когда до клиентов у вас только 10 мегобайт в секунду ?

Клиентскому сокету выделяется, скажем, 2 мегабайта, ставится high watermark for send и если его не хватило, сокет дропается, таковы суровые реалии. Клиент или обеспечивает нормальный канал, или подписывается на адекватный объем данных. Считаем, что по условиям задачи исходящей пропускной способности сети достаточно, иначе нефиг заниматься таким бизнесом :)

westtrd
() автор топика
Ответ на: комментарий от tailgunner

И что? Свет клином сошелся на красной шапке? Тем более, что реальную обработку данных скорее всего на ней и придется делать и ksocket'ом к ней присоединяться. (Благо опять копирование будет исключительно в ядре, без юзерспейса). Эта хрень ведь под рутом запускается и походу модули ядра подгружает. И еще раз - коммерческий порт нетграфа под линукс существует.

anonymous
()
Ответ на: комментарий от ae1234

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

this will be shown in top as hardware interrupts or smth like that. sorry for english, I'm setting up my fresh ubuntu...

true_admin ★★★★★
()
Ответ на: комментарий от anonymous

По условию задачи дан RHEL MRG. Под него есть нетграф?

И что?

Видимо, это означает «netgraph для RHEL MRG нет».

Свет клином сошелся на красной шапке?

Я не знаю, ты тоже. Возможно, именно RHEL MRG указана в ТЗ; возможно, нужно именно RT, которого нет ни в одной BSD.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Жесткой завязки нет, но речь идет о серьезном приложении, требования к устойчивости которого весьма жесткие.

Идти в этот проект без коммерческой поддержки со стороны коммерческого дистрибутива я бы не стал.

Отсутствие же функционала RT приведет к броскам латентности, что неприемлемо изначально, готовы получить чуть более худшее среднее, но с минимальной девиацией.

westtrd
() автор топика
Ответ на: комментарий от tailgunner

Обрати внимание, что самые частые слова в твоем посте были «возможно» и «видимо». ТС это решение заинтересовало, сейчас он просто выбирает то, что покажется ему наилучшим. И да, mea culpa, и твои аргументы не совсем были техническими, да и мои ответы.

anonymous
()
Ответ на: комментарий от anonymous

Обрати внимание, что самые частые слова в твоем посте были «возможно» и «видимо».

Второе «видимо» оказалось правильным.

tailgunner ★★★★★
()
Ответ на: комментарий от westtrd

Какая-то поддержка RT во фряхе есть, но только для рута. (Хотя не буду кривляться, сам с этим не работал). Самое главное, что есть, существующие модули и решения, проверенные временем.

anonymous
()
Ответ на: комментарий от westtrd

да нет же - пойми о чем я

буферы тут непричем

если у вас на ВСЕХ юзеров 100мбит - а вы будете выдавать со скоростью под гигабит (ну иль скажем 250мбит) - то пакеты будут тупо теряться и это не изза тормазных юзеров - а изза тормазного общего вашего соединения с провайдером потери конечно tcp востановит - но ретрансмиты будут очень и очень немелкие - и это будут не еденичные юзеры - а очень и очень приличное колво

дальше то что вы добиваетесь - чтобы данные начали раздаваться как можно быстрее обьесняю - сисколы делаються больше чем по мильону в секунду - пакет ядро отсылает максимально быстро около 150тон в секунду когда на систему приходит пакет с заданием на рассылку - драйвер ее подхватывает принимает и ядро записывает в буффер приема сокета - след вызов епола / чтение - за натуральные 2 микросекунды - вытянет это задание в юзерспейс после чего оно начент рассылать пакеты по юзерам с частотой 6 микросекунда за пакет

и из этого всего - подумай - что ты собираешся оптимизировать бесконечным циклом ? вот эту 1 микросекунду из 7 тысяч микросекунд при рассылке на тысячу юзеров ?

ae1234 ★★
()
Ответ на: комментарий от anonymous

я просил ядерный модуль - и его уж нашли и уже затестили - и заодно выяснили почему это не нашло особого распространения - потому что выйгрыш отсилы 15%

вы влезли в разговор - сказали неграф - сказали это типа круто - и ни цифр ничего ? цифры - простые цифры сервера - к которому подключено 1000 юзеров по tcp - и на юзеров разослать одно сообщение
и за сколько времени оно сделает эту рассылку

ae1234 ★★
()
Ответ на: комментарий от ae1234

вы влезли в разговор

Нет, это решение я предлагал и раньше.

к которому подключено 1000 юзеров по tcp

Для тестирования у меня столько клиентов нет, увы. Сила нетграфа не только в производительности (хотя и это не отнять), а в гибкости и технологичности (это прежде всего!). Функциональность добавляется и расширяется легко и непринужденно.

anonymous
()
Ответ на: комментарий от anonymous

клиентов столктьо и ненужно - нужно просто 2 машины соединенных гигабитом
на одном запускается сервер tcp - который скажем раз в секунду на всех подключенных юзеров отсылает 128 байт
а на второй машине делает эмуляция клиентов - ab -c 1000 -n 1000 http://сервер:1000/index.html
и пускай сервер замеряет и печает - за сколько времени он разослал сообщение (само собой от первого до последнего - а не какаято постановка в очередь всего задания)

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

ae1234 ★★
()
Ответ на: комментарий от ae1234

Не, такая эмуляция - это не то. Там ядро хитрит. Поэтому и профит от того модуля маленький. Я хоть и простой быдлокодер, но быть похожим на фороникс не хочу.

anonymous
()
Ответ на: комментарий от ae1234

Тьфу на меня)). Для четкого экперимента нужно синхронизировать время на машинах, отметить время начала отсылки сообщения с сервера, и время приема каждым клиентом. Наибольшее время клиента и будет временем отсылки сообщения. Так что 2 машины не прокатят.

anonymous
()
Ответ на: комментарий от anonymous

незнаю как на бсд - на линуксе оно могет хитрить (насколько знаю) только при заюзывание Nagle алгоритма - когда отправка откладывается в надежде получить еще данные и отправить большим пакетом в линуксе оно отключается TCP_NODELAY флагом у сокета

ae1234 ★★
()
Ответ на: комментарий от ae1234

за сколько времени он разослал сообщение (само собой от первого до последнего - а не какаято постановка в очередь всего задания)

Еще раз уточню, чтобы не было недопониманий в части постановки тестов. Меня интересует не доставка клиенту, не уход даже с сетевой карточки, а ИМЕННО окончание (успешное) записи в клиентский сокет (для всех клиентов).

Еще раз подчеркну - клиент, не справившийся с нагрузкой, УБИВАЕТСЯ. Се ля ви. Клиент должен или иметь канал достаточной толщины или брать столько данных, сколько он может переварить. Объем данных регулируется клиентом через объем подписок.

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

Спасибо большое за внимание к проблеме, сам по факту сбора стенда постараюсь сделать постановочные тесты, о результатах доложусь :)

westtrd
() автор топика
Ответ на: комментарий от ae1234

кстати мысля еще
те 6микросекунд что отсылает ядро пакет - что если в нем - весьма приличный кусок занимает общение с сетевой и передача ей задания на отсылку
что если - запретить передачу - потом залить в буфер 1000пакетов - и после этого разрешить передачу
возможно что ядро - видя столько подготовленных пакетов на передачу - сразу передаст их через драйвер на сетевую - и накладных расходов на общение с сетевой будет значительно меньше

ae1234 ★★
()
Ответ на: комментарий от westtrd

а что будет если из 1000пакетов мгновенно отосланных - 750 просто сразу потеряються на следующем хосте у вас ? неужели это всеравно ? :)

ae1234 ★★
()
Ответ на: комментарий от anonymous

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

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

Я, если нужны точные замеры, пользую или CLOCK_MONOTONIC или constant_tsc, ибо даже простой счетчик процессорных тиков на такой точности уже начинает врать, и существенно.

А кардинальное решение проблемы синхронизации в локальной сети - карты, поддерживающие РТР, в промышленном варианте возможна синхронизация с дискретностью порядка 200 наносекунд.

westtrd
() автор топика
Ответ на: комментарий от ae1234

Не катит.

В данной предметной области неприемлемо ожидание следующих пакетов, котировка с рынка должна быть немедленно доставлена клиента, это специфика финансового рынка.

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

westtrd
() автор топика
Ответ на: комментарий от ae1234

а что будет если из 1000пакетов мгновенно отосланных - 750 просто сразу потеряються на следующем хосте у вас ? неужели это всеравно ? :)

Это проблема буферов TCP, сетевого оборудования, клиента наконец, но вовсе не моя :) До провайдера стоит сеть достаточного качества, чтобы оно не исчезало как пыль, а уж дальше - как Бог пошлет, я не собираюсь и не могу управлять неуправляемым :)

westtrd
() автор топика
Ответ на: комментарий от westtrd

ну - вот обычьная отправка это 6микросекунд на пакет - а если скажем через tc - show / manipulate traffic control settings засунуть отсылку пакетов в класс с 0левой скоростью - сделать буффер в >1000 пакетов - и write сделать на каждый сокет - при этом пакеты будут накапливаться в буффере - и есть надежда что сискол будет 1микросекундным - и загонит все 1000 пакетов за 1000микросекунд после чего - разблокировать скорость - и пакеты попрут (наверно) на фулл гигабите по 1.3 микросекунды на 128байтный пакет и общее время отсылки будет не 7000 а 2300 микросекунд (ну и да - 1000микросекунд будет ожидание)

--------- почемуже это неуправляемое - если известно что до провайдера 100мбит - то отсылать на него 200 мегабит пакетов и надеяться на высшие силы с лице буфферов устройств - имхо както нетак

ae1234 ★★
()
Ответ на: комментарий от ae1234

при этом пакеты будут накапливаться в буффере

не самый желательный вариант

почемуже это неуправляемое

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

Самое смешное заключается в том, что ДОСТАВКА внутри гигабитной сети в приложении, сделанном на дот-оффтопик с момента попадания пакета в буфер данного сервера показывает среднее порядка 2 миллисекунд. Что не устраивает в данном решении - отвратительная девиация. Потому и принято решение ухода с оффтопика.

westtrd
() автор топика
Ответ на: комментарий от ae1234

Миллисекунд.

Это не я - я как раз в том решении не участвовал. За что купил, за то и продаю :)

westtrd
() автор топика
Ответ на: комментарий от ae1234

Вчера общался с человеком из Штатов, работающим в реалтайм солюшнах

Он мне выдал довольно таки интересные рекомендации: http://www.openonload.org/

Но там надо модифицировать код драйвера под свой NIC.

Что это дает - работа с NIC из userspace минуя kernel со всеми вытекающими, включая уход от проблемы переключения контекстов.

westtrd
() автор топика
Ответ на: комментарий от westtrd

и что - эмулировать всю работу с tcp в юзерспейсе ? а смысл ? ядро ОЧЕНЬ хорошо работает с tcp - тут и сомневаться то бесмысленно

был бы udp - смысл был бы

ae1234 ★★
()
Ответ на: комментарий от westtrd

ксеон 2.4 выдает 250 мегабит если поставите типа i7 на 4.5 ггрц - будет выдавать 500 мегабит из гигабита

вы уверены что это вам мало ?

ae1234 ★★
()
Ответ на: комментарий от westtrd

уж незнаю какие 12 - у меня было 6-7 :)

если там говориться о 4.2 микросекунд - это хардваре причем на том же железе - 2.4ггрц ксеон - то то что у меня получилось 6-7 микросекунд - это крайне хорошо уж чтобы не было - но 2-3 микросекнуд на обработку всех tcp премудростей - всяко не жалко

ae1234 ★★
()
Ответ на: комментарий от westtrd

и если не заметили - там все тесты на udp
у вас же tcp - и я тестил tcp
с udp все конечно просто - там логики в обработке и нет совсем - это вам не tcp

ae1234 ★★
()
Ответ на: комментарий от ae1234

Кстати, в openonload свой стек протоколов :) Единственно, надо фрагменты драйвера корректировать, что совсем муторно :)

Дождусь тестового стенда, начну тестить разные варианты )

Результатами поделюсь :)

westtrd
() автор топика
Ответ на: комментарий от ae1234

Вот потому и фрагмент дров надо переписывать под ту карту с которой будете работать.

Архитектура же openonload не меняется для этого, она включает дрова + стек в юзерспейсе.

westtrd
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.