Поддержка Netty Adaptive UDP Multicast

Новички, у которых возникают проблемы с обработкой видеопотока UDP с помощью Netty 3.2.4. На разных машинах мы видим отброшенные байты и т. д., используя Netty. У нас есть небольшой счетчик после того, как Netty получает байты, чтобы увидеть, сколько байтов получено. Дисперсия больше, чем то, что можно было бы объяснить ненадежностью UDP. В нашем случае мы также сохраняем байты в файл для воспроизведения видео. Воспроизведение видео в VLC действительно иллюстрирует пропущенные байты. (Размер отправляемых пакетов составлял около 1000 байт).

Вопросы

  • Верны ли наши предположения о Netty API с точки зрения невозможности использования AdaptiveReceiveBufferSizePredictor для прослушивателя потока UDP?
  • Есть ли лучшее объяснение поведения, которое мы наблюдаем?
  • Есть ли лучшее решение? Есть ли способ использовать адаптивный предиктор с UDP?

Что мы пробовали

...
DatagramChannelFactory datagramChannelFactory = new OioDatagramChannelFactory(
                                                Executors.newCachedThreadPool());
connectionlessBootstrap = new ConnectionlessBootstrap(datagramChannelFactory);
...
datagramChannel = (DatagramChannel) connectionlessBootstrap.bind(new 
                  InetSocketAddress(multicastPort));
datagramChannel.getConfig().setReceiveBufferSizePredictor(new   
                FixedReceiveBufferSizePredictor(2*1024*1024));
...
  • Судя по документации и поиску в Google, я думаю, что правильный способ сделать это — использовать OioDatagramChannelFactory вместо NioDatagramChannelFactory.

  • Кроме того, хотя я не нашел явного указания, вы можете использовать FixedReceiveBufferSizePredictor только с OioDatagramChannelFactory (по сравнению с AdaptiveReceiveBufferSizePredictor). Мы обнаружили это, просмотрев исходный код и поняв, что метод previousReceiveBufferSize() AdaptiveReceiveBufferSizePredictor не вызывался из класса OioDatagramWorker (в то время как он вызывался из класса NioDatagramWorker).

  • Итак, мы изначально установили FixedReceivedBufferSizePredictor в (2*1024*1024)

Наблюдаемое поведение

  • Работая на разных машинах (разная вычислительная мощность), мы видим, что Netty принимает разное количество байтов. В нашем случае мы передаем потоковое видео через UDP и можем использовать воспроизведение переданных байтов для диагностики качества прочитанных байтов (размеры отправляемых пакетов составляли около 1000 байт).

  • Затем мы поэкспериментировали с разными размерами буфера и обнаружили, что 1024*1024 вроде бы улучшают работу... но на самом деле понятия не имеем, почему.

  • Изучив, как работает FixedReceivedBufferSizePredictor, мы поняли, что он просто создает новый буфер каждый раз, когда приходит пакет. В нашем случае он будет создавать новый буфер размером 2*1024*1024 байта независимо от того, был ли пакет 1000 байт или 3 МБ. Наши пакеты были всего 1000 байт, поэтому мы не думали, что это наша проблема. Может ли какая-либо из этой логики вызывать проблемы с производительностью? Например, создание буфера каждый раз, когда приходит пакет?

Наш обходной путь

Затем мы подумали о том, как сделать размер буфера динамическим, но поняли, что не можем использовать AdaptiveReceiveBufferSizePredictor, как указано выше. Мы экспериментировали и создали свой собственный MyAdaptiveReceiveBufferSizePredictor вместе с сопутствующими классами MyOioDatagramChannelFactory, *Channel, *ChannelFactory, *PipelineSink, *Worker (которые в конечном итоге вызывают MyAdaptiveReceiveBufferSizePredictor). Предсказатель просто изменяет размер буфера, чтобы удвоить размер буфера на основе размера последнего пакета или уменьшить его. Это, казалось, улучшило ситуацию.


person Sam P.    schedule 01.02.2012    source источник


Ответы (1)


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

person Marc-Christian Schulze    schedule 23.04.2012