⚡️Почему Redis быстрый, несмотря на однопоточность
Архитектура редиса устроена так, что все клиентские команды выполняются лишь одним тредом. Это позволяет избавиться от оверхеда на context switch и синхронизацию потоков, но встает вопрос о производительности
Если бы редис синхронно делал следующие шаги для каждого клиентского запроса:
- tcp handshake
- ожидание команд, отправка результатов
- tcp termination
то ни о какой производительности речи бы не шло, т.к. в случае долгого соединения наш тред был бы занят только им
Именно поэтому редис не блокируется на IO - т.е. во время ожидания позволяет потоку заниматься другими полезными вещами. Это является основным принципом обеспечения “параллельной” обработки запросов на одном потоке
Как оно устроено внутри:
epoll() - метод, предоставляемый линуксом, который позволяет проверить, что хотя бы один файловый дескриптор готов к IO. В нашем случае, например, если в установленное между клиентом и редис-сервером tcp соединение от клиента пришли какие-то данные
И далее на этом единственном треде крутится event loop с примерно такой логикой
Таким образом, мы заменили блокирующее ожидание новых данных на периодические проверки, между которыми можно заниматься полезной работой
Архитектура редиса устроена так, что все клиентские команды выполняются лишь одним тредом. Это позволяет избавиться от оверхеда на context switch и синхронизацию потоков, но встает вопрос о производительности
Если бы редис синхронно делал следующие шаги для каждого клиентского запроса:
- tcp handshake
- ожидание команд, отправка результатов
- tcp termination
то ни о какой производительности речи бы не шло, т.к. в случае долгого соединения наш тред был бы занят только им
Именно поэтому редис не блокируется на IO - т.е. во время ожидания позволяет потоку заниматься другими полезными вещами. Это является основным принципом обеспечения “параллельной” обработки запросов на одном потоке
Как оно устроено внутри:
epoll() - метод, предоставляемый линуксом, который позволяет проверить, что хотя бы один файловый дескриптор готов к IO. В нашем случае, например, если в установленное между клиентом и редис-сервером tcp соединение от клиента пришли какие-то данные
И далее на этом единственном треде крутится event loop с примерно такой логикой
while true:
if epoll():
do_something_useful()
Таким образом, мы заменили блокирующее ожидание новых данных на периодические проверки, между которыми можно заниматься полезной работой