Следует ли запускать дизель с использованием актора синхронизации, actix_web :: web :: block или futures-cpupool?

Фон

Я работаю над приложением actix-web, использующим дизельное топливо через r2d2, и не знаю, как лучше всего выполнять асинхронные запросы. Я нашел три варианта, которые кажутся разумными, но я не уверен, какой из них лучше.

Возможные решения

Актер синхронизации

Например, я мог бы использовать пример actix, но это довольно сложно и требует справедливая сделка шаблона для построения. Надеюсь, есть более разумное решение.

Actix_web::web::block

В качестве другого варианта я мог бы использовать actix_web::web::block для перенести мои функции запросов в будущее, но я не уверен в последствиях этого для производительности.

Выполняется ли запрос в той же системе Tokio? Из того, что я смог найти в источнике, он создает поток в базовом пуле потоков actix-web. Это проблема?

Если я правильно прочитал код, r2d2 блокирует свой поток при получении соединения, что заблокирует часть основного пула actix-web. То же самое с запросами к базе данных. Тогда это заблокирует весь actix-web, если я сделаю больше запросов, чем у меня есть потоков в этом пуле? Если так, то большая проблема.

Фьючерсы-cpupool

Наконец, безопасный вариант, при котором могут возникнуть ненужные накладные расходы, - это futures-cpupool. Основная проблема заключается в том, что это означает добавление еще одного ящика в мой проект, хотя мне не нравится идея о том, что несколько пулов процессоров без надобности плавают в моем приложении.

Поскольку блокируют и r2d2, и дизель, здесь есть удивительное количество хитрых вещей.

Самое главное, не делитесь этим cpupool с чем-либо, что не использует тот же пул r2d2 (поскольку все созданные потоки могут просто блокировать ожидание соединения r2d2, блокируя весь пул, когда существует работа).

Во-вторых (немного более очевидно), у вас, таким образом, не должно быть больше соединений r2d2, чем потоков в пуле, и наоборот, поскольку более крупный будет тратить ресурсы (неиспользуемые соединения / потоки постоянно блокируются) (возможно, еще один поток, может быть, быстрее передача соединения планировщиком ОС, а не планировщиком cpupool).

Наконец, помните, какую базу данных вы используете и какую производительность у вас есть. Запуск одного соединения r2d2 и одного потока в пуле может быть лучше всего в приложении sqlite с большим объемом записи (хотя я бы порекомендовал для этого подходящую базу данных).

Старые ответы

Старые решения, которые могут работать

https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/

По сути, рекомендует Futures-cpupool.

Каков наилучший подход к инкапсуляции блокировки? I / O in future-rs?

Рекомендует Futures-cpupool для общих случаев.

Старые решения, которые не работают

https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/

Действительно хорошее исправление для старой версии actix-web. Из того, что я могу найти, в запросах больше нет пула процессора.


person logina    schedule 08.11.2019    source источник
comment
Из комментариев в этой проблеме, похоже, что futures-cpupool рекомендуемый обходной путь из-за отсутствия поддержки async в Diesel.   -  person Jmb    schedule 08.11.2019
comment
Это скорее общее решение. Я надеюсь на то, что будет использовать систему actix. Тем не менее, сейчас я покопаюсь в futures-cpupool, чтобы найти проблемы.   -  person logina    schedule 08.11.2019
comment
Добро пожаловать в Stack Overflow! Похоже, на ваш вопрос могут ответить ответы Как лучше всего инкапсулировать блокирующий ввод-вывод в future-rs? . В противном случае отредактируйте свой вопрос, чтобы объяснить различия. В противном случае мы можем отметить этот вопрос как уже полученный.   -  person Shepmaster    schedule 08.11.2019
comment
Поскольку cpupool также взаимодействует с пулом блокирующих соединений в r2d2, я не уверен, как лучше всего решить эту проблему. Я сам сейчас изучаю это и скоро обновлю.   -  person logina    schedule 08.11.2019


Ответы (1)


Я собираюсь с Futures-cpupool. Это лучшее решение из-за блокирующего характера моих взаимодействий.

Использование actix_web :: web :: block достаточно прилично, но будет использовать общий пул потоков в actix (и из-за блокирующих вызовов, которые я использую, это может блокировать весь пул потоков и мешать другим задачам, переданным actix_web).

Лучше использовать futures-cpupool для создания отдельного пула потоков для каждой базы данных только для взаимодействия с базой данных. Таким образом, вы группируете все задачи, которые должны ждать друг друга (когда задач больше, чем подключений), в один пул, не позволяя им блокировать любые другие задачи, которым не требуется подключение, и потенциально ограничивая количество потоков до количество подключений (чтобы задание было запланировано только тогда, когда оно не будет заблокировано).

В случае, когда вы хотите использовать только одно соединение с базой данных (или очень мало), актор синхронизации - довольно хороший вариант. Он будет действовать как Futures-cpupool с одним потоком, гарантируя, что все задачи выполняются по очереди, за исключением того, что он будет использовать один из основных потоков actix-web, а не отдельный (поэтому подходит только для очень небольшого количества подключений) . Я считаю, что шаблон слишком велик, чтобы того стоить.

person logina    schedule 08.11.2019
comment
чтение моих выводов выше - пожалуйста, поместите информацию, имеющую отношение к ответу, в ответ, а не вопрос. - person Shepmaster; 08.11.2019
comment
Какой размер бассейна вы бы порекомендовали? - person Acidic9; 09.05.2021