TNonblockingServer, TThreadedServer и TThreadPoolServer, какой из них лучше всего подходит для моего случая?

Наш аналитический сервер написан на C++. Он в основном запрашивает базовый механизм хранения и возвращает довольно большие структурированные данные по бережливости. Обработка типичного запроса занимает от 0,05 до 0,6 секунды в зависимости от размера запроса.

Я заметил, что есть несколько вариантов того, какой сервер Thrift мы можем использовать в коде C++, в частности, TNonblockingServer, TThreadedServer и TThreadPoolServer. Похоже, что TNonblockingServer — это то, что нужно, поскольку он может поддерживать гораздо больше одновременных запросов и по-прежнему использует пул потоков за сценой для выполнения задач. Это также позволяет избежать затрат на создание/разрушение потоков.

Новости Facebook о бережливости: http://www.facebook.com/note.php?note_id=16787213919

Здесь, в Facebook, мы работаем над полностью асинхронным клиентом и сервером для C++. Этот сервер использует ввод-вывод, управляемый событиями, как текущий сервер TNonblockingServer, но его интерфейс с кодом приложения полностью основан на асинхронных обратных вызовах. Это позволит нам создавать серверы, способные обслуживать тысячи одновременных запросов (каждый из которых требует обращения к другим серверам Thrift или Memcache) с использованием всего нескольких потоков.

Связанные сообщения о стеке: Большое количество одновременных подключений в бережливости

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

Просто интересно, есть ли какие-то другие факторы, которые мне здесь не хватает? Как мне решить, какой из них лучше всего соответствует моим потребностям?


person Community    schedule 22.08.2010    source источник
comment
Я наткнулся на этот пост. blog.51cto.com/luckybins/1344189. Мне было ясно.   -  person sivabudh    schedule 22.07.2018


Ответы (2)


Запросы, выполнение которых занимает 50-600 миллисекунд, довольно длинные. Время, необходимое для создания или уничтожения потока, намного меньше, поэтому не позволяйте этому фактору влиять на ваше решение в данный момент. Я бы выбрал тот, который проще всего поддерживать и который наименее подвержен ошибкам. Вы хотите свести к минимуму вероятность скрытых ошибок параллелизма.

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

Если ваша транзакционная нагрузка увеличивается (т. е. больше клиентских транзакций) или запросы становятся быстрее для обработки (приближаясь к 1 миллисекунде на транзакцию), то накладные расходы на транзакцию становятся более важным фактором. Метрика, на которую следует обратить внимание, — это пропускная способность: сколько транзакций выполняется в единицу времени. Абсолютная продолжительность отдельной транзакции менее важна, чем скорость, с которой они выполняются, по крайней мере, если она остается значительно ниже одной секунды.

person Community    schedule 25.10.2011

Один парень на Github провел хорошее сравнение.

TThreadedServer

TThreadedServer порождает новый поток для каждого клиентского соединения, и каждый поток остается активным, пока клиентское соединение не будет закрыто. Это означает, что при наличии 1000 одновременных клиентских подключений TThreadedServer должен одновременно запускать 1000 потоков.

TНеблокирующий сервер

TNonblockingServer имеет один поток, выделенный для сетевого ввода-вывода. Тот же поток также может обрабатывать запросы, или вы можете создать отдельный пул рабочих потоков для обработки запросов. Сервер может обрабатывать множество одновременных соединений с небольшим количеством потоков, поскольку ему не нужно создавать новый поток для каждого соединения.

TThreadPoolServer (здесь тест не проводился)

TThreadPoolServer похож на TThreadedServer; каждое клиентское соединение получает свой собственный выделенный серверный поток. Он отличается от TThreadedServer двумя способами:

Поток сервера возвращается в пул потоков после того, как клиент закрывает соединение для повторного использования. Существует ограничение на количество потоков. Пул потоков не будет расти сверх установленного предела. Клиент зависает, если в пуле потоков больше нет доступных потоков. Его гораздо сложнее использовать по сравнению с двумя другими серверами.

person Community    schedule 16.02.2015