Поиск по сайту:

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


Введение

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

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

Что такое шардинг?

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

Может быть полезно рассматривать горизонтальное разделение с точки зрения того, как оно связано с вертикальным разделением. В вертикально секционированной таблице целые столбцы выделяются и помещаются в новые отдельные таблицы. Данные, хранящиеся в одном вертикальном разделе, не зависят от данных во всех остальных, и каждый из них содержит как отдельные строки, так и столбцы. На следующей диаграмме показано, как таблица может быть разделена как по горизонтали, так и по вертикали:

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

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

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

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

Преимущества шардинга

Основная привлекательность сегментирования базы данных заключается в том, что она может облегчить горизонтальное масштабирование, также известное как масштабирование. Горизонтальное масштабирование — это практика добавления большего количества машин к существующему стеку, чтобы распределить нагрузку и обеспечить больший трафик и более быструю обработку. Это часто противопоставляется вертикальному масштабированию, также известному как масштабирование, которое включает в себя обновление оборудования существующего сервера, обычно путем добавления дополнительной оперативной памяти или ЦП.

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

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

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

Недостатки шардинга

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

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

Одна из проблем, с которой пользователи иногда сталкиваются после сегментирования базы данных, заключается в том, что сегменты в конечном итоге становятся несбалансированными. В качестве примера предположим, что у вас есть база данных с двумя отдельными сегментами, один для клиентов, чьи фамилии начинаются с букв от A до M, а другой для тех, чьи имена начинаются с букв от N до Z. Однако ваше приложение обслуживает чрезмерное количество людей, чьи фамилии начинаются на букву G. Соответственно, сегмент AM постепенно накапливает больше данных, чем сегмент N-Z, что приводит к замедлению и зависанию приложения для значительной части ваших пользователей. Сегмент AM стал так называемой точкой доступа к базе данных. В этом случае любые преимущества сегментирования базы данных сводятся на нет замедлением и сбоями. Базу данных, вероятно, потребуется отремонтировать и повторно разделить, чтобы обеспечить более равномерное распределение данных.

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

Последний недостаток, который следует учитывать, заключается в том, что сегментирование изначально поддерживается не каждым механизмом базы данных. Например, PostgreSQL не включает автоматическое сегментирование как функцию, хотя можно вручную сегментировать базу данных PostgreSQL. Существует ряд ответвлений Postgres, которые включают автоматическое сегментирование, но они часто отстают от последней версии PostgreSQL и не имеют некоторых других функций. Некоторые специализированные технологии баз данных, такие как MySQL Cluster или некоторые продукты типа «база данных как услуга», такие как MongoDB Atlas, включают функцию автоматического сегментирования, но стандартные версии этих систем управления базами данных этого не делают. Из-за этого шардинг часто требует «своего собственного» подхода. Это означает, что документацию по шардингу или советы по устранению неполадок часто трудно найти.

Это, конечно, лишь некоторые общие вопросы, которые необходимо рассмотреть перед шардингом. У сегментирования базы данных может быть гораздо больше потенциальных недостатков в зависимости от варианта ее использования.

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

Шардинг архитектуры

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

Разделение на основе ключей

Сегментирование на основе ключа, также известное как сегментирование на основе хэша, предполагает использование значения, взятого из вновь записанных данных, таких как идентификационный номер клиента, IP-адрес клиентского приложения, ZIP-файл. код и т. д. — и подключите его к хеш-функции, чтобы определить, в какой сегмент должны попасть данные. Хеш-функция – это функция, которая принимает в качестве входных данных часть данных (например, адрес электронной почты клиента) и выводит дискретное значение, известное как хэш-значение. В случае сегментирования хеш-значение — это идентификатор сегмента, используемый для определения того, на каком сегменте будут храниться входящие данные. В целом процесс выглядит так:

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

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

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

Разделение на основе диапазона

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

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

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

Разделение на основе каталогов

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

Здесь столбец зоны доставки определяется как ключ сегмента. Данные из ключа сегмента записываются в таблицу поиска вместе с любым сегментом, в который должна быть записана каждая соответствующая строка. Это похоже на сегментирование на основе диапазона, но вместо того, чтобы определять, в какой диапазон попадают данные ключа сегмента, каждый ключ привязан к своему конкретному сегменту. Сегментирование на основе каталогов является хорошим выбором по сравнению с сегментированием на основе диапазона в тех случаях, когда ключ сегмента имеет низкую кардинальность — то есть имеет небольшое количество возможных значений — и сегменту не имеет смысла хранить диапазон ключей. Обратите внимание, что он также отличается от сегментирования на основе ключа тем, что не обрабатывает ключ сегмента с помощью хеш-функции; он просто сверяет ключ с таблицей поиска, чтобы увидеть, куда нужно записать данные.

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

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

Должен ли я осколок?

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

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

  • Объем данных приложения растет и превышает емкость хранилища одного узла базы данных.
  • Объем операций записи или чтения в базу данных превышает возможности одного узла или его реплик чтения, что приводит к замедлению времени отклика или тайм-аутам.
  • Пропускная способность сети, необходимая приложению, превышает пропускную способность, доступную для одного узла базы данных и любых реплик чтения, что приводит к замедлению времени отклика или тайм-аутам.

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

  • Настройка удаленной базы данных. Если вы работаете с монолитным приложением, в котором все его компоненты находятся на одном сервере, вы можете повысить производительность своей базы данных, переместив ее на отдельный компьютер. Это не добавляет такой сложности, как сегментирование, поскольку таблицы базы данных остаются нетронутыми. Однако он по-прежнему позволяет вертикально масштабировать базу данных отдельно от остальной инфраструктуры.
  • Реализация кэширования. Если производительность чтения вашего приложения вызывает у вас проблемы, кэширование — это одна из стратегий, которая может помочь улучшить ее. Кэширование предполагает временное хранение данных, которые уже были запрошены, в памяти, что позволяет вам получить к ним гораздо более быстрый доступ позже.
  • Создание одной или нескольких реплик чтения. Еще одна стратегия, которая может помочь повысить производительность чтения, заключается в копировании данных с одного сервера базы данных (основной сервер) на один или несколько дополнительных серверов. После этого каждая новая запись отправляется на первичный, а затем копируется на вторичные серверы, а чтение выполняется исключительно на вторичные серверы. Такое распределение операций чтения и записи не позволяет какой-либо одной машине брать на себя слишком большую нагрузку, помогая предотвратить замедление работы и сбои. Обратите внимание, что создание реплик для чтения требует больше вычислительных ресурсов и, следовательно, стоит больше денег, что может быть серьезным ограничением для некоторых.
  • Переход на более крупный сервер. В большинстве случаев масштабирование сервера базы данных до машины с большим количеством ресурсов требует меньше усилий, чем сегментирование. Как и в случае создания реплик чтения, обновленный сервер с большим количеством ресурсов, вероятно, будет стоить больше денег. Соответственно, изменять размер следует только в том случае, если это действительно лучший вариант.

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

Заключение

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

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