PgPool-II: що ламається при відмові вузла бази даних
Основний вузол бази перестає відповідати в найневдаліший момент — наприклад, уночі, коли черговий інженер дізнається про це із системи оповіщень.
Застосунок у цей момент тримає відкриті з'єднання до вузла, що відмовив, а не до резерву: пул ще не перебудований, маршрутизація не перемкнута. Записи та замовлення починають падати з помилкою з'єднання, а необроблені запити накопичуються в черзі.
Далі починається ручна робота. Резервний вузол потрібно перевести в режим запису, перемкнути на нього трафік, переконатися, що репліка наздогнала основний за журналом, і лише потім повернути застосунок до роботи.
Поки це відбувається, частина запитів губиться безповоротно — їх ніхто не переграє, бо черга вже розійшлася по клієнтах і розпалася на рівні з'єднання.
PgPool-II ставиться між застосунком і базою саме для того, щоб цей сценарій не розгортався вручну. Він тримає власний пул з'єднань, періодичними перевірками стежить за станом вузлів і при відмові сам виключає вузол, що впав, з маршрутизації, а резервний переводить у режим запису.
Застосунок продовжує отримувати з'єднання з пулу — для сервісу змінюється адреса призначення, а не сам факт доступності бази.
Але присутність PgPool-II у схемі сама по собі не прибирає точку відмови. Якщо він запущений в одному екземплярі, без резервування самого пулу і без вивірених таймаутів перевірки, відмова просто переїжджає з бази на нього. Нижче розбираємо, як це закривається.
Що дає відмовостійкий кластер баз даних
Відмовостійкість проявляється не в спокійній роботі, а в перші секунди після збою. Тому дивимося не на заявлену підтримку реплікації, а на шкалу часу: як швидко балансувальник помічає вузол, що впав, хто перемикає трафік і що в цей момент бачить застосунок.
Застосунок підключається до однієї адреси, а PgPool-II розподіляє вхідні з'єднання між серверами. Перевірка доступності йде з коротким інтервалом: після кількох невдалих відгуків вузол виключається з видачі, решта приймають його трафік.
Помилок з'єднання на боці застосунку немає — змінюється лише внутрішня маршрутизація, а час відновлення вимірюється секундами замість ручного розбору.
Далі вмикається розділення читання і запису: запити на вибірку йдуть на репліки, змінювальні — на основний вузол. Застосунок про це не знає, рядок підключення і код залишаються попередніми.
На типовому навантаженні на репліки йде до двох третин звернень, і основний вузол перестає бути єдиною точкою і за навантаженням, і за відмовами.
Передбачуваність тут важливіша за пікову продуктивність. Деградація одного вузла перетворюється на подію з відомим сценарієм: частина запитів сповільнюється, але сервіс залишається доступним.
Клас відмов «упав сервер — лежить весь продукт» зникає з переліку ризиків, а поведінка кластера перевіряється на навчаннях, а не з'ясовується в момент реальної аварії.
Режими роботи PgPool-II та їхні обмеження
Відмовостійкий контур на PgPool-II збирають кількома способами, і балансувальник потрібен не завжди. Ключове питання — що саме потрібно: переживати відмову основного вузла, розподіляти читаюче навантаження або гасити сплески коротких підключень. Від цього залежить, де стане PostgreSQL, а де — проміжний шар.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Потокова реплікація гарячого резерву без балансувальника | Один основний вузол і резерв, читання з резерву, перемикання за регламентом | Автоматичного перемикання при відмові немає; адреси вузлів прописані в конфігурації застосунку |
| PgPool-II у режимі реплікації запитів | Єдина адреса для застосунку та автоматичне перемикання при відмові | Без сторожового модуля можливе розщеплення кластера при обриві зв'язку; читання з реплік відстає |
| PgPool-II як балансувальник з'єднань | Багато коротких підключень, сплески, жорсткий ліміт з'єднань на сервері | Відмовостійкості не дає — лише утримання й перерозподіл з'єднань |
| Логічна реплікація вибіркових таблиць | Перенесення між мажорними версіями, винесення частини даних на окремий контур | Немає автоматичного перемикання, затримка вища, склад об'єктів має збігатися |
Що перевірити перед вибором
Режим реплікації запитів не знімає обмежень самої СУБД: запити, чутливі до актуальності даних, маршрутизуються на основний вузол, а розширення мають стояти на всіх вузлах.
Сумісність перевіряють на піковому навантаженні — затримку реплікації, поведінку при обриві каналу і коректне повернення старого основного вузла в стрій.
Як ми впроваджуємо відмовостійкий кластер: етапи робіт
Кластер високої доступності збирається не «на живу», а за послідовністю, де кожен крок підтверджується перевіркою. Нижче — порядок робіт, за яким ми ведемо проєкт: від аудиту до передачі зміні замовника. На кожному етапі видно, що вже зроблено, чим це перевірено і які ризики залишилися відкритими.
- Аудит поточної схеми та точок відмови. Розбираємо контур як є: де проходить запис, хто тримає з'єднання, як влаштована реплікація. Виписуємо одиничні точки — один вузол запису, балансувальник без резерву, ручне переведення при збої — і оцінюємо ціну простою кожної.
- Проєктування контуру. Фіксуємо ролі вузлів (ведучий, резервний, вузли читання), схему потоків даних між PgPool-II, серверами баз і застосунками, правила маршрутизації запитів на читання і запис, режим розподілу навантаження.
- Налаштування вузлів і перевірка перемикання. Піднімаємо пул з'єднань, реплікацію, перевірки живучості й автоматичне перемикання ролей. Окремо перевіряємо, що застосунок переживає зміну ведучого вузла без правок у коді.
- Випробування відмовою на стенді. По черзі виводимо з ладу кожен вузол і зв'язок між майданчиками: дивимося час перемикання, поведінку черги запитів і те, які транзакції губляться, а які ні.
- Прогін під навантаженням. Подаємо профіль, близький до робочого: пікові з'єднання, важкі звіти, довгі транзакції. Перевіряємо, що перемикання вкладається в узгоджене вікно і під навантаженням.
- Передача в експлуатацію та навчання зміни. Віддаємо конфігурації, схему ролей і потоків, регламент перемикання і розбору збоїв. Проводимо навчання зі зміною замовника, щоб переведення вузлів робилося за інструкцією, а не з пам'яті.
Конфігурації, схеми та регламенти: артефакти впровадження
Впровадження вважається закритим не коли вузли піднялися, а коли в замовника залишається комплект артефактів, за яким контур можна супроводжувати власними силами. Частина файлів іде в репозиторій конфігурацій, частина — у базу знань чергової зміни. Нижче — що саме передаємо.
- Робочі конфігурації відмовостійкого контуру — файли PgPool-II, вузлів реплікації і менеджера кластера з параметрами під ваш профіль навантаження, а не демонстраційні. Зберігаються під контролем версій, щоб налаштування можна було відкотити, а не відновлювати з пам'яті.
- Схема контуру — актуальна топологія: ролі вузлів, маршрути трафіку, точки відмови та порядок їх проходження. Оновлюється при кожній зміні, а не живе в голові одного інженера.
- Правила доступу та ролі — матриця прав на вузли, режимні функції балансувальника і моніторинг; окремі облікові записи для чергового і для автоматизації, розділення читання і зміни.
- Регламент перемикання — покроковий сценарій планового й аварійного переведення ролей, з очікуваним часом, критеріями «пора втручатися» і порядком повернення вузлів у стрій.
- Інструкція з відновлення вузла — що робити при відставанні або випадінні репліки: перевірка синхронності, умови догону без повного перестворення, команди для типових збоїв.
- Спостережуваність і оповіщення про збої — набір метрик (відставання реплік, стан вузлів, частка помилок маршрутизації) з порогами, за яких черговий отримує сигнал, а не дізнається про збій із скарг.
- Записи навчань — фактичний час відновлення за підсумками тренувань і список правок, внесених до регламенту після кожного.
Кейс: простій при відмові вузла скоротився в рази
Вихідна схема та її слабкі місця
Сервіс з постійним потоком записів тримався на одному основному вузлі та гарячому резерві, а перемикання виконував черговий інженер вручну.
При відмові основного вузла застосунок отримував помилки запису, поки резерв не піднімали і не перенаправляли трафік: простій сягав десятків хвилин, а частину незавершених транзакцій розбирали і повторювали руками.
Слабке місце було не в самому резерві, а у відсутності автоматичного арбітра — рішення про перехід ухвалювала людина за непрямими ознаками і з затримкою.
Що змінили і що показали метрики
Перед кластером поставили PgPool-II: він тримає пул з'єднань, періодично опитує вузли і сам ініціює перемикання на резерв, коли основний перестає відповідати.
Частка автоматичних перемикань зросла з нуля майже до всіх відмов, які фіксує моніторинг; ручний розбір залишився лише для сценаріїв із втратою мережі між вузлами, де потрібне усвідомлене рішення.
Простій при відмові вузла скоротився в рази: перемикання вкладається в секунди, застосунок перепідключається до нового основного вузла, а не чекає інженера.
Пул з'єднань зняв навантаження на базу під піками — застосунок більше не відкриває лавину нових підключень на кожен сплеск, і черга запитів перестала впиратися в ліміт з'єднань.
Чим відрізняється балансування з'єднань від реплікації
Реплікація і балансування вирішують різні задачі, і плутати їх дорого. Реплікація відповідає за те, щоб копія даних існувала на іншому вузлі: основний вузол передає зміни потоком, резервний застосовує їх і доступний лише на читання.
Балансування відповідає за маршрут запиту — на який вузол він піде і що станеться з ним у момент відмови.
Налаштувавши потокову реплікацію, навантаження читання ви не розподілите. Репліка отримує ті самі дані, але застосунок звертається до основного вузла, поки між ним і базами немає маршрутизатора.
PgPool-II працює тут: розбирає запит, зміни надсилає на основний вузол, читання розкладає по репліках і тримає пул з'єднань.
Схему вибирають за профілем навантаження. Якщо переважають записи, репліки основний вузол не розвантажать — вони лише повторюють зміни.
Якщо домінує читання, розподіл запитів читання знімає з основного вузла помітну частку звернень, але застосунок має миритися з відставанням репліки.
Звідси головний ризик: поки вузли розходяться, репліка віддає застарілі дані — користувач не бачить щойно збереженого запису. Зворотна помилка гірша: зміна йде на вузол, який маршрутизатор помилково вважає основним.
Тоді розходяться вже самі вузли, і це не лікується перезапуском. Тому поруч із балансуванням ідуть перевірки стану вузлів, автоматичне перемикання на резервний і захист від розщеплення кластера.
Що робити при відставанні — чекати, виключати репліку з розподілу або переводити читання на основний вузол — вирішують заздалегідь.
Технічні сумніви перед впровадженням: розбір
Перед впровадженням PgPool-II у команди спливають одні й ті самі сумніви: чи доведеться правити застосунок, чи потрібен простій, чи спрацює автоматичне перемикання, що робити при розходженні даних.
Застосунок доведеться переписувати?
Ні. PgPool-II стає між застосунком і кластером і говорить тією ж протоколою, що й звичайний сервер баз даних. Змінюється лише рядок підключення — драйвери та бібліотеки доступу до даних продовжують працювати. Точково перевіряємо запити, зав'язані на одному вузлі: послідовності та серверні курсори.
Впровадження на працюючому кластері — це простій?
Простій не потрібен. PgPool-II піднімається поруч із поточним кластером; спочатку переводимо на нього читання і дивимося поведінку під навантаженням, запис — останнім. На це потрібна пауза в секунди, щоб закрилися відкриті транзакції. Відкат — повернення застосунків на попередній рядок підключення.
Як перевірити автоматичне перемикання?
На стенді, наближеному до бойового: зупиняємо основний вузол і фіксуємо час до переведення репліки в основний, число втрачених транзакцій, поведінку застосунку при розриві з'єднання. Потім повторюємо на репетиції бойового контуру — зі звітом і логами.
Що буде при розходженні даних?
PgPool-II стежить за відставанням реплік: при перевищенні порогу вузол виключається з видачі читання — застосунок не отримує застарілі дані. Вузол, що випав після збою, перезбирається з копії основного.
Затримка реплікації, доступність і зміна ролі виводяться на панель моніторингу: алерт приходить раніше, ніж проблему помітять користувачі.
Обговоримо задачу і повернемося з планом робіт
Щоб оцінка спиралася на факти, а не на припущення, для старту достатньо опису поточної схеми і характеру навантаження. Ми розберемо, де зараз точка відмови, як розподіляються читання і запис між вузлами і чи готова єдина точка входу для застосунків.
Від замовника потрібно небагато:
- Схема контуру: число вузлів PostgreSQL, наявність реплік, режим реплікації, хто зараз керує зміною ролі основного вузла.
- Профіль навантаження: частка читання і запису, пікові періоди, вимоги до часу відповіді на запит.
- Поведінка застосунків: як переживають розрив з'єднання, чи використовують єдину адресу підключення, чи готові коректно повторити запит після перемикання.
- Парк з'єднань: скільки клієнтів підключається одночасно і чи є пул на боці застосунку.
- Вимоги до відмови: допустимий час недоступності на запис і на читання, чи потрібне автоматичне повернення ролі на попередній вузол.
- Регламенти: вікно обслуговування, доступи до серверів і до систем моніторингу.
За підсумками обговорення надсилаємо план впровадження: склад і порядок робіт, етапність (підготовка вузлів, увімкнення розподілу читання, перевірка перемикання ролі, навантажувальна перевірка), критерії приймання і порядок передачі із супроводом. Опишіть задачу — повернемося з оцінкою та планом.







