«В теории нет разницы между теорией и практикой. А на практике есть»
Йоги Берра
Распределённые системы — это вообще интересная и непростая тема, мы по ней проводим целую конференцию Hydra. А у опенсорсного проекта Apache Ignite (и его коммерческой версии GridGain) есть ещё и своя интересная специфика: эта база данных добивается производительности с помощью in-memory computing, помещая данные в оперативную память.
Сейчас компания GridGain готовит новые версии Apache Ignite 3 и GridGain 9. А ещё она недавно поучаствовала в Hydra, и в связи с этим мы решили спросить её: как выглядит работа над этими новыми версиями? C какими вопросами приходится сталкиваться, когда делаешь распределённую БД? Ответ компании — под катом.
Репликация — наше все
Одной из ключевых причин перехода к распределенным системам является их высокая доступность, которая, главным образом, обеспечивается за счет избыточности, которая, в свою очередь, невозможна без репликации данных. Существует довольно большое количество различных протоколов репликации данных, обеспечивающих разные гарантии согласованности. Тем не менее, в последние годы, де-факто, стандартным стал класс протоколов, обеспечивающих строгую согласованность данных. Именно на этот класс протоколов мы и опираемся при разработке новых версий Apache Ignite и GridGain.
В академических кругах есть огромное количество публикаций, предлагающих разные протоколы репликации данных. На первый взгляд, все они удовлетворяют нашим требованиям. Однако такие статьи часто упускают из вида общепринятые практики эксплуатации или делают допущения, которые неоправданно увеличивают сложность практического использования и реализации реальных систем.
В рамках работы над Apache Ignite 3 и GridGain 9 мы рассмотрели широкий ряд протоколов репликации и проанализировали их не только со стороны обеспечения необходимых нам гарантий, но и со стороны удобства использования будущей системы, понятности и простоты поддержки протокола, его самодостаточности, а также возможности восстановления при выходе за рамки классической модели отказов. Дополнительным фактором выбора было то, что наша система совмещает два довольно разнородных сценария использования: in-memory и классическое персистентное хранилище.
Среди интересных рассмотренных протоколов были многие варианты семейства Paxos, Raft, а также некоторые менее известные протоколы, такие как PacificA и Hermes. Каждый из протоколов был рассмотрен архитектурной группой GridGain в рамках открытых обсуждений, в которых мог принять участие любой инженер компании. В итоге выбрали протокол Raft, потому что он совмещает в себе прежде всего легкость понимания (а следовательно, и поддержки), необходимую производительность, и широко применяется в индустрии.
На данный момент в альфа-версиях Apache Ignite 3 мы пользуемся open source имплементацией протокола JRaft. Но к сожалению, она имеет ряд практических недостатков, которые нужно устранить перед финальным релизом. Ни один из вариантов реализации этого протокола на Java нас полностью не устроил, поэтому не исключено, что в итоге мы придем к собственной реализации этого протокола, основанной на модели etcd, являющейся одной из наиболее известных имплементаций протокола Raft.
Транзакции и SQL
Следующий шаг — это переработка транзакционного протокола, что является еще более интересной и сложной задачей.
Новые транзакционные протоколы появляются ежегодно, и каждый из них предлагает некоторые компромиссы с точки зрения возможной модели согласованности, уровня изоляции и производительности. Но выбор транзакционного протокола — не только инженерная задача: каждый из компромиссов влияет на возможности использования будущей системы в различных сценариях, а следовательно, определяет и позиционирование продукта.
Одним из минусов предыдущих версий Apache Ignite является то, что SQL запросы не поддерживают транзакции. Поэтому важным фактором при выборе транзакционного протокола для Apache Ignite 3 является ориентированность на SQL, а также строгие гарантии, способ упорядочивания транзакций при их исполнении в распределенной системе, интерактивность транзакций и отсутствие ограничений на количество ключей в транзакции.
Еще один недостаток предыдущих версий — это модель распределенного исполнения SQL-запросов, основанная на map/reduce, что существенно ограничивает набор запросов, которые способна выполнить система. Кроме того, исторически мы использовали H2 для парсинга SQL, что приводило к ряду технических неудобств и невозможности использования оптимизатора запросов в плане распределенного исполнения. В Apache Ignite 3 активно разрабатывается новая модель исполнения запросов в распределенной среде. Мы полностью отказываемся от H2 в пользу собственного движка исполнения на базе Apache Calcite. Это позволит расширить спектр исполняемых запросов, использовать лучший оптимизатор запросов и более тонко контролировать исполнение запросов в кластере.
User Experience
Более строгие гарантии, более высокая надежность, более широкие возможности SQL — все это нужно, но недостаточно для успешного использования системы в реальных условиях. Важно удобство конфигурирования, развертывания, поддержки и обновления кластера. В Apache Ignite 3 мы хотим существенного улучшить все аспекты эксплуатации системы.
Новый подход к конфигурации системы, основанный на формате HOCON, призван заменить собой многословный и не всегда удобный Spring XML. При этом многие параметры узла или кластера можно изменять динамически в runtime с помощью унифицированного интерфейса без необходимости перезапуска узлов.
Новая модель дистрибуции продукта предполагает скачивание и установку минимально необходимого набора исполняемых файлов и библиотек, а также специальной CLI-утилиты, позволяющей выполнять установку необходимых расширений при надобности.
Эта CLI-утилита также является унифицированным инструментом, представляющим единую точку входа для управления кластером Apache Ignite и позволяющим запускать и останавливать узлы, управлять схемой данных, получать информацию о статусе отдельных узлов или кластера целиком, запрашивать метрики.
Многие API, которые предоставляет Apache Ignite, переосмысливаются и проектируются с нуля. И все это для того, чтобы конечные пользователи получили более консистентные, интуитивно понятные и удобные способы работы с системой.
Хочется большего?
Если вы дочитали досюда, похоже, что тема разработки распределённой БД вам интересна. Поэтому дадим напоследок две ссылки для тех, кто готов лезть глубже:
Во-первых, 26 июня GridGain проводит онлайн-митап, где можно будет прикоснуться к этой теме ещё ближе: не только послушать разработчиков компании, но и лично попробовать решить нетривиальные задачи. Среди того, о чём пойдёт речь — Unsafe Java, concurrency-баги, нюансы работы с B-деревом. В общем, не рутина, а хардкор!
А во-вторых, с такими склонностями вам может быть интересно попросту присоединиться к инженерной команде GridGain, начав решать эти нетривиальные задачи уже по работе. Если так, то для вас — эта ссылка.