Сравнение Akka Actors pipToSelf и Future в системах с высокой пропускной способностью и низкой задержкой

У меня вопрос по поводу pipeToSelf vs Futures. Предположим, у нас есть серверное приложение Scala, которое работает на машине Google Cloud типа n2d-standard-16 с 16 ядрами, где на каждом узле размещается один модуль приложения.

Детали кластера:

  1. обслуживает 200 тыс. RPS с внутренним временем обработки 1 мс на p95.
  2. используя конфигурации akka с диспетчером по умолчанию, используя fork-join-executor с 16 потоками, обслуживающими весь трафик.
  3. Каждый HTTP-запрос направляется группе из 30 субъектов без сохранения состояния, некоторые из которых выполняют блокирующие операции, а другие выполняют неблокирующие операции, включающие запросы к распределенному кешу. Кроме того, 16 дополнительных потоков обрабатывают операции чтения для этого распределенного кеша, что составляет всего 32 потока.
  4. Каждая неблокирующая операция использует context.pipeToSelf для извлечения данных из распределенного кеша, а затем позволяет актеру вернуть результат отправителю.

Вопрос:

В такой системе с высокой пропускной способностью и низкой задержкой есть ли какие-либо накладные расходы при использовании context.pipeToSelf(readFromCache) вместо использования возможностей Future монад? например

readFromCache.map { reply => ...  }.recover { case NonFatal(ex) => ... }

С context.executionContext исполнителем. Мои опасения:

  1. Доступен ли контрольный показатель в отношении количества дополнительных усилий, необходимых для вставки сообщения в почтовый ящик и последующего его извлечения? Кроме того, можно ли получить ссылку на конкретный класс, который расширяет свойство ActorRef и реализует метод tell?

  2. Время внутренней обработки не увеличивается? Если мы обработаем первое сообщение, а затем отправим результат обратно себе, возможно, почтовый ящик уже содержит другие сообщения, что может привести к увеличению задержки из-за природы почтового ящика FIFO. Эти сообщения могут быть из другого HTTP-запроса. with Future map и recover встречаются в одном и том же потоке и возвращают ответ перед обработкой других сообщений.

  3. Из-за конфигурации по умолчанию пропускной способности = 5 возможно, что все доступные потоки в настоящее время используются. Если между потоками возникает контекст выполнения, когда необходимо вернуть ответ из распределенного кеша из-за дополнительного сообщения в почтовом ящике от pipeToSelf, может возникнуть задержка в ожидании доступности другого потока.

Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
0
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
Есть ли какие-либо накладные расходы при использовании context.pipeToSelf(readFromCache) вместо использования возможностей монад Future?

Абсолютно больше накладных расходов. Актеры делают намного больше, чем просто обрабатывают асинхронную обработку.

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

Обновлено: Кроме того, чтобы быть ясным, мое понимание вопроса было «должен ли я использовать актеров или использовать фьючерсы на основе монад». Не «должен ли я использовать pipeToSelf с актером или фьючерсом». Вы (обычно) не можете просто использовать Future внутри Актера напрямую по причинам, объясненным в pipeToSelf.

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

Я сильно сомневаюсь, что для этой конкретной метрики существуют ориентиры. По своей сути почтовый ящик — это просто очередь. Реализация этой очереди может немного отличаться в зависимости от конфигурации вашего субъекта, но это все равно очередь и, вероятно, очень простая. Операции "голова/хвост" в очередях выполняются абсурдно быстро. Опять же, я не претендую на то, что у Актеров вообще нет накладных расходов, но операции с почтовыми ящиками меня никогда не касались.

Я не хочу быть пренебрежительным. 200 тысяч запросов в секунду при 1 мс — это серьезно. По сути, вам придется все тестировать и измерять. Но время постановки/удаления из очереди меня не сильно беспокоит.

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

Время внутренней обработки не увеличивается? Если мы обработаем первое сообщение, а затем отправим результат обратно себе, возможно, почтовый ящик уже содержит другие сообщения, что может привести к увеличению задержки из-за природы почтового ящика FIFO. Эти сообщения могут быть из другого HTTP-запроса. с Future сопоставление и восстановление происходят в одном потоке и возвращают ответ перед обработкой других сообщений.

Теоретически да. На самом деле это не проблема, если только вы не запутались и не блокируете операции в неблокирующем диспетчере.

Конечно, без тестирования невозможно узнать, особенно при скорости 200 000 000 в секунду. Но реальность большинства сценариев реального мира такова, что вы либо справляетесь с нагрузкой, либо не справляетесь с нагрузкой. Если вы не отстаете от нагрузки, средний размер неблокирующего почтового ящика будет близок к нулю. Определенно есть исключения, особенно в отношении блокировки почтовых ящиков, но есть люди, которых я знаю, которые запускают системы реального времени на Akka; Задержка в 1 мс достижима.

Другой способ думать об этом состоит в том, что реальные накладные расходы и задержка связаны с переключением контекста на поток. Даже в том маловероятном случае, если ваш почтовый ящик стал «длинным» (скажем, несколько десятков), обработка всех писем не займет много времени. Задержка ожидания запланирована, а не обработки почтового ящика. Что приводит к вашему следующему вопросу.

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

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

Это определенно то, на что вы должны обратить внимание, если вам нужна задержка менее 1 мс. Но, с другой стороны, реальность такова, что у вас всего 16 ядер. Таким образом, если бы у вас было в два раза больше объявлений, вам было бы легче получить поток, но дополнительные потоки были бы бесполезны, потому что им было бы трудно бороться за физическое время процессора. На самом деле почтовые ящики могут помочь вам в этом, потому что пакетная обработка уменьшит переключение контекста.

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

Другие вопросы по теме