Технологии

ZooKeeper

Как использовать ZooKeeper для решения широкого круга задач по System Design

Координация распределенных систем - сложная задача. Несмотря на значительный прогресс в вычислительной мощности и методах масштабирования, фундаментальная проблема все та же: как организовать совместную работу десятков или сотен серверов? Когда этим машинам необходимо выбирать лидеров, поддерживать согласованные конфигурации и обнаруживать сбои в режиме реального времени, мы сталкиваемся именно с теми проблемами, для решения которых и был разработан ZooKeeper.

Выпущенный в 2008 году, ZooKeeper стареет, и появилось множество альтернатив. Тем не менее, он по-прежнему играет центральную роль, особенно в экосистеме Apache.

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

Давайте рассмотрим, как работает ZooKeeper, когда его следует использовать и как он развивается в современном мире распределенных систем.

Практический пример

Чтобы понять, почему координация - сложная задача, давайте начнем с примера. Представьте, что вы разрабатываете приложение для чата.

Изначально ваше приложение работает на одном сервере. Все просто. Когда Алиса отправляет сообщение Бобу, оба пользователя подключаются к одному и тому же серверу. Сервер точно знает, куда доставить сообщение - все хранится в памяти, низкая задержка, координация не требуется.

Приложение для чата на одном сервере

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

Приложение для чата с двумя серверами

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

Но это создает новые проблемы. База данных становится единой точкой отказа. Если она выйдет из строя, вся система чата перестанет работать. Это также увеличивает задержку - теперь каждое сообщение требует обращения к базе данных перед маршрутизацией. По мере масштабирования системы до миллионов пользователей эта база данных будет перегружена запросами, создавая узкое место в системе.

Приложение для чата с базой данных

Вы можете попытаться оптимизировать процесс с помощью кэширования, но тогда возникнут проблемы с согласованностью кэша. Что если пользователь отключится от сервера 2 и переподключится к серверу 3, но кэш сервера 1 по-прежнему будет считать, что он находится на сервере 2? Сообщения будут потеряны.

Возможно, вы думаете: "заставим серверы напрямую сообщать друг другу об изменениях". Когда пользователь подключается к серверу 3, он отправляет широковещательное сообщение всем остальным серверам. Но по мере того, как ваша система разрастается до десятков или сотен серверов, эти широковещательные сообщения создают большой сетевой трафик. Каждому серверу приходится поддерживать соединения с каждым другим сервером - это соединений, что плохо масштабируется.

Широковещательные сообщения

Затем возникает проблема сбоя сервера. Что если сервер 2 выйдет из строя? Он не сможет никому сообщить о своей неработоспособности. Подключенные к нему пользователи будут отключены, но другие серверы об этом не знают. Они продолжат пытаться отправлять сообщения на неработающий сервер.

Возможно, вы решили внедрить проверку работоспособности (heartbeats) - серверы периодически проверяют, активны ли другие серверы. Но это создает новую проблему: известную как "сетевое разделение" (network partition). Что если сервер 2 активен, но между ним и сервером 1 возникла проблема с сетью? Сервер 1 считает, что сервер 2 не работает, хотя это не так. Некоторые серверы могут видеть сервер 2 как активный, а другие - как неработающий. В результате вы получаете противоречивое представление о состоянии вашей системы.

Перейдите на Premium, чтобы продолжить

Разблокируйте доступ к этой статье и всем остальным материалам с NowInterview Premium

Перейти на Premium