Как масштабировать MongoDB? Каковы лучшие практики шардинга?

Хотя гибкая схема – это то, как большинство людей знакомится с MongoDB, она также является одной из лучших баз данных (возможно, даже лучшей, когда речь идет о повседневных приложениях) для обработки очень и очень больших наборов данных. В то время как обоснование этого аргумента требует самой статьи (я надеюсь, что когда-нибудь смогу найти для нее время!), Общая идея состоит в том, что решения на основе SQL не поддерживают шардинг, а построение его на ваших отстой усердно.

Лучшее, на что вы можете надеяться, – это создать кластер (кстати, между прочим, это не имеет ничего общего с шардингом) или выбрать управляемое решение, такое как Amazon RDS или Google Cloud SQL, которое становится непомерно дорогим по мере роста ваших данных..

В этой статье мы рассмотрим один из основных методов горизонтальное масштабирование базы данных: шардинг, для MongoDB, и рекомендовать некоторые лучшие практики для того же. Тем не менее, я чувствую, что лучше начать с основ шардинга, потому что многие люди, которые хотят масштабировать MongoDB, могут быть не очень знакомы с ним..

Однако, если вам известно о шардинге, смело просматривайте следующий раздел..

Основы шардинга

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

Теперь, учитывая, что даже на лучших серверах в настоящее время нет более 256 ГБ ОЗУ или 16 ТБ жесткого диска, вы быстро попадаете в кирпичную стену, когда пытаетесь масштабировать по вертикали (или «масштабировать», как гласит терминология). Тем не менее, вы можете соединить столько отдельных машин вместе (по крайней мере, теоретически) и легко обойти это ограничение..

Конечно, задача сейчас заключается в координации между всеми этими машинами.

Sharding базы данных

Термин «разделение» обычно применяется к базам данных, идея состоит в том, что одной машины никогда не будет достаточно для хранения всех данных. При разбиении база данных «разбивается» на отдельные части, которые находятся на разных машинах. Простым примером может быть: предположим, что у бизнеса есть компьютеры, которые могут хранить до 2 миллионов элементов данных клиентов. Теперь бизнес достигает этой точки разрыва и, вероятно, скоро превзойдет 2,5 миллиона пользователей. Итак, они решили разбить свою базу данных на две части:

И волшебным образом емкость системы теперь удвоилась!

Ну, если бы жизнь была такой простой! ��

Проблемы в разделении базы данных

Как только вы немного задумаетесь о шардинге, некоторые отвратительные проблемы поднимают их уродливую голову.

Нет первичных ключей

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

Нет внешних ключей

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

Странные ошибки данных

Если выходит из строя одна машина, конечному пользователю может быть показано «К сожалению, что-то сломалось!» страница, которая, несомненно, будет раздражать, но через некоторое время жизнь будет на правильном пути.

Теперь рассмотрим, что происходит в зашифрованной базе данных. Предположим, что в нашем предыдущем примере защищенная база данных является банковской базой данных, и один клиент отправляет деньги другому. Предположим также, что данные первого клиента хранятся в первом шарде, а данные второго клиента – во втором (ты видишь, куда я иду с этим ?!). Если машина, содержащая второй осколок, выходит из строя, можете ли вы представить, в каком состоянии находится система? Куда пойдут деньги на транзакцию? Что увидит первый пользователь? Что увидит второй пользователь? Что они оба увидят, когда осколки вернутся в онлайн?

Управление транзакциями

Давайте также рассмотрим критически важный случай управления транзакциями. На этот раз предположим, что система работает на 100% нормально. Теперь два человека (A и B) делают платеж третьему (C). Весьма вероятно, что обе транзакции будут одновременно считывать остаток на счете C, что приводит к путанице:

  • Баланс счета С = 100 $.
  • Транзакция A читает остаток C: $ 100.
  • Транзакция B считывает остаток C: $ 100.
  • Транзакция А добавляет 50 долларов и обновляет баланс: 100 долларов + 50 = 150 долларов.
  • Транзакция B добавляет 50 долларов и обновляет баланс: 100 долларов + 50 = 150 долларов.

Черт! 50 долларов просто исчезли в воздухе!

Традиционные системы SQL избавляют вас от этого, предоставляя встроенное управление транзакциями, но как только вы выходите из одной машины, вы тост.

Дело в том, что с такими системами легко столкнуться с проблемами повреждения данных, которые невозможно восстановить. Тянуть волосы тоже не поможет! ��

MongoDB Sharding

Для архитекторов программного обеспечения волнение от MongoDB было не столько в его гибкой схеме, сколько в его встроенной поддержке шардинга. С помощью всего лишь нескольких простых правил и подключенных машин вы были готовы запустить защищенный кластер MongoDB в кратчайшие сроки..

Изображение ниже показывает, как это выглядит в типичном развертывании веб-приложения.

Изображение предоставлено: mongodb.com

Самое приятное в шардировании MongoDB – это то, что даже балансировка шардов происходит автоматически. То есть, если у вас есть пять осколков, и два из них почти пусты, вы можете сказать MongoDB перебалансировать вещи так, чтобы все осколки были одинаково полны..

Как разработчик или администратор, вам не нужно сильно беспокоиться, поскольку MongoDB за кулисами выполняет большую часть тяжелой работы. То же самое касается частичного отказа узлов; если у вас правильно настроены и работают наборы реплик в кластере, частичные простои не влияют на работоспособность системы.

Полное объяснение будет довольно кратким, поэтому я закрою этот раздел, сказав, что MongoDB имеет несколько встроенных инструментов для разделения, репликации и восстановления, что позволяет разработчикам очень легко создавать крупномасштабные приложения. Если вы хотите получить более полное руководство по возможностям шардинга MongoDB, официальные документы место для.

Вы также можете быть заинтересованы в этом полное руководство разработчика.

MongoDB Sharding Best Practices

Хотя MongoDB «просто работает» из коробки для шардинга, это не значит, что мы можем почивать на лаврах. Sharding может навсегда разрушить ваш проект, в зависимости от того, насколько хорошо или плохо это было сделано.

Более того, нужно учитывать множество мелких деталей, в противном случае нередки случаи, когда проекты рушатся. Цель не в том, чтобы напугать вас, а в том, чтобы подчеркнуть необходимость планирования и быть предельно осторожными даже при небольших решениях.

Ключ шардинга неизбежно контролирует шардинг в MongoDB, поэтому идеально, чтобы мы начали наш опрос с этого.

Высокая мощность

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

Здесь у нас довольно простое расположение; входящий документ сканируется на предмет имени пользователя, и в зависимости от того, где первая буква лежит в английском алфавите, он попадает в один из трех осколков. Точно так же поиск документа очень прост: например, детали для «Питера» наверняка будут во втором осколке..

Все это звучит хорошо, но дело в том, что мы не контролируем имена пользователей входящих документов. Что если мы будем получать имена только в диапазоне от B до F большую часть времени? Если это так, у нас будет так называемый «гигантский» кусок в shard1: большая часть системных данных будет там переполнена, что фактически превратит установку в единую систему баз данных..

Лечение?

Выберите ключ с высокой степенью кардинальности – например, адрес электронной почты пользователей, или вы даже можете пойти на составной ключ шарда, который является комбинацией нескольких полей.

Монотонно меняющееся

Распространенной ошибкой в ​​шардинге MongoDB является использование монотонно увеличивающихся (или автоматически увеличивающихся, если хотите) ключей в качестве ключа шарда.

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

Изображение предоставлено: mongodb.com

Как вы можете видеть на картинке, как только мы преодолеем диапазон 20, все документы начнут собираться в Чанке C, вызывая там монолит. Решение состоит в том, чтобы перейти к схеме хэширования ключа хэширования, которая создает ключ сегментирования путем хеширования одного из предоставленных полей и использования его для определения порции.

Изображение предоставлено: Mongodb.com

Ключ хешированного ключа выглядит так:

{
"_Я бы" :"6b85117af532da651cc912cd"
}

. . . и может быть создан в клиентской оболочке Mongo с помощью:

db.collection.createIndex ({_id: hashedValue})

Осколок рано

Один из самых полезных советов непосредственно из окопов – осколок на ранней стадии, даже если вы в конечном итоге получите небольшой кластер из двух частей. Как только объем данных превысит 500 ГБ или что-то в этом роде, в MongoDB осколок станет грязным процессом, и вы должны быть готовы к неприятным сюрпризам. Кроме того, процесс перебалансировки потребляет очень большую пропускную способность сети, которая может задушить систему, если вы не будете осторожны.

Однако не все сторонники. В качестве интересного примера (обучение на самом деле в комментариях), посмотрите этот хороший Percona блог.

Запуск балансира

Еще одна хорошая идея – отслеживать шаблоны трафика и запускать балансировщик сегментов только в периоды низкого трафика. Как я уже упоминал, для перебалансировки требуется значительная пропускная способность, которая может быстро привести к полному обходу всей системы. Помните, несбалансированные осколки не являются причиной немедленной паники. Просто дайте нормальному использованию сохраниться, дождитесь возможностей с низким трафиком, и пусть балансировщик сделает все остальное!

Вот как это можно сделать (если у вас низкий трафик с 3 до 5 часов):

использовать конфиг
db.settings.update (
{ _Я бы: "балансер" },
{$ set: {activeWindow: {start: "3:00", стоп : "5:00" }}},
{upsert: true}
)

Вывод

Разделение и масштабирование любой базы данных – сложная задача, но, к счастью, MongoDB делает ее более управляемой, чем другие популярные базы данных..

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

Я надеюсь, что эта статья смогла пролить некоторый свет на то, что такое разделение в MongoDB, и на что должен позаботиться разработчик при переходе к масштабированию. Чтобы узнать больше, вы можете получить это онлайн курс для освоения MongoDB.

TAGS:

  • База данных

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me