Redis однопоточен, тогда как он выполняет параллельный ввод-вывод?

Пытаясь понять некоторые основы Redis, я наткнулся на интересный пост в блоге.

Автор заявляет:

Redis является однопоточным с epoll/kqueue и масштабируется бесконечно с точки зрения ввода-вывода concurrency.

Я, конечно, неправильно понимаю всю резьбу, потому что я считаю это утверждение озадачивающим. Если программа однопоточная, как она делает что-то одновременно? Почему это так здорово, что операции Redis являются атомарными, если сервер однопоточен?

Может кто-нибудь пролить свет на проблему?

Ответ 1

Ну, это зависит от того, как вы определяете concurrency.

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

Например, бармен может следить за несколькими клиентами, пока он может только готовить один напиток за раз. Поэтому он может предоставить concurrency без parallelism.

Этот вопрос обсуждался здесь: Concurrency vs parallelism - В чем разница?

См. также эту презентацию от Rob Pike.

Однопоточная программа может определенно предоставлять concurrency на уровне ввода-вывода с помощью механизма мультиплексирования ввода-вывода (de) и цикла событий (что и делает Redis).

Parallelism имеет стоимость: с несколькими сокетами/несколькими ядрами, которые вы можете найти на современном оборудовании, синхронизация между потоками чрезвычайно дорога. С другой стороны, узким местом эффективного механизма хранения, например Redis, часто является сеть, задолго до процессора. Изолированные циклы событий (которые не требуют синхронизации), поэтому рассматриваются как хороший дизайн для создания эффективных масштабируемых серверов.

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

Ответ 2

ОК, Redis является однопоточным на уровне пользователя, OTOH, все асинхронные операции ввода-вывода поддерживаются пулами потоков ядра и/или раздельными драйверами.

' Параллельный', для некоторых, включает в себя распространение сетевых событий в состояниях состояний сокетов. Он однопоточный, работает на одном ядре (на уровне пользователя), поэтому я бы не назвал его параллельным. Другие отличаются.

' шкала неопределенно с точки зрения ввода-вывода concurrency' просто экономична с истиной. Они могут получить больше убеждений, если они скажут, что "может масштабироваться лучше, чем один поток на клиенте, поскольку клиенты не требуют многого", хотя впоследствии они могут почувствовать себя обязанными добавить "сдутые при большой загрузке другими асинхронными решениями" которые используют все ядра на уровне пользователя ".