Настройка Netty на 32 ядра / 10 Гбит Хосты - PullRequest
4 голосов
/ 29 марта 2012

Netty Server отправляет потоки на Netty-клиент (точка-точка, от 1 до 1):

Хорошо

  • case: оба сервера и клиента 12 cores, 1Gbit NIC=> с постоянной скоростью 300K 200 байтовых сообщений в секунду

Не очень хорошо

  • case: сервер и клиент оба 32 cores, 10Gbit NIC => (тот же код), начиная со скорости 130 К / с, снижаясь до сотен в секунду в течение минут

Наблюдения

  • Netperf показывает, что «плохая» среда на самом делевполне превосходно (может передавать 600 МБ / с в течение получаса).

  • Это не похоже на проблему с клиентом, так как, если я переключу клиента на , известно хороший клиент (написал его на C), который устанавливает максимум ОС SO_RCVBUF и ничего не делает, но читает байты [] и игнорирует их => поведение остается тем же.

  • Ухудшение производительности начинается до того, как достигнут высокий уровень записи водяного знака (200 МБ, но пробовал другие)

  • Куча ощущается qкак ни странно, и, конечно, как только он достигнет максимума, GC начинает блокировать мир, но это происходит после появления «плохих» симптомов.В «хорошей» среде куча остается стабильной где-то на 1 Гб, где она логически, учитывая конфиги, должна быть.

  • Одна вещь, которую я заметил: большинство из 32 ядериспользуются в то время как потоки Netty Server, которые я пытался ограничить, установив все потоки Boss / NioWorker на 1 (хотя в любом случае есть один канал, но на всякий случай):

val bootstrap = new ServerBootstrap(
  new NioServerSocketChannelFactory (
    Executors.newFixedThreadPool( 1 ),
    Executors.newFixedThreadPool( 1 ), 1 ) )

// 1 thread max, memory limitation: 1GB by channel, 2GB global, 100ms of timeout for an inactive thread
val pipelineExecutor = new OrderedMemoryAwareThreadPoolExecutor(
                1, 1 *1024 *1024 *1024, 2 *1024 *1024 *1024, 100, TimeUnit.MILLISECONDS,
  Executors.defaultThreadFactory() )

bootstrap.setPipelineFactory(
  new ChannelPipelineFactory {
    def getPipeline = {
      val pipeline = Channels.pipeline( serverHandlers.toArray : _* )
      pipeline.addFirst( "pipelineExecutor", new ExecutionHandler( pipelineExecutor ) )
      pipeline
    }
} )

Но это не ограничивает количество используемых ядер => все же большинство ядер используется.Я понимаю, что Netty пытается округлить рабочие задачи робина, но есть подозрение, что 32 ядра "сразу" могут быть слишком сложными для NIC.

Вопрос (ы)

  1. Предложения по снижению производительности?
  2. Как ограничить количество ядер, используемых Netty (конечно, без прохождения маршрута OIO)?

примечания:Я бы хотел обсудить это в списке рассылки Нетти, но он закрыт.попробовал IRC Нетти, но он мертв

1 Ответ

2 голосов
/ 22 мая 2014

вы пробовали привязку к процессору / прерыванию? Идея состоит в том, чтобы отправлять прерывания io / irq только в 1 или 2 ядра и предотвращать переключение контекста в других ядрах. дайте это хорошо. попробуйте vmstat и монитор ctx и обратный контекст переключается до и после. Вы можете открепить приложение от ядра (ов) обработчика прерываний.

...