NATS масштабируется горизонтально (пропускная способность)
Мы используем NATS и используем кластеризацию из 3+ узлов. У нас есть несколько производителей и много потребителей. Размеры сообщений небольшие ( ~100 байт), однако наша пропускная способность несколько высока. ~40k/ сек. Весь трафик проходит по внутренним сетям 2x10 Гбит / с.
Мне было любопытно, если увеличение кластера с большим количеством узлов поможет пропускной способности кластера. У нас есть небольшая задержка, которая, кажется, немного увеличивается при записи большего количества сообщений в секунду.
В качестве вторичного замечания, есть ли какие-нибудь советы / хитрости, которые можно сделать для повышения пропускной способности? В настоящее время мы используем protobufs, но есть ли какие-то настройки сервера, которые можно сделать?
1 ответ
На пропускную способность может повлиять наличие множества соответствующих подписок на данную тему.
Например, предположим, что вы используете 1 соединение и публикуете foo
, Есть 100 подписок на foo
, Когда сервер получает сообщение, он доставляет его всем соответствующим подпискам. В этом случае это означает, что TCP отправляет это сообщение 100 раз, независимо от того, принадлежат ли подписки одному и тому же соединению или нет.
При выполнении отправки подписчикам сервер не читает другие сообщения, опубликованные этим подключением.
Горизонтальное масштабирование путем добавления серверов может помочь, если вы также распределите нагрузку по подпискам в кластере. В приведенном выше примере, скажем, что 50 потребителей находятся на одном сервере, 50 - на другом, тогда сервер, получающий опубликованное сообщение, теперь должен будет отправить это сообщение только 50+1 раз (50 для своих локальных подписчиков, 1 для маршрута). Затем другой сервер отправит 50 сообщений своим локальным подписчикам.
Но простое добавление серверов не улучшит пропускную способность единственного соединения, если была одна (или нет) соответствующая подписка.
Еще один способ улучшить пропускную способность паба - использовать больше соединений. Поскольку сервер использует подпрограмму go для каждого соединения (для чтения данных из сокета, а затем для отправки подпискам), некоторые работы можно распараллелить.
Я мог бы запустить тест, включенный в репо, чтобы получить верхний предел, который вы можете получить на своей машине. Например, стендовые тесты сервера обычно записывают данные непосредственно в сокет, а не с помощью клиента NATS. Это необходимо для измерения производительности сервера без каких-либо ограничений, налагаемых реализацией клиента:
go test -v -run=xxx -bench=. ./test
Обязательно посмотрите, как вы отправляете сообщения и как они обрабатываются в обратных вызовах подписок. Все, что вы можете сделать для улучшения производительности, будет иметь большую ценность.
Надеюсь это поможет.