Виды репликации в MongoDB



    Привет, хабровчане! Расшифровали для вас часть урока по MongoDB от Евгения Аристова, разработчика с 20-летним стажем и автора онлайн-курса «Нереляционные базы данных». Материал, как и сам курс, будет полезен специалистам, сталкивающимся в работе с NoSQL, желающим научиться оптимизировать свои базы данных и работу с ними.

    Зачем нужна репликация?


    1. Высокая доступность. Бэкап это хорошо, но нужно время на его развертывание.
    2. Горизонтальное масштабирование. В случае, когда закончились физические ядра и память у сервера.
    3. Бэкап лучше делать с реплики, а не с мастера.
    4. Геораспределение нагрузки.

    В MongoDB видов репликации из коробки немного: самый актуальный на данный момент Replicaset, а второй — Master-slave, который ограничен версией 3.6 и подробно рассматриваться в этой статье не будет.

    №1. Запись и чтение с основного сервера


    У нас есть драйвер клиентского приложения, который читает и пишет на Primary-ноду. Дальше по протоколу репликации информация, которая записывается на Primary-ноду, отправляется на Secondary-ноды.



    №2. Чтение с реплики


    Альтернативой чтению и записи с Primary является вариант, когда драйвер может читать информацию с Secondary. При этом настройки могут быть разными, например, «читать информацию предпочтительнее с Secondary, а потом с Primary» или «читать информацию с ближайшего по карте сети нода» и т.д. Такие варианты настроек используются чаще, чем первый вариант репликации, где все идет через Primary.



    3 способа сделать реплику доступной для чтения:


    • Указать db.slaveOk()
    • Указать в строке подключения драйвера нужные параметры
    • Указать все, а потом более точечно прописать в самом запросе, например, читай из Secondary в Южном регионе: db.collection.find({}).readPref( “secondary”, [ { “region”: “South”} ] )

    Проблемы чтения с реплики


    1. Так как запись асинхронная, она может быть уже сделана на Primary, но не доехать до Secondary, поэтому будут прочитаны старые данные с Secondary.
    2. Записав данные на основной, нельзя быть уверенным, когда остальные получат эти данные.
      Чтобы было все синхронно, каждая нода должна подтвердить получение данных. Сейчас в MongoDB есть общие настройки, а есть на каждый запрос, где можно указать, от скольки нод ожидается подтверждение запроса.
    3. Когда падает основной сервер, запускается процесс выборов (кворум) — а это уже особое отдельное «веселье».

    Настроен процесс репликации может быть двумя способами


    А) Ноды «слушают» друг друга, эта связь называется Heartbeat. То есть каждая нода постоянно проверяется другими на предмет «живая/ неживая», для того, чтобы предпринимать какие-то действия, если что-то случилось.



    Б) Одна Secondary-нода меняется на Arbiter. Это очень легковесное приложение, запускается как Mongo, практически не ест ресурсов и отвечает за то, что определяет, какую ноду в момент голосования признать главной. И это в целом рекомендуемая конфигурация.



    Основные особенности этой конфигурации


    • Репликация асинхронная
    • Арбитр не содержит данных, и поэтому очень легковесный
    • Primary может стать Secondary и наоборот. Арбитр не может стать ни Primary, ни Secondary
    • Максимальное количество реплик 50 и только 7 из них имеют право голосовать
    • Arbiter можно установить и на Primary или Secondary, но делать это не рекомендуется, т.к. если этот сервер упадет, Arbiter тоже не сможет выполнить свою функцию.

    Если вам интересно узнать больше о кластерных возможностях MongoDB, посмотреть запись всего демо-урока можно тут. На занятии Евгений Аристов демонстрирует отличия Replicaset от Master-slave, объясняет процесс кворума, масштабирование, шардирование и правильный подбор ключа к шардированию.

    Изучение возможностей MongoDB входит в программу онлайн-курса «Нереляционные базы данных». Курс предназначен для разработчиков, администраторов и других специалистов, которые сталкиваются в работе с NoSQL. На занятиях студенты на практике осваивают наиболее актуальные сегодня инструменты: Cassandra, MongoDB, Redis, ClickHouse, Tarantool, Kafka, Neo4j, RabbitMQ.

    Старт уже 30 сентября, но в течение первого месяца можно присоединиться к группе. Изучайте программу, проходите вступительный тест и присоединяйтесь!
    OTUS. Онлайн-образование
    Цифровые навыки от ведущих экспертов

    Похожие публикации

    Комментарии 8

      0
      1) есть ли какая фича балансировки запросов между секондари нодами?
      2) если апдейт секондари нод асинхронный. В монго же есть map reduce. Возможно ли такое что запрос возьмет половину данных из секондари1 где всё обновилось, а другую неактульную из секондари2 где апдейт еще не докатился? Или там по принципу на какую ноду попал запрос из той и только той всё будет прочитано
      3) можно ли подключать новый секондари ноды на лету?
      4) если примари нода стала Арбитром, получается база на запись не работает? Что происходит с запросами на запись?
        0
        1. есть, балансировка проиходит на уровне драйвера в приложении (либо на уровне mongos в случае с sharded-cluster). Управляется указанием read preference при запросе, если просто указываем secondaryPreferred, то там юзается раундробин между репликами емнип.
        2. на самом деле есть write concern, который определяет минимальное кол-во acknowledgment'ов для успешной записи. Касательно map-reduce — эта операция не распределяется между нодами в реплика-сете (куда пришли, там и сделали)
        3. можно подключать/отключать налету. При первом подключении нода перейдёт в режим синхронизации и будет синкаться с мастера, а после завершения досинкается из бинлога (oplog) — тут важно чтобы длины оплога хватило по времени синхронизации.
        4. так нельзя) Арбитром не становятся — им рождаются (ну или ручками можно сконвертить).
          +2
          1. У вас есть writecocnern — сколько нод должно записать и то же самое прочитать данные. если стоит majority — данные консистентны
          2. в mapreduce так же уже есть writeConcern. Без него конечно это возможно
          3. Конечно %)

          Предлагаю просто посмотреть видео
          0

          Почему конфигурация с Арбитром рекомендуемая, она же не fault-tolerant, в отличие от конфигурации А?


          Если упадёт Primary или Secondary, то новый Primary конечно выбран будет. Но он будет недоступен для majority-записи по причине отсутствия этой самой majority. Арбитр в неё не входит. Останется только чтение и неконсистентная запись с “w:1”

            0
            Полностью с вами согласен, не озвучил данный момент для writeConcern «majority»
            0
            Так я не понял, кирик ответил что приматри не может стать арбитром, а тмакс наоборот. В общем момент с арбитром не очень ясен.

            По остальным вопросам всё понятно.
              0
              Не вижу чтобы тмакс говорил что праймари может стать арбитром. Арбитр в схеме с primary+secondary+arbiter нужен только лишь для создания кворума. Такую схему обычно запускают когда в распоряжении имеется ограниченное кол-во ресурсов: 2 «большие» машины под мастер и слейв и одна мелкая под арбитр. В идеальном мире нужно всё-таки стремиться запускать схему master-secondary-secondary, причём не обязательно что третий secondary должен участвовать в выборах, главное чтобы он мог голосовать. Его так же можно сделать отстающей репликой на случай факапа в основной связке мастер-слейв — с него можно будет восстановить данные. Такой а-ля бэкап получается.
              0

              Какая-то мало-актуальная статья. Ни слова про write concern и cache pressure. Зато про 20 лет опыта не поленились написать. В целом уровень "немного разобрался как работал реплика-сет до верии 3.0".

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое