Что такое шардирование бд

Инструменты пользователя

Инструменты сайта

Боковая панель

Олег Зорин

Содержание

Шардирование баз данных

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

Сложно сказано, однако, суть проста. Давайте посмотрим вначале на примерчик.

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

Предлагаю рассмотреть практический пример.

Постановка задачи

Допустим у нас есть очень популярный сервис публикации веселых картинок. Нам необходимо разработать метод хранения информации о картинках.

Необходимо хранить следующие данные:

Требуется организовать выборку картинок по автору.

В общем все просто и обыкновенно, но не забывайте, что у нас супер популярный ресурс.

«Классически» подход

Самым простым решением будет следующее.

1. Создаем базу данных `my_super_service`.

2. Создаем табличку `pictures`, со следующей структурой:

3. Подключение к базе данных

4. Получение записей

Все очень просто и прямолинейно, в прицепе в большинстве случаев ни чего больше и не надо.

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

Подход с применением шардирования баз данных

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

К примеру, мы уже не можем использовать `photo_id` из классического представления, так как мы объявили его autoincrement. Но баз то теперь может быть две, три или вообще сто и в каждой будет запись с одинаковым `photo_id` и в рамках нескольких таблиц он уже не будет уникальным. В данном случаи мы должны предусмотреть какой-то универсальный идентификатор картинки, который будет нести в себе и информацию о авторе картинки. Можно, на пример, использовать GUID.

Итак преобразуем процесс, у нас получится следующее:

1. Создаем начальную базу данных `my_super_service`, а можно создать сразу две `my_super_service0` и `my_super_service1`, для тестирования механизма шардирования.

2. Создаем табличку `pictures` в каждой базе данных, со следующей структурой:

Как вы наверно обратили внимание в нашей табличке остался уникальный идентификатор `photo_id`. Надо понимать, что это поле должно быть уникальным в рамках всех баз данных, а не одной какой-то определенной. И еще раз напоминаю, так как шардирование мы решили проводить по полю `user_id`, и если у вас возникнет необходимость делать выборку по полю `photo_id` (что мы сейчас не рассмативаем), то наш идентификатор картинок должен быть комплексным и нести в себе информацию о идентификаторе пользователя.

3. Подключение к базе данных

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

Я предлагаю разработать скрипт, который будет работать по следующему алгоритму:

Далее мы рассмотрим одну из реализаций подобного скрипта. Условно назовем эту функцию sqlShard().

Для построения хеша поля `user_id` будем использовать функцию md5(). Вы конечно волны использовать любой другрой принцип построения хеша.

4. Получение записей

Скрипт подключения к базе данных

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

Давайте рассмотрим алгоритм поэтапно.

Распределение подключений к базе данных

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

Получение настроек для подключения к базе данных

Простой

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

Посложнее

Для получения настроек напишем следующий алгоритм:

Подключение к базе и отправка запроса

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

Резюме

В заключение я хочу дать несколько подсказок.

Источник

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

Шардирование баз данных

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

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

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

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

Критерий шардинга — какой-то параметр, который позволит определять, на каком именно сервере лежат те или иные данные.

Содержание

Подход с применением шардирования баз данных

Шардинг и репликация

Репликация

Репли­ка­ция — это син­хрон­ное или асин­хрон­ное копи­ро­ва­ние дан­ных между несколь­кими сер­ве­ра­ми. Веду­щие сер­вера назы­вают масте­рами (master), а ведо­мые сер­вера — слэй­вами (slave). Мастера исполь­зу­ются для изме­не­ния дан­ных, а слэйвы — для счи­ты­ва­ния. В клас­си­че­ской схеме репли­ка­ции обычно один мастер и несколько слэй­вов, так как в боль­шей части веб-про­ек­тов опе­ра­ций чте­ния на несколько поряд­ков боль­ше, чем опе­ра­ций запи­си. Однако в более слож­ной схеме репли­ка­ции может быть и несколько масте­ров.

Шардинг

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

Совместное использование

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

Шардинг и репликация — это популярные и мощные техники масштабирования систем работы с данными. Несмотря на примеры для MySQL, эти подходы универсальны и могут применяться для любой технологии.

SQL Azure Federations

Если приложение использует базы данных MS SQL, возникает несколько вопросов. Конечно первое что приходит в голову — организовать кластер из виртуальных машин SQL Server. Решение достаточно простое и хорошо всем знакомое. А что делать, если приложение использует базу данных как сервис (SaaS)? Что если мы не хотим заниматься настройкой кластера SQL Server? Конечно же, если мы говорим о Windows Azure, то в качестве SQL базы данных будет использоваться SQL Azure. Эта база данных поддерживает технологию горизонтального масштабирования (шардинг) называемую SQL Azure Federations. Принцип ее работы очень простой: логически независимые друг от друга строки одной таблицы хранятся в разных базах данных.

Ограничения SQL Azure

Что это дает: во-первых, изоляцию данных друг от друга. Данные одного аккаунта никак не связаны с данными другого. Соответственно, применением технологии шардинга мы можем реализовать не только горизонтальное масштабирование базы данных, но и multi-tenant сценарий.

Увеличивается скорость выборки данных из базы, поскольку сам размер хранящихся в конкретном шарде данных на порядок меньше, чем суммарный объем базы. Однако, в любой технологии есть свои недостатки. Шардинг не исключение. Если вспомнить, архитектуру SQL Azure, то как известно сервис не поддерживает выборку данных из нескольких баз данных одновременно. То есть одна база данных — одно соединение. И шарды — не исключение. То есть, если допустим простейший запрос на возврат количества клиентов в базе данных необходимо выполнить на каждом шарде отдельно.

Пример запроса для конкретного шарда:

Логику же суммирования значений, возвращаемых этим запросом необходимо размещать в приложении. То есть в результате использования федераций часть кода «уйдет» в приложение, поскольку на уровне базы данных некоторые возможности обычного SQL Server ограничены.

Конечно SQL Azure Federations не является панацеей и можно реализовать свой принцип горизонтального масштабирования баз данных. Допустим multi-tenant подход — тоже своего рода горизонтальное масштабирование базы данных. Поскольку данные одного пользователя отделены не только «логически» от данных другого пользователя, но и «физически». Если необходимо добавить нового пользователя — мы конфигурируем для него отдельную базу данных. Вопрос в том, что в логике приложения должен быть механизм «роутинга». То есть приложение должно знать с какой базой данных оно в данный момент работает.

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

Серверы баз данных, поддерживающие шардирование:

MongoDB поддерживает шардирование с версии 1.6.

Grails поддерживает шардирование путем Grails Sharding Plugin.

Redis база данных с поддержкой шардирования на стороне клиента.

Microsoft поддерживает шардирование в SQL Azure через «федерации».

Практически любой сервер баз данных может быть использован по схеме шардинга, при реализации соответствующего уровня абстракции на стороне клиента. К примеру eBay применяет серверы Oracle в режиме шардинга[1], Facebook[2] и Twitter[3] применяют шардирование поверх MySQL и т. д.

Источник

Масштабирование базы данных через шардирование и партиционирование

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Масштабирование базы данных через шардирование и партиционирование

Денис Иванов (2ГИС)

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

Немного расскажу о себе — я работаю в команде WebAPI в компании 2GIS, мы предоставляем API для организаций, у нас очень много разных данных, 8 стран, в которых мы работаем, 250 крупных городов, 50 тыс. населенных пунктов. У нас достаточно большая нагрузка — 25 млн. активных пользователей в месяц, и в среднем нагрузка около 2000 RPS идет на API. Все это располагается в трех датацентрах.

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

Я в большей степени расскажу про шардинг. Он бывает вертикальным и горизонтальным. Также бывает такой способ масштабирования как репликация. Доклад «Как устроена MySQL репликация» Андрея Аксенова из Sphinx про это и был. Я эту тему практически не буду освещать.

Перейдем подробнее к теме партицирования (вертикальный шардинг). Как это все выглядит?

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Про репликацию я не буду останавливаться, тут все очень просто.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Перейдем глубже к этой теме, и я расскажу практически все о партицировании на примере Postgres’а.
Давайте рассмотрим простую табличку, наверняка, практически в 99% проектов такая табличка есть — это новости.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

У новости есть идентификатор, есть категория, в которой эта новость расположена, есть автор новости, ее рейтинг и какой-то заголовок — совершенно стандартная таблица, ничего сложного нет.

Как же эту таблицу разделить на несколько? С чего начать?

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

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

В данном случае признак — это category_id=1, т.е. только записи с category_id=1 будут попадать в эту таблицу.
Какие типы проверок бывают для партицированных таблиц?

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

И так просто его сделать можно. Но нельзя. Можно сделать, потому что нам разрешат такое сделать, PostgreSQL поддерживает такое. Как вы видите, у нас в 1-ую партицию попадают данные между 100 и 200, а во 2-ую — между 200 и 300. В какую из этих партиций попадет запись с рейтингом 200? Не известно, как повезет. Поэтому так делать нельзя, нужно указывать строгое значение, т.е. строго в 1-ую партицию будут попадать значения больше 100 и меньше либо равно 200, и во вторую больше 200, но не 200, и меньше либо равно 300.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Также не стоит создавать партиции по разным полям, т.е. что в 1-ую партицию у нас будут попадать записи с category_id=1, а во 2-ую — с рейтингом 100.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Опять же, если нам придет такая запись, в которой category_id = 1 и рейтинг =100, то неизвестно в какую из партиций попадет эта запись. Партицировать стоит по одному признаку, по какому-то одному полю — это очень важно.
Давайте рассмотрим нашу партицию целиком:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Ваша партицированная таблица будет выглядеть вот так, т.е. это таблица news_1 с признаком, что туда будут попадать записи только с category_id = 1, и эта таблица будет унаследована от базовой таблицы news — все очень просто.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Мы на базовую таблицу должны добавить некоторое правило, чтобы, когда мы будем работать с нашей основной таблицей news, вставка на запись с category_id = 1 попала именно в ту партицию, а не в основную. Мы указываем простое правило, называем его как хотим, говорим, что когда данные будут вставляться в news с category_id = 1, вместо этого будем вставлять данные в news_1. Тут тоже все очень просто: по шаблончику оно все меняется и будет замечательно работать. Это правило создается на базовой таблице.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Давайте рассмотрим пример вставки данных:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Данные будем вставлять как обычно, будто у нас обычная большая толстая таблица, т.е. мы вставляем запись с category_id=1 с category_id=2, можем даже вставить данные с category_id=3.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Вот мы выбираем данные, у нас они все есть:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Мы также можем сделать соответствующие запросы в определенные партиции, указывая наше условие, т.е.category_id = 1, или вхождение в числа (2, 3).

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Все будет замечательно работать, все данные будут выбираться. Опять же, несмотря на то, что с партиции с category_id=3 у нас нет.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Здесь можно, как видно на слайде, вставлять данные напрямую в партицию. Можно вставлять данные с помощью правил в основную таблицу, но можно и в саму партицию.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Если мы будем вставлять данные в партицию с каким-то чужеродным условием, например, с category_id = 4, то мы получим ошибку «сюда такие данные нельзя вставлять» — это тоже очень удобно — мы просто будем класть данные только в те партиции, которые нам действительно нужно, и если у нас что-то пойдет не так, мы на уровне базы все это отловим.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

У нас будет Seq Scan по всей таблице целиком, потому что туда данные могут все равно попадать, и будет скан по партиции. Если мы будем указывать условия нескольких категорий, то он будет сканировать только те таблицы, на которые есть условия. Он не будет смотреть в остальные партиции. Так работает оптимизатор — это правильно, и так действительно быстрее.

Мы можем посмотреть, как будет выглядеть explain на самой партиции.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Это будет обычная таблица, просто Seq Scan по ней, ничего сверхъестественного. Точно так же будут работать update’ы и delete’ы. Мы можем update’тить основную таблицу, можем также update’ы слать напрямую в партиции. Так же и delete’ы будут работать. На них нужно так же соответствующие правила создать, как мы создавали с insert’ом, только вместо insert написать update или delete.

Перейдем к такой вещи как Index’ы

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Как мы с этой проблемой боролись у себя. Мы создали замечательную утилиту PartitionMagic, которая позволяет автоматически управлять партициями и не заморачиваться с созданием индексов, триггеров с несуществующими партициями, с какими-то бяками, которые могут происходить. Эта утилита open source’ная, ниже будет ссылка. Мы эту утилиту в виде хранимой процедуры добавляем к нам в базу, она там лежит, не требует дополнительных extension’ов, никаких расширений, ничего пересобирать не нужно, т.е. мы берем PostgreSQL, обычную процедуру, запихиваем в базу и с ней работаем.

Вот та же самая таблица, которую мы рассматривали, ничего нового, все то же самое.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Как же нам запартицировать ее? А просто вот так:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Мы вызываем процедуру, указываем, что таблица будет news, и партицировать будем по category_id. И все дальше будет само работать, нам больше ничего не нужно делать. Мы так же вставляем данные.

У нас тут три записи с category_id =1, две записи с category_id=2, и одна с category_id=3.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

После вставки данные автоматически попадут в нужные партиции, мы можем сделать селекты.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

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

Рассматривать будем такую же структуру с двумя шардами — news_1 и news_2, но это будут разные инстансы, третьим инстансом будет основная база, с которой мы будем работать:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Та же самая таблица:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Единственное, что туда нужно добавить, это CONSTRAINT CHECK, того, что записи будут выпадать только с category_id=1. Так же, как в предыдущем примере, но это не унаследованная таблица, это будет таблица с шардом, которую мы делаем на сервере, который будет выступать шардом с category_id=1. Это нужно запомнить. Единственное, что нужно сделать — это добавить CONSTRAINT.

Мы еще можем дополнительно создать индекс по category_id:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Как настроить шардинг на основном сервере?

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Мы подключаем EXTENSION. EXTENSION идет в Postgres’e из коробки, делается это командой CREATE EXTENSION, называется он postgres_fdw, расшифровывается как foreign data wrapper.

Далее нам нужно завести удаленный сервер, подключить его к основному, мы называем его как угодно, указываем, что этот сервер будет использовать foreign data wrapper, который мы указали.

Таким же образом можно использовать для шарда MySql, Oracle, Mongo… Foreign data wrapper есть для очень многих баз данных, т.е. можно отдельные шарды хранить в разных базах.

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

Далее мы создаем маппинг для пользователя — по этим данным основной сервер будет авторизироваться к дочернему. Мы указываем, что для сервера news_1 будет пользователь postgres, с паролем postgres. И на основную базу данных он будет маппиться как наш user postgres.

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

Далее мы заводим табличку на основном сервере:

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Схема по дефолту — это public, таблицу, которую мы завели, назвали news. Точно так же мы подключаем 2-ую таблицу к основному серверу, т.е. добавляем сервер, добавляем маппинг, создаем таблицу. Все, что осталось — это завести нашу основную таблицу.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Это делается с помощью VIEW, через представление, мы с помощью UNION ALL склеиваем запросы из удаленных таблиц и получаем одну большую толстую таблицу news из удаленных серверов.

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Мы заводим основное правило, которое будет срабатывать, если ни одна проверка не сработала, чтобы не происходило ничего. Т.е. мы указываем DO INSTEAD NOTHING и заводим такие же проверки, как мы делали ранее, но только с указанием нашего условия, т.е. category_id=1 и таблицу, в которую данные вместо этого будут попадать.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Т.е. единственное отличие — это в category_id мы будем указывать имя таблицы. Также посмотрим на вставку данных.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Выбираем данные

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

Обратите внимание на сортировку идентификаторов — у нас сначала выводятся все записи из первого шарда, затем из второго. Это происходит из-за того, что postgres ходит по VIEW последовательно. У нас указаны select’ы через UNION ALL, и он именно так исполняет — посылает запросы на удаленные машины, собирает эти данные и склеивает, и они будут отсортированы по тому принципу, по которому мы эту VIEW создали, по которому тот сервер отдал данные.

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

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

Посмотрим на explain.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

У нас foreign scan по news_1 и foreign scan по news_2, так же, как было с партицированием, только вместо Seq Scan-а у нас foreign scan — это удаленный скан, который выполняется на другом сервере.

Что такое шардирование бд. Смотреть фото Что такое шардирование бд. Смотреть картинку Что такое шардирование бд. Картинка про Что такое шардирование бд. Фото Что такое шардирование бд

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

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *