Масштабування бази даних

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Реплікація

            У веб додатках зазвичай домінують запити на отримання інформації - читання коментарів, постів, призначених для користувача даних і т.д. Таким чином слабким місцем є операція читання і саме її потрібно масштабувати. Для вирішення цього завдання використовується механізм реплікації - один сервер призначається головним (майстер-сервером) і виконує всі запити модифікації даних, а інші сервера (слейв) обробляють тільки запити отримання даних. При зміні або додаванні даних, майстер сервер повідомляє всі слейв сервера, таким чином підтримуючи актуальність даних.

            Крім того, реплікація використовується для географічного розподілу серверів (наприклад один сервер в Америці, інший в Європі).

Принцип роботи реплікації

            Майстер сервер при виконанні модифікацій пише всі зроблені зміни в лог, slave сервера з певною періодичністю перевіряють лог на предмет появи нових даних і якщо вони є - виконують аналогічні дії зі своїми даними.

Реплікаційні схеми

            Схема зазвичай використовується в додатках з домінуючими запитами на читання - всі запити на зміну бази направляються майстер сервером, тоді як запити на читання розподіляються між слейв.

Зазвичай в додатку вказується список серверів (пул) призначених для читання, з якого mysql клієнт деяким чином (випадковим або за вказаною алгоритму) вибирає сервер для виконання запиту, таким чином балансуючи навантаження між усіма серверами.

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

  • Ланцюжок майстер серверів 

            Дуже зручний для географічного розподілу даних. Наприклад, ставимо сервера в Європі, Азії та Америці, налаштовуємо їх в ланцюжок і вчимо додаток вибирати сервер в залежності від регіону. Таким чином отримуємо виграш за рахунок зменшення шляху подорожі запиту до сервера.

            При збільшенні навантаження на один з регіональних серверів до нього запросто можна додати кілька слейв.

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

  • 2 майстри, багато слейв 

            Схема є ланцюжком з двох майстер серверів. Обидва майстри виконують запити на модифікацію даних і мають рівну кількість слейв. Таким чином при виході з ладу одного майстра, додаток продовжить працювати з другим і його слейв.

Розглянемо на прикладі налаштування реплікації між майстром і слейв.

            На слейв потрібно створити користувача, яким він буде авторизуватися на майстер. Бажано створити аналогічного користувача й на майстрі, на випадок якщо він вийде з ладу і доведеться зробити слейв майстром, а майстер, після виправлення помилки, слейв.

CREATE USER 'repl' @ '%' IDENTIFIED BY 'replpass';

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *. * TO repl @ '%';

            Кожен сервер в реплікаційній схемі повинен мати унікальний номер (ціле число), яке потрібно прописати в my.cnf в секції [mysqld].

Наприклад для майстра:

server-id = 1

Для слейв:

server-id = 2

Крім того, на майстра потрібно включити лог, для чого туди ж вписуємо:

log-bin

            Рестартуємо обидва сервера, після чого майстер вже готовий до роботи, а слейв потрібно вказати хто його майстер, для цього:

CHANGE MASTER TO MASTER_HOST = 'master.example.com', MASTER_USER = 'repl', MASTER_PASSWORD = 'replpass';

START SLAVE;

Все, реплікація між серверами налаштована, тепер після виконання запиту модифікації на майстра, дані оновляться і на слейв. Просто і сердито.

            Якщо реплікацію потрібно налаштувати для вже існуючої бази, перед запуском обидва сервера повинні мати однакові дані.

Партіціонірованіе

            Іноді зустрічаються таблиці з деяким логічним угрупованням даних, наприклад, список покупок користувача або лог дій можна згрупувати за датою. І коли більшість запитів працює з групами (наприклад, цікавить тільки статистика за рік), тоді є сенс зберігати дані розбиті на групи безпосередньо в БД. Процес поділу даних і зберігання їх у вигляді деяких груп і називається партіціонірованіем.

Розглянемо на прикладі таблиці:

CREATE TABLE employees (

    id INT NOT NULL,

    fname VARCHAR (30),

    lname VARCHAR (30),

    hired DATE NOT NULL DEFAULT '1970-01-01',

    separated DATE NOT NULL DEFAULT '9999-12-31',

    job_code INT NOT NULL,

    store_id INT NOT NULL

)

4 типи партіціонірованія:

  • За діапазону

Кожне розбиття містить дані, які належать зазначеному діапазону значень колонки.

PARTITION BY RANGE (store_id) (

    PARTITION p0 VALUES LESS THAN (6),

    PARTITION p1 VALUES LESS THAN (11),

    PARTITION p2 VALUES LESS THAN (16),

    PARTITION p3 VALUES LESS THAN (21)

);

У партіціі p0 потраплять всі рядки в яких store_id <6.

  • За списком значень

Кожне розбиття містить дані, які мають певне значення в колонці.

PARTITION BY LIST (store_id) (

    PARTITION pNorth VALUES IN (3,5,6,9,17),

    PARTITION pEast VALUES IN (1,2,10,11,19,20),

         PARTITION pWest VALUES IN (4,12,13,14,18),

     PARTITION pCentral VALUES IN (7,8,15,16)

);

Наприклад в партіціі pNorth потраплять всі рядки в яких store_id = 3, 5, 6, 9, 17.

  • За хешу

Таблиця розбивається по хешу значення деякої колонки.

  • За ключем

Аналогічно до попереднього методу, але по ключу.

Останні два методи не дають можливості вказати в яку з партіцій потрапить рядок, а тільки кількість партіцій, механізм розподілу MySQL бере на себе.

Партіціі можна розбивати на подпартіціі, які можна далі партіціоніровать і т.д.

При цьому при складанні запиту не потрібно думати де і в якому вигляді зберігаються дані, просто пишемо запит до таблиці employees, а MySQL визначить для яких партіцій його потрібно виконати.

У реальному житті партіціі використовуються не часто, тому, що в більшості випадків індексу досить, але все ж потрібно пам'ятати про їх існування.

Шардінг

Шардінг - розвиток партіціонірованія - розбиття даних на групи і зберігання будь-якої групи на окремому сервері (Шарден). В цьому випадку група не обов'язково включає одну таблицю, це може бути кілька таблиць, які містять одне ціле. Наприклад, маючи багато зареєстрованих користувачів, дані яких лежать в декількох таблицях (реєстраційні дані, історія покупок, лог дій), на кожній Шардена буде зберігатися повна інфраструктура (всі таблиці), але з даними тільки тих, хто поточної Шарден (наприклад одна Шарда - користувачі з прізвищами від А до Д, друга Д-К і т.д).

MySQL не підтримує автоматичного шардінга, тому його доводиться робити на рівні додатку, вибираючи в залежності від запиту до сервера. Зазвичай створюється параметризовані пул серверів (в прикладі вище таким параметром була б перша буква прізвища) і при виконанні кожного запиту, за цим параметром вибирається потрібний сервер.

Шардінг це остання міра масштабування (коли реплікація вже не рятує), не тільки через складність реалізації, а й через ускладнення роботи з даними. Оскільки робота з Шардена відбувається на рівні додатку, ми автоматично відмовляємося від тригерів, збережених процедур і інших вбудованих в БД можливостей, які повинні працювати з усіма даними, оскільки на рівні БД кожної Шардена існує тільки її набір даних і вона нічого не знає про інших.

Тому перед тим, як впроваджувати MySQL шардінг, потрібно дуже добре подумати і бути точно впевненим, що іншого шляху немає.