LINUX.ORG.RU

Как быстро и экономно накапливать сообщения?


0

1

Знаете ли вы какие нибудь стратегии накопления сообщений для Reactor паттерна?

Суть в том, что есть очень много перманентных сокетных соединений и из них вычитываются сообщения, потенциально большие, но в большинстве случаев маленькие. За один read в буфер вычитывается только часть сообщения. После чтения потенциально долго может не приходить его остальное содержание. Лишь когда оно прийдет, то сообщение будет передано дальше для обработки.

Как экономно организовать хранение этих накапливаемых сообщений?

Наивное решение с аллокацией будет дергать собственно аллокатор. И сообщение размером с 1 МБ будет занимать 1 МБ, при том что всего мегабайта пришлось долго ждать, клиент тупил. Лучшее решение, но неидеально, так как хотелось бы достичь максимальной производительности в балансе с экономией.

Возможно второе наивное решение - заготовленые большие блоки. Плохо - блоки фиксированые, но ограниченые.

Чуть хитрее - маленькие блоки в гиганском массиве и как-то их менеджить, хранить сообщения кусками, но тут неясно делает ли кто-то так, будет ли тормозить.

Планирую все выходные читать сорцы Jetty. Естественно буду бенчмаркать и делать прототипы, но вдруг кто-то видел статьи годные.

★★★★★

Последнее исправление: vertexua (всего исправлений: 2)

Я бы использовал буферы привязанные к соединениям. Если таковых не очень много - фиксированные. Если много - фиксированный наиболее вероятный размер + последующая реалокация при превышении

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

Ну. Если это не особенность протокола, то конечно нужно убивать точки по таймауту, и/или по иному критерию, иначе потенциальный DoS

vasily_pupkin ★★★★★
()

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

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

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

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

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

За совет спасибо, мне было важно узнать что кто-то такое успешно использует

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

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

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

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

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

У нити есть список свободных блоков, и есть сколько то списков занятых

Чуть вдоль не сделал не увидев такого очевидного. Мда, надо чаще спать.

vertexua ★★★★★
() автор топика

В grizzly вроде как это хорошо организовано, но исходники этого места внимательно не смотрел.

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

Не понял вопроса.

Я лично на мегавысоких загрузках свой мини-сервер не тестировал, не моя это специализация, но grizzly представляют как высокопроизводительное решение поверх nio в том числе и для этого.

note173 ★★★★★
()

заведи пул direct буферов фиксированного размера. Длинные сообщения объединяй в цепочки, ввод-вывод прямо с цепочками умеет работать

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

direct буферов

хорошее замечание

цепочки

http://docs.oracle.com/javase/6/docs/api/java/io/SequenceInputStream.html ?

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

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

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

vertexua ★★★★★
() автор топика

Гигантской помощью было бы если бы кто-то сказал как сформировать в гугл запрос

vertexua ★★★★★
() автор топика

Насчет аллокатора: почитайте про SLUB из ядра Linux, некоторые концепции (особенно блочное выделение памяти можно взять оттуда).

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