(На основі https://ruhighload.com/)
Масштабування баз даних - найскладніше завдання під час росту проекту. 90% всіх зусиль зазвичай припадає саме на роботу, пов'язану з ростом обсягу даних і операцій з ними.
Класична схема роботи програми з базою даних виглядає так:
Один сервер бази даних в якийсь момент перестає справлятися з навантаженням. У цей момент слід застосовувати описані тут техніки масштабування.
Перед тим, як приступати до масштабування, необхідно провести аналіз повільних запитів і переконатися, що сервер MySQL налаштований оптимально.
Cтратегії.
В основі масштабування даних лежить той же принцип, що і в основі масштабування Web додатків. Це поділ даних на групи і виділення їх на окремі сервера. Існує дві основні стратегії - реплікація і шардінг.
Реплікація
Реплікація дозволяє створити повний дублікат бази даних. Так, замість одного сервера у Вас їх буде кілька:
Найчастіше використовують схему master-slave:
Реплікація дозволяє використовувати два або більше однакових серверів замість одного. Операцій читання (SELECT) даних часто набагато більше, ніж операцій зміни даних (INSERT/UPDATE). Тому, реплікація дозволяє розвантажити основний сервер за рахунок перенесення операцій читання на слейв.
Робота з програми
У додатку у Вас має бути два з'єднання з базою даних. Одне - для майстра і одне для слейв:
<? $Master = mysql_connect ('10 .10.0.1 ',' root ',' pwd '); $Slave = mysql_connect ('10 .10.0.2 ',' root ',' pwd '); <Коди> $q = mysql_query ( 'INSERT INTO users ....', $Master); <Коди> $q = mysql_query ( 'SELECT FROM users WHERE ....', $Slave); <Коди>
При виконанні запитів необхідно використовувати відповідне з'єднання.
Реплікація зазвичай підтримується самою СУБД (наприклад, MySQL) і налаштовується незалежно від програми.
Слід зазначити, що реплікація сама по собі не дуже зручний механізм масштабування.
Причиною є – порушення синхронізації даних і затримки в копіюванні з майстра на слейв. Зате це відмінний засіб для забезпечення відмовостійкості. Ви завжди можете переключитися на слейв, якщо майстер ламається і навпаки. Найчастіше реплікація використовується спільно з шардінгом саме з міркувань надійності.
Шардінг (sharding)
Шардінг (іноді шардірування) – це інша техніка масштабування роботи з даними. Суть його полягає в поділі бази даних на окремі частини (partition, секціювання) так, щоб кожну з них можна було винести на окремий сервер. Цей процес залежить від структури бази даних і виконується прямо в додатку на відміну від реплікації.
Вертикальний шардінг
Вертикальний шардінг - це виділення таблиці або групи таблиць на окремий сервер. Наприклад, в додатку є такі таблиці:
Таблицю users Ви залишаєте на одному сервері, а таблиці photos і albums переносите на інший. В такому випадку в додатку Вам необхідно буде використовувати відповідне з'єднання для роботи з кожною таблицею:
<? $users_connection = mysql_connect ('10 .10.0.1 ',' root ',' pwd '); $photos_connection = mysql_connect ('10 .10.0.2 ',' root ',' pwd '; <коди> $q = mysql_query ( 'SELECT * FROM users WHERE ...', $users_connection); <коди> $q = mysql_query ( 'SELECT * FROM photos WHERE ...', $photos_connection); <коди> $q = mysql_query ( 'SELECT * FROM albums WHERE ...', $photos_connection);
Для кожної таблиці або групи таблиць буде окреме з'єднання. На відміну від реплікації, ми використовуємо різні з'єднання для будь-яких операцій, але з певними таблицями.
Горизонтальний шардінг
Горизонтальний шардінг – це поділ однієї таблиці і розміщення їх на різні сервери. Це необхідно використовувати для величезних таблиць, які не поміщаються на одному сервері. Поділ таблиці на частини робиться за таким принципом:
Припустимо, наш додаток працює з величезною таблицею, яка зберігає фотографії користувачів. Ми підготували два сервера (зазвичай вони називаються шардами) для цієї таблиці.
Для непарних користувачів ми будемо працювати з першим сервером, а для парних – з другим. Таким чином, на кожному з серверів буде тільки частина всіх даних про фотографії користувачів. Це буде виглядати так:
<? # Список з'єднань для таблиці з фотками $photo_connections = [ '1' => '10 .10.0.1 ', '2' => '10 .10.0.2 ', ] $user_id = $ _SESSION [ 'user_id']; # Отримання фотографій для користувача $user_i $connection_num = $user_id% 2 == 0? 1: 2; $connection = mysql_connect ($photo_connections [$connection_num],'root', 'pwd'); $q = mysql_query ( 'SELECT * FROM photos WHREE user_id ='. Intval ($user_id), $connection); # Перед зверненням до таблиці, ми вибираємо потрібне нам з'єднання.
Результат цієї операції $user_id% 2 буде залишком від ділення на 2. Тобто для парних чисел - 0, а для непарних - 1.
Будь-яка робота з таблицею photos тепер буде відбуватися тільки після отримання потрібного з'єднання на основі $user_id.
Горизонтальний шардінг – це дуже потужний інструмент масштабування даних. Але в той же час і дуже нетривіальний.
Не слід застосовувати техніку шардінга до всіх таблиць.
Правильний підхід - це поетапний процес поділу зростаючих таблиць. Слід замислюватися про горизонтальний шардінг, коли кількість рядків в одній таблиці переходить за межі від кількох десятків мільйонів до сотень мільйонів.
Спільне використання
Шардінг і реплікація часто використовуються спільно. У нашому прикладі, ми могли б використовувати по два сервера на кожен шард таблиці:
Тоді в додатку робота з цією таблицею може виглядати так:
<? # Список з'єднань, для кожного шарда - майстер і слейв $photo_connections = [ '1' => [ 'Master' => '10 .10.0.10 ', 'Slave' => '10 .10.0.11 ', ], '2' => [ 'Master' => '10 .10.0.20 ', 'Slave' => '10 .10.0.21 ', ], ]; $user_id = $ _SESSION [ 'user_id']; # Читаємо дані з слейв $connection_num = $user_id% 2 == 0? 1: 2; $connection = mysql_connect ($photo_connections [$connection_num] [ 'slave'], 'root', 'pwd'); $q = mysql_query ( 'SELECT * FROM photos WHREE user_id ='. Intval ($user_id), $connection); <Коди> # Зміна даних відбувається на майстрах $photo_id = 7; $connection_num = $user_id% 2 == 0? 1: 2; $connection = mysql_connect ($photo_connections [$connection_num] [ 'master'], 'root', 'pwd'); $q = mysql_query ( 'UPDATE photos SET views = views + 1 WHREE photo_id ='. Intval ($photo_id), $connection); # Читаємо дані з слейв, а записуємо на майстер-сервер/
Така схема часто використовується не для масштабування, а для забезпечення відмовостійкості. Так, при виході з ладу одного з серверів шардена, інший завжди буде запасний.
Пам'ятайте. Шардінг і реплікація - це популярні і потужні техніки масштабування систем роботи з даними. Незважаючи на приклади для MySQL, ці підходи є універсальними і можуть застосовуватися для будь-якої технології. Процес масштабування даних - це архітектурне рішення, воно не пов'язане з конкретною технологією. Проблеми зазвичай пов'язані з архітектурою, а не конкретною базою даних.