Orchestrator для MySQL: чому без нього не можна будувати відмово проект

Будь-який великий проект починався з кількох серверів. Спочатку був один DB-сервер, потім до нього додалися слейви, щоб масштабувати читання. І тут – стоп! Майстер один, а слейв багато; якщо піде один із слейвів, то все буде добре, а якщо піде майстер - буде погано: даунтайм, адміни в милі піднімають сервер. Що робити? Резервувати майстер. Мій колега Павло вже писав про це статтю, Я не буду її повторювати. Натомість розповім, чому вам обов'язково потрібен Orchestrator для MySQL!

Почнемо з головного питання: «Як ми перемикатимемо код на нову машину при догляді майстра?».

  • Схема з VIP (Virtual IP) мені подобається найбільше, про неї ми поговоримо нижче. Вона найпростіша і очевидніша, хоча має явне обмеження: майстер, який ми резервуватимемо, повинен перебувати в L2-сегменті з новою машиною, тобто про друге ДЦ можна забути. Та й, по-хорошому, якщо дотримуватися правила, що великий L2 - це зло, тому що L2 тільки на стійку, а між стійками L3, а така схема має ще більше обмежень.
  • Можна прописати в коді DNS-ім'я та налаштувати його через /etc/hosts. Насправді резолву не буде. Гідність схеми: немає обмеження, характерного для першого способу, тобто можна і cross-ДЦ організувати. Але тоді виникає очевидне питання, як швидко ми через Puppet-Ansible підвеземо зміну /etc/hosts.
  • Можна другий спосіб трохи змінити: на всіх веб-серверах ставимо кешуючий DNS, через який код ходитиме в майстер-базу. Можна прописати TTL 60 для цього запису в DNS. Здається, що з правильної реалізації спосіб хороший.
  • Схема з service discovery, що передбачає застосування Consul та etcd.
  • Цікавий варіант з ProxySQL. Потрібно весь трафік на MySQL загорнути через ProxySQL, ProxySQL сам вміє визначати, хто зараз майстер. До речі про один із варіантів використання даного продукту можна прочитати в моїй статті.

Автор Orchestrator, працюючи у Github, спочатку реалізував першу схему з VIP, а потім переробив на схему c consul.

Типова схема інфраструктури:

Orchestrator для MySQL: чому без нього не можна будувати відмово проект
Відразу опишу очевидні ситуації, які потрібно врахувати:

  • VIP-адреса не повинна бути прописана в конфізі на жодному з серверів. Уявімо ситуацію: майстер перезавантажився, а поки він вантажиться, Orchestrator перейшов у режим failover і зробив майстром один із слейвів; потім піднявся старий майстер і тепер VIP на двох машинах. Це погано.
  • Для оркестратора потрібно буде написати скрипт звернення до старого майстра та нового майстра. На старому необхідно виконувати ifdown, а на новому майстрі – ifup vip. Добре було б ще в цей скрипт вписати, що у випадку failover порт на комутаторі старого майстра просто гаситься, щоб уникнути будь-якого splitbrain.
  • Після того, як Orchestrator викликав ваш скрипт, щоб спочатку зняти VIP та/або згасити порт на комутаторі, а потім на новому майстрі викликав скрипт підняття VIP, не забудьте командою arping сказати всім, що новий VIP тепер тут.
  • На всіх слейвах має бути read_only = 1, а як тільки промоутувати слейв до майстра, у нього має стати read_only = 0.
  • Не забувайте, що майстром може стати будь-який слейв, який ми вибрали для цього (у Orchestrator є цілий механізм переваги, який слейв розглянути кандидатом на новий майстер насамперед, який у другу, а який слейв взагалі ні за яких обставин не повинен бути обраний майстром). Якщо слейв стане майстром, на ньому залишиться навантаження слейва і додасться навантаження майстра, це потрібно враховувати.

Чому ж вам обов'язково потрібен Orchestrator, якщо у вас його немає?

  • Orchestrator має дуже зручний графічний інтерфейс, що відображає всю топологію (дивіться скріншот нижче).
  • Orchestrator може відстежувати, які відстали слейви, а де реплікація взагалі зламалася (у нас до Orchestrator прикручені скрипти для відправки SMS).
  • Orchestrator говорить вам, на яких слейв є помилка GTID errant.

Інтерфейс Orchestrator:

Orchestrator для MySQL: чому без нього не можна будувати відмово проект
Що таке GTID errant?

Є дві основні вимоги для роботи Orchestrator:

  • Потрібно, щоб на всіх машинах MySQL кластера був включений pseudo GTID, у нас включений GTID.
  • Потрібно, щоб скрізь був один тип бінлогів, можна стати. У нас була така конфігурація, при якій на майстрі та більшості слейвів був Row, а на двох історично залишився режим Mixed. В результаті ці слейви Orchestrator просто не захотів підключати до нового майстра.

Пам'ятайте, що найголовніше в production-слейві – його консистентність із майстром! Якщо у вас і на майстрі, і на слейв включений Global Transaction ID (GTID), то через функцію gtid_subset можна дізнатися, чи дійсно на цих машинах виконані ті самі запити на зміни даних. Детальніше про це можна почитати можна тут.

Таким чином, Orchestrator показує через помилку GTID errant, що на слейві є транзакції, яких немає на майстрі. Чому так відбувається?

  • На слейві не включений read_only=1, хтось підключився та виконав запит на зміну даних.
  • На слейве не включений super_read_only=1, тоді адмін, переплутавши сервер, зайшов і виконав запит.
  • Якщо ви врахували обидва попередні пункти, то є ще одна хитрість: у MySQL запит про flush бінлог теж потрапляє в бінлог, тому при першому ж flush на майстрі і на всіх слейвах з'явиться GTID errant. Як цього уникнути? У perona-5.7.25-28 з'явилося налаштування binlog_skip_flush_commands=1, що забороняє писати flush у бінлоги. На сайті mysql.com є заведений баг.

Резюмую все сказане вище. Якщо ви не хочете використовувати Orchestrator в режимі failover, то поставте його в режимі спостереження. Тоді у вас завжди буде перед очима карта взаємодії MySQL-машин і наочна інформація про те, який тип реплікації на кожній машині, чи відстають слейви, і найголовніше - наскільки вони консистентності з майстром!

Очевидне питання: «А як же має працювати Orchestrator?». Він повинен вибрати новий майстер із поточних слейвів, а потім перепідключити до нього всі слейви (саме для цього потрібен GTID; якщо використовувати старий механізм з binlog_name та binlog_pos, то перемикання слейва з поточного майстра на новий просто неможливо!). До того, як у нас з'явився Orchestrator, мені одного разу довелося робити все це вручну. Старий майстер зависав через глючний контролер Adaptec, у нього було близько 10 слейвів. Мені потрібно було перекинути VIP з майстра на один із слейвів і перепідключити на нього всі інші слейви. Скільки ж консолей мені довелося відкрити, скільки одночасних команд ввести… Довелося почекати до 3 години ночі, зняти навантаження з усіх слейвів, крім двох, зробити майстром першу машину з двох, одразу до неї підчепити другу машину, тому до нового майстра підчепити всі інші слейви та повернути навантаження. Загалом жах…

Як працює Orchestrator, коли переходить у режим failover? Це найлегше показати на прикладі ситуації, коли ми хочемо зробити майстром потужнішу, сучаснішу машину, ніж зараз.

Orchestrator для MySQL: чому без нього не можна будувати відмово проект
На малюнку представлено середину процесу. Що вже було зроблено досі? Ми сказали, що хочемо зробити якийсь слейв новим майстром, Orchestrator почав просто перепідключати до нього всі інші слейви, при цьому новий майстер виконує роль транзитної машини. За такої схеми помилок не виникає, всі слейви працюють, Orchestrator знімає VIP зі старого майстра, переносить на новий, робить read_only=0 і забуває про старого майстра. Всі! Даунтайм нашого сервісу – час переносу VIP, це 2-3 секунди.

На сьогодні все, дякую всім. Незабаром буде друга стаття про Orchestrator. У відомому радянському фільмі "Гараж" один герой сказав: "Я з ним би в розвідку не пішов!" Так ось, Orchestrator, я б з тобою в розвідку пішов!

Джерело: habr.com

Додати коментар або відгук