Введение
«Енисей» — это распределенная документо-ориентированная NoSQL-система управления базами данных, базовая архитектура которой работает с гибкой моделью данных, обеспечивает легкую масштабируемость, стабильную высокую производительность, постоянную работу в режиме 24/7, а также повышенную безопасность. Эта СУБД подходит для многих отраслей производства. После тщательного сравнительного анализа «Енисей» и MongoDB многие специалисты выбрали первую, поскольку она предлагает впечатляющий набор разнообразных возможностей и преимуществ архитектуры:
- масштабируемость и высокая доступность;
- глобальное развертывание;
- гибридная оперативная и аналитическая обработка;
- полнотекстовый поиск;
- события и функции на стороне сервера;
- встраиваемая мобильная СУБД.
В этой статье мы сравним MongoDB и «Енисей» по таким характеристикам, как легкое, эффективное и надежное масштабирование корпоративных приложений, масштабирование отдельных сервисов, а не всей базы данных, предотвращение простоев и поддержание высокой доступности 24/7 с помощью репликации, автоматического восстановления после отказа, а также работы в режиме «онлайн».
Масштабирование и доступность
MongoDB — это иерархическая архитектура, которая требует сложной настройки, включает множество узлов (серверов конфигурации, маршрутизаторов, наборов реплик) для масштабирования по мере роста нагрузки на приложение.
«Енисей» — одноранговая распределенная система с простой, но гибкой архитектурой, позволяющей удовлетворить растущие потребности приложения.
- «Енисей» осуществляет автоматическое шардирование. Для сравнения: в MongoDB шардирование производится вручную, требует трудозатрат, для каждой коллекции должен быть выбран ключ шардирования.
- «Енисей» не зависит от масштаба: все функции работают при любом масштабе. MongoDB ориентирована на работу только с одним хранилищем, многие важные функции, такие как соединение и группировка, не работают в конфигурациях multi-shard.
- «Енисей» умеет масштабироваться простым добавлением одного нового узла. MongoDB для включения в кластер дополнительного шарда требует добавления как минимум трех узлов, что значительно повышает совокупную стоимость владения.
- «Енисей» невосприимчив к отказам узлов или сетевой инфраструктуры. Восстановление доступности MongoDB после возможных отказов требует около 13–14 с.
Шардирование
Архитектура MongoDB располагает простым набором реплик, при работе с ней отмечают многие сложности и низкую эффективность. Для критически важных приложений требуется действительно масштабируемая и высокодоступная база данных.
Шардирование в MongoDB осуществляется вручную или на основе ключей шардирования, а значит, разработчики приложений и операционных систем должны знать знать особенности своих данных. Кроме того, кластер оказывается привязан к одной схеме доступа. Так, если документы «Полеты» содержат названия аэропортов вылета и прибытия, а в качестве ключа шардирования выбран исходный аэропорт, запросы к исходному аэропорту вылета будут выполняться быстро, а к аэропорту прибытия — медленно.
- Шардирование на основе диапазонов может привести к перекосу данных, что делает выбор ключа еще более нетривиальной задачей.Шардирование на основе хэшей в MongoDB приводит к большему числу широковещательных сообщений.
- Коллекции в MongoDB могут быть разделены по-разному, поэтому нельзя увеличить или уменьшить общую емкость системы простым добавлением или удалением узлов. Влияние добавления или удаления узла на производительность или размещение данных ясно не до конца: оно зависит от того, как разделяются коллекции. Ознакомьтесь с документацией по шардированию в MongoDB, чтобы оценить, насколько сложно разрабатывать ключи шардирования, управлять шардированием и принимать во внимание ограничения шардирования.
- В шардированной конфигурации MongoDB требует настройки маршрутизаторов, серверов конфигурации и наборов реплик. Кроме того, сетевое соединение между маршрутизатором Mongo, серверами конфигурации и каждым шардом включает в себя несколько прыжков и потому влияет на общую производительность.
- Настройка репликации для обеспечения высокой доступности является сложным и расточительным процессом. MongoDB требует создания набора реплик для каждого шарда и минимум 3 узла для производственных установок. Серверы вторичных узлов простаивают при низкой загрузке оборудования.
- В MongoDB нет встроенной функции Rack Awareness (осведомленность об аппаратных ресурсах). Ее необходимо настраивать вручную, выбирая вторичные серверы каждого набора реплик на разных стойках, а это весьма трудоемкий процесс.
«Енисей» же был разработан специально для легкого масштабирования и не требует ручной настройки шардирования – все происходит автоматически. Это настолько просто, что описание разделения участков памяти помещается на одной странице. Напротив, в MongoDB на описание шардирования уходит несколько разделов.
Однако, в «Енисей» имеется и ручное управление шардированием, которое может быть полезно в некоторых исключительных случаях.
Настройка отказоустойчивого кластера «Енисей» настолько проста, что практически не требует конфигурации:
- Не нужно создавать наборы реплик.
- «Енисей» автоматически распределяет все шарды и их реплики равномерно по всем узлам.
- Каждый сервер в кластере имеет равное количество шардов.
- В «Енисей» нет простаивающих узлов.
Добавление или удаление узла для увеличения или уменьшения мощности можно легко автоматизировать без ручного вмешательства.
MongoDB ригидна и не адаптируется к меняющимся рабочим нагрузкам
Ключ шардирования в MongoDB не может быть изменен после создания коллекции. Выбор ключа шардирования – это необратимое и важное решение, от которого зависит функциональность кластера. Как указано в их документации:
Выбор ключа шардирования влияет на производительность, эффективность и масштабируемость шардированного кластера. Кластер с наилучшим оборудованием и инфраструктурой может тем не менее стать узким местом из-за выбора ключа шардирования. Выбор ключа шардирования и его резервного индекса также может повлиять на стратегию шардирования, которую может использовать ваш кластер.
В MongoDB данные и их индексы имеют один и тот же секционный ключ. Приложения оптимизируют задержки ответов за счет того, что секционный ключ предоставляется в запросе и в ходе поиска первичного ключа. Если добавляются новые рабочие нагрузки, требующие фильтрации по ключам, не относящимся к секциям, MongoDB приходится возвращаться к фрагментации-дефрагментации. Это, в свою очередь, может привести к увеличению накладных расходов на обработку и повысить время ожидания ответа.
В документации MongoDB ограничение фрагментации-дефрагментации описано следующим образом: «Если запрос не включает ключ шардирования, MongoDB должна направить его ко всем шардам в кластере. Такие запросы scatter-gather могут быть неэффективными. На больших кластерах запросы этого типа становятся невыполнимыми для рутинных операций».
Для масштабируемой архитектуры scatter-gather – так называемый «анти-паттерн» (то есть неэффективный подход) во всех случаях, когда снижение производительности оперативных запросов связано с ростом размера кластера. По мере роста бизнеса и размера требуемого кластера это может пропорциональным образом замедлить и работу приложения.
Кроме того, поскольку MongoDB выполняет всю обработку запросов локально на узлах данных, при росте нагрузки на оперативные запросы требуется масштабирование кластера данных (что приводит к перемещению фрагментов данных), даже если размер данных не меняется. MongoDB не обеспечивает изоляции рабочих нагрузок и независимого масштабирования для рабочих нагрузок оперативных запросов.
СУБД «Енисей» спроектирована с расчетом на изменения
«Енисей» не требует необратимых решений, таких как выбор ключей шардирования. Для оптимизации поиска по первичному ключу данные (документы) автоматически и прозрачным образом разбиваются на разделы по таким ключам. Индексы могут иметь свой собственный секционный ключ (или не иметь его вовсе), поэтому каждый из них может быть разбит самостоятельно для соответствия конкретному запросу. По мере появления новых требований приложение сможет создавать новые индексы с собственными секционными ключами, не влияя на производительность существующих запросов. Это дает приложениям возможность сократить задержки при масштабировании (за счет устранения фрагментации-дефрагментации), а также гибко оптимизировать различные схемы доступа.
Благодаря разделению данных и индексов приложение может добавлять любое необходимое число индексов, не влияя на задержку записи. Это позволяет разделить оптимизацию задержек между трафиком записи и трафиком чтения (запросами). Добавление новых индексов не замедлит трафик записи в приложениях, но при этом в случае необходимости они смогут поддерживать согласованность при чтении. Такой уровень адаптивности особенно хорош для микросервисов, поскольку база данных может развиваться, не боясь снижения производительности записи для критически важных транзакций (например, отправка заказа).
Благодаря «Енисей» приложения могут воспользоваться преимуществами настоящей изоляции рабочих нагрузок в базе данных, где каждая служба может работать на различных типах копий для конкретной производительности и потребностей. Это дает приложению полную возможность регулировать производительность рабочей нагрузки в соответствии с меняющимися потребностями.
Один узел «Енисей» на вашем ноутбуке показывает точно такие же интерфейс и поведение, как и 3-узловой тестовый кластер виртуальных машин в центре обработки данных – и даже как 20-узловой (и более) кластер облачных экземпляров или контейнеров. Для развертывания в различных средах в приложение не требуется вносить изменения. В отличие от MongoDB, все функции «Енисей» доступны и ведут себя одинаково как при использовании как одноузловой, так и многоузловой конфигурации.
Стоимость владения шардированной конфигурацией MongoDB значительно выше
Количество серверов, необходимых для создания шардированной системы MongoDB, намного больше , чем количество шардов.
- Для настройки отказоустойчивого кластера каждый шард в MongoDB требует создания набора реплик с минимум 3 узлами. Настройка набора реплик не только сложна, но и дорога из-за количества необходимых серверов. Вместо полной копии данных можно использовать узел Arbiter ("арбитр"), но это все равно требует выделения полного узла.
- Вторичные узлы каждого набора реплик (не менее 2 узлов на набор реплик) простаивают и не обрабатывают трафик записи. Это приводит к неполному использованию аппаратного обеспечения.
- Необходима настройка серверов конфигурации. Это дополнительные серверные узлы, и их требуется не менее 3, поскольку они должны быть настроены как наборы реплик для обеспечения высокой доступности.
При этом «Енисей»:
- Не имеет требований к минимальному количеству узлов, к их четности или нечетности
- Прозрачным образом распределяет шарды и их реплики равномерно по кластеру любого размера
- Не имеет понятия простаивающих/пассивных узлов: рабочая нагрузка равномерно распределяется между всеми участниками каждого сервиса
- Не имеет выделенных узлов конфигурации/метаданных
MongoDB зависит от масштаба
Функциональность MongoDB варьируется в зависимости от того, является ли коллекция шардированной или нет, и это вынуждает менять приложение при переходе с одного узла на шардированную систему. Это следствие выбранного MongoDB дизайна в своей архитектуре шардинга и индексирования.
При переходе на шардированную среду приложения MongoDB сталкиваются со многими изменениями, и вот некоторые из них:
- Для явного использования шардирования код инициализации и настройки приложения должен быть изменен. Например, шардирование должно быть включено, ключ шардирования должен быть определен, по ключу шардирования должен быть создан индекс, каждая коллекция должна быть явно шардирована – и так далее по списку. MongoDB предоставляет обширную страницу документаци о том, как перейти на шардированную структуру.
- Многие операции недоступны в шардированных конфигурациях: например, поиск по группам и геопоиск Следовательно, приложение должно быть переписано, чтобы обойти эти ограничения. Полный список ограничений работы шардированного кластера доступен в документации MongoDB. Эти ограничения также подчеркивают тот факт, что MongoDB основана на системе с одним узлом, которая постепенно превратилась в шардированную систему, а не начинала работать как таковая сразу.
- Даже такая функция, как уникальные ключи, которую MangoDB преподносит как преимущество перед «Енисей», в шардированных системах не работает.
- Аналог JOIN у MongoDB – это $lookup, который даже не позволяет объединять шардированные коллекции с помощью $lookup: коллекция from не может быть шардирована.
«Енисей» отличает отсутствие потребности в восстановлении после отказа
Восстановление после отказа в MongoDB основано на осуществлении выборов при отказе основного узла. Это увеличивает время восстановления по сравнению с «Енисей», которой такая процедура не требуется.
В документации MongoDB говорится, что среднее время выборов основного узла обычно не превышает 12 секунд – с учетом времени на обнаружение недоступности основного узла и проведение выборов. Поскольку в «Енисей» не нужно проводить выборы, эти накладные расходы исключаются.
MongoDB не указывает время, необходимое для фактической обработки восстановления после выборов, но даже в лучшем случае –1–2 секунды – их общее время обхода отказа составляет 13–14 секунд. Таким образом, общее время простоя при использовании «Енисей» существенно ниже и может стать решающим фактором для достижения приложением уровня доступности 99,999 против 99,9.
Принцип обнаружения сбоев в MongoDB нестабилен и опирается только на тактирование. По этой причине MongoDB не рекомендует снижать electionTimeoutMillis со значения в 10 секунд, установленного по умолчанию, так как это может привести к частым выборам (источник документации здесь):
«Снижение параметра конфигурации репликации electionTimeoutMillis со значения по умолчанию 10000 (10 секунд) может привести к более быстрому обнаружению отказа первичного сервера. Однако кластер может чаще назначать выборы в связи с такими факторами, как временная сетевая задержка, даже если первичная система в остальном здорова. Это может привести к увеличению откатов для операций записи w : 1».
В кластере «Енисей» все узлы абсолютно равноправны, в нем нет арбитров и процедуры их выбора, так же как нет и необходимости в перевыборах чего-либо при возникновении сбоев. Кластер «Енисей» абсолютно устойчив к фрагментации сети и к критическим сбоям отдельных узлов. Главное, чтобы оставались доступны хотя бы по одной реплики каждого шарда. В случае «Енисей» оказывается вообще не применимо такое понятие, как восстановление после сбоя: доступность данных сохраняется даже в самых сложных условиях.
Как только фрагментация сети восстанавливается, а отказавшие узлы возвращаются в строй, запускается процедура синхронизации данных с этими узлами и в конце концов все узлы снова приобретают полную консистентность. Такое восстановление кластера «Енисей» не требует прерывания никаких пользовательских сценариев, прикладные процессы продолжают работать и никак не ощущают изменений в функциональности СУБД. «Енисей» полностью поддерживает концепцию “Eventual consistency”, то есть “согласованности в конечном счете”. Любой отказ в сети или на отдельном узле не является отказом с точки зрения кластера «Енисей», пока имеется доступ хотя бы к одной реплике данных.
Отсутствие изоляции отказов в MongoDB
MongoDB – это монолитный процесс, который обрабатывает чтение/запись данных, управление кластером, управление индексами и обработку запросов. Сбой в любом из этих доменов приводит к отказу всей функциональности узла: архитектура единого процесса не обеспечивает изоляции от сбоев.
«Енисей», напротив, построен на модели большого количества параллельно и независимо функционирующих акторов (акторная архитектура), каждый из которых выполняет только свою персональную свою задачу и обменивается асинхронными сообщениями с другими акторами. Этому принципу полностью соответствует и встроенный в «Енисей» веб-сервер, обеспечивающий прием и обработку клиентских запросов к REST API. Обработка каждого из запросов полностью изолирована: исключение, возникшее при обработке одного из запросов никак не влияет на обработку всех остальных параллельных запросов. При возникновении проблемы только один запрос, в котором она возникла, завершается ошибкой, а все остальные обрабатываются в штатном режиме за счет надежной изоляции процессов на уровне кода, архитектуры и даже самого языка, на котором реализован «Енисей» (Erlang).
Такая изоляция от сбоев в «Енисей» является ключевым фактором для достижения еще более высокого уровня безотказной работы приложений, работающих на «Енисей».
Итоги сравнения масштабируемости и доступности «Енисей» и MongoDB
Выводы
MongoDB предоставляет длинный список функций «для галочки», но многие из них не работают согласованно друг с другом. В итоге пользователь имеет базу данных, которая не поддается масштабированию и не способна функционировать должным образом и адаптироваться к современным требованиям предприятий. В конечном итоге MongoDB лучше всего подходит для гибкого доступа к данным в тех случаях, когда среди требований нет низкой задержки, высокой пропускной способности, множества шаблонов доступа, географической репликации или автономного доступа.
«Енисей» же регулярно используется для кэширования уровней, источников информации и систем записи в сценариях использования, предполагающих высокую степень гибкости и большие масштабы, включая мобильные приложения, работающие в автономном режиме. Благодаря своему дизайну «Енисей» доступна и управляется через согласованный набор API, масштабируется, обновляется и диагностируется как единое целое. Таким образом, «Енисей» является полноценной платформой баз данных, которая не только удовлетворяет потребности сегодняшнего дня, но и предлагает гибкость для адаптации к потребностям завтрашнего дня.