
Bugungi kunda xizmatlarning yuqori mavjudligi nafaqat yirik qimmat loyihalarda, balki har doim va hamma joyda talab qilinadi. “Kechirasiz, texnik xizmat koʻrsatilmoqda” xabari boʻlgan vaqtincha mavjud boʻlmagan saytlar hali ham uchrab turadi, lekin odatda kamsituvchi tabassumga sabab boʻladi. Keling, bulutlarda hayotni qo'shaylik, qo'shimcha serverni ishga tushirish uchun APIga faqat bitta qo'ng'iroq kerak bo'lganda va "temir" operatsiyasi haqida o'ylashning hojati yo'q. Va endi tanqidiy tizim nima uchun klaster texnologiyalari va ortiqcha ishlov berishdan foydalangan holda ishonchli tarzda yaratilmaganiga hech qanday bahona yo'q.
Sizga xizmatlarimizdagi ma'lumotlar bazalarining ishonchliligini ta'minlash uchun qanday echimlarni ko'rib chiqqanimiz va biz nimani o'ylab topganimizni aytib beramiz. Bundan tashqari, keng qamrovli xulosalar bilan demo.
Yuqori darajadagi arxitekturadagi meros
Bu turli xil ochiq kodli tizimlarning rivojlanishi kontekstida yanada yaxshi ko'rinadi. Eski yechimlar talab ortishi bilan yuqori darajadagi texnologiyalarni qo'shishi kerak edi. Va ularning sifati har xil edi. Keyingi avlod echimlari o'z arxitekturasining asosiga yuqori mavjudlikni qo'yadi. Masalan, MongoDB klasterni asosiy foydalanish holati sifatida joylashtiradi. Klaster gorizontal ravishda kengaytiriladi, bu esa ushbu DBMSning kuchli raqobatdosh ustunligidir.
Keling, PostgreSQL-ga qaytaylik. Bu eng qadimgi mashhur ochiq kodli loyihalardan biri bo'lib, uning birinchi chiqarilishi o'tgan asrning 95-yillarida bo'lib o'tgan. Loyiha jamoasi uzoq vaqt davomida yuqori darajadagi mavjudlikni tizim tomonidan hal qilinishi kerak bo'lgan vazifa deb hisoblamadi. Shu sababli, ma'lumotlar nusxalarini yaratish uchun replikatsiya texnologiyasi 8.2 yilda faqat 2006 versiyasida o'rnatilgan bo'ldi, lekin bu fayl (jurnalni jo'natish) edi. 2010 yilda oqimli replikatsiya 9.0 versiyasida paydo bo'ldi va u turli xil klasterlarni yaratish uchun asos bo'ldi. Bu, aslida, Enterprise SQL yoki zamonaviy NoSQL-dan keyin PostgreSQL bilan tanishadigan odamlar uchun juda hayratlanarli - hamjamiyatning standart yechimi oddiygina sinxron yoki asinxron replikatsiyaga ega master-replika juftligidir. Shu bilan birga, drenajda usta qo'lda almashtiriladi va mijozlarni almashtirish masalasi ham mustaqil ravishda hal qilinishi taklif etiladi.
Qanday qilib biz ishonchli PostgreSQL yaratishga qaror qildik va buning uchun nimani tanladik
Biroq, PostgreSQL doimiy e'tiborni talab qilmaydigan nosozliklarga chidamli yechim yaratishga yordam beradigan ko'plab loyihalar va vositalar bo'lmaganida bunchalik mashhur bo'lmagan bo'lardi. Bulutda (MCS) DBaaS ishga tushirilgandan beri yagona PostgreSQL serverlari va asinxron replikatsiyaga ega master-replika juftliklari mavjud edi.
Tabiiyki, biz hamma uchun hayotni osonlashtirmoqchi bo'ldik va doimiy ravishda kuzatib borish va almashtirish uchun tunda uyg'onish shart bo'lmagan yuqori darajada mavjud xizmatlar uchun asos bo'lib xizmat qilishi mumkin bo'lgan PostgreSQL o'rnatilishini taqdim qilmoqchi edik. Ushbu segmentda eski tasdiqlangan echimlar va eng so'nggi ishlanmalardan foydalanadigan yangi yordamchi dasturlar avlodi mavjud.
Bugungi kunda yuqori mavjudlik muammosi zahiraga bog'liq emas (bu o'z-o'zidan ma'lum), balki konsensusga - liderni tanlash algoritmiga (Lider saylovi) bog'liq. Ko'pincha yirik baxtsiz hodisalar serverlar etishmasligi tufayli emas, balki konsensus bilan bog'liq muammolar tufayli yuzaga keladi: yangi rahbar chiqmadi, turli ma'lumotlar markazlarida ikkita lider paydo bo'ldi va hokazo. Masalan, Github MySQL klasteridagi ishdan chiqish - ular yozishdi .
Bu masalada matematik asos juda jiddiy. Bir tomondan, u erda , bu HA yechimlarini qurish imkoniyatlariga nazariy cheklovlar qo'yadi, boshqa tomondan, konsensusni aniqlash uchun matematik jihatdan tasdiqlangan algoritmlar, masalan. и . Shu asosda juda mashhur DCS (markazlashtirilmagan konsensus tizimlari) mavjud - Zookeeper, etcd, Consul. Shuning uchun, agar qaror qabul qilish tizimi mustaqil ravishda yozilgan o'zining ba'zi algoritmlari bo'yicha ishlayotgan bo'lsa, bunga juda ehtiyot bo'lish kerak. Ko'p sonli tizimlarni tahlil qilib, biz asosan Zalando tomonidan ishlab chiqilgan ochiq kodli tizim Patroniga joylashdik.
Lirik chekinish sifatida shuni aytamanki, biz ko'p masterli echimlarni, ya'ni yozish uchun gorizontal ravishda o'lchab qo'yilishi mumkin bo'lgan klasterlarni ham ko'rib chiqdik. Biroq, ikkita asosiy sababga ko'ra, biz bunday klasterni yaratmaslikka qaror qildik. Birinchidan, bunday echimlar yuqori murakkablik va shunga mos ravishda ko'proq zaifliklarga ega. Barcha holatlar uchun barqaror yechim topish qiyin bo'ladi. Ikkinchidan, bu holda PostgreSQL sof (mahalliy) bo'lishni to'xtatadi, ba'zi funktsiyalar mavjud bo'lmaydi, ba'zi ilovalar ish paytida yashirin xatolarga duch kelishi mumkin.
Patroni
Xo'sh, Patroni qanday ishlaydi? Ishlab chiquvchilar g'ildirakni qayta ixtiro qilmadilar va asos sifatida tasdiqlangan DCS echimlaridan birini ishlatishni taklif qilishdi. Uning rahm-shafqatiga konfiguratsiyalarni sinxronlashtirish, etakchini tanlash va kvorum bilan bog'liq barcha masalalar beriladi. Buning uchun etcd ni tanladik.
Keyinchalik, Patroni barcha PostgreSQL sozlamalari va replikatsiya sozlamalarini to'g'ri qo'llash, shuningdek o'tish va o'zgartirish buyruqlarini bajarish bilan shug'ullanadi (ya'ni masterning muntazam va g'ayritabiiy o'zgarishi). Xususan, MCS bulutida siz masterdan, sinxron replikadan va bir yoki bir nechta asinxron replikalardan klaster yaratishingiz mumkin. Sinxron replikaning mavjudligi kamida 2 ta serverdagi ma'lumotlarning xavfsizligini ta'minlaydi va aynan shu replika asosiy "bosh nomzod" bo'ladi.
etcd bir xil serverlarda joylashtirilganligi sababli optimal kvorum uchun 3 yoki 5 ta server tavsiya etiladi. Bunday klaster o'qish uchun gorizontal ravishda o'lchaydi (yuqorida yozish uchun masshtablash haqida yozganman). Biroq, asenkron replikatsiyalar, ayniqsa, og'ir yuklar ostida kechikishga moyil ekanligini unutmang.
O'qish uchun bunday replikalardan foydalanish (hot kutish rejimi) hisobot berish yoki tahliliy vazifalar uchun oqlanadi va asosiy serverni yuklaydi.
Agar siz bunday klasterni o'zingiz yaratmoqchi bo'lsangiz, unda sizga kerak bo'ladi:
- 3 yoki undan ortiq serverlarni tayyorlash, ular o'rtasida IP-manzil va xavfsizlik devori qoidalarini sozlash;
- etcd, Patroni, PostgreSQL xizmatlari uchun paketlarni o'rnatish;
- etcd klasterini o'rnatish;
- patroni xizmatini PostgreSQL bilan ishlash uchun sozlang.
Ya'ni, jami o'nlab konfiguratsiya fayllarini to'g'ri tuzish va hech qanday joyda xato qilmaslik kerak. Buni amalga oshirish uchun, masalan, Ansible kabi konfiguratsiyani boshqarish vositasidan foydalanishingiz kerak. Biroq, hali ham yuqori darajadagi TCP balansi mavjud emas. Uni yaratish alohida ish.
Tayyor klasterga muhtoj bo'lganlar uchun, lekin bularning barchasi bilan shug'ullanishni istamaydiganlar uchun biz hayotni soddalashtirishga harakat qildik va bulutimizda Patronida tayyor klaster yaratdik, siz uni bepul sinab ko'rishingiz mumkin. Klasterning o'ziga qo'shimcha ravishda biz quyidagilarni qildik:
- TCP balansi; turli portlarda u har doim mos ravishda joriy master, sinxron yoki asinxron replikaga ishora qiladi;
- Faol Patroni ustasini almashtirish uchun API.
Ular MCS bulutli API va veb-konsol orqali quyi sinflarga bo'linishi mumkin.
Namoyish
MCS bulutida PostgreSQL klasterining imkoniyatlarini sinab ko'rish uchun keling, DBMS bilan bog'liq muammolar yuzaga kelganda jonli ilova qanday harakat qilishini ko'rib chiqaylik.
Quyida sun'iy hodisalarni qayd qilib, ekranga xabar beradigan dastur kodi keltirilgan. Xatolar bo'lsa, u bu haqda xabar beradi va biz Ctrl + C kombinatsiyasi bilan to'xtatmagunimizcha, o'z ishini tsiklda davom ettiradi.
from __future__ import print_function
from datetime import datetime
from random import randint
from time import sleep
import psycopg2
def main():
try:
connection = psycopg2.connect(user = "admin",
password = "P@ssw0rd",
host = "89.208.87.38",
port = "5432",
database = "myproddb")
cursor = connection.cursor()
cursor.execute("SELECT version();")
record = cursor.fetchone()
print("Connection opened to", record[0])
cursor.execute(
"INSERT INTO log VALUES ({});".format(randint(1, 10000)))
connection.commit()
cursor.execute("SELECT COUNT(event_id) from log;")
record = cursor.fetchone()
print("Logged a value, overall count: {}".format(record[0]))
except Exception as error:
print ("Error while connecting to PostgreSQL", error)
finally:
if connection:
cursor.close()
connection.close()
print("Connection closed")
if __name__ == '__main__':
try:
while True:
try:
print(datetime.now())
main()
sleep(3)
except Exception as e:
print("Caught error:n", e)
sleep(1)
except KeyboardInterrupt:
print("exit")
Ilova ishlashi uchun PostgreSQL kerak. API yordamida MCS bulutida klaster yarataylik. Oddiy terminalda, OS_TOKEN o'zgaruvchisi API ga kirish uchun tokenni o'z ichiga oladi (ochiq stack tokenni chiqarish buyrug'i bilan olinishi mumkin), biz buyruqlarni yozamiz:
Klaster yarating:
cat <<EОF > pgc10.json
{"cluster":{"name":"postgres10","allow_remote_access":true,"datastore":{"type":"postgresql","version":"10"},"databases":[{"name":"myproddb"}],"users":[{"databases":[{"name":"myproddb"}],"name":"admin","password":"P@ssw0rd"}],"instances":[{"key_name":"shared","availability_zone":"DP1","flavorRef":"d659fa16-c7fb-42cf-8a5e-9bcbe80a7538","nics":[{"net-id":"b91eafed-12b1-4a46-b000-3984c7e01599"}],"volume":{"size":50,"type":"DP1"}},{"key_name":"shared","availability_zone":"DP1","flavorRef":"d659fa16-c7fb-42cf-8a5e-9bcbe80a7538","nics":[{"net-id":"b91eafed-12b1-4a46-b000-3984c7e01599"}],"volume":{"size":50,"type":"DP1"}},{"key_name":"shared","availability_zone":"DP1","flavorRef":"d659fa16-c7fb-42cf-8a5e-9bcbe80a7538","nics":[{"net-id":"b91eafed-12b1-4a46-b000-3984c7e01599"}],"volume":{"size":50,"type":"DP1"}}]}}
EOF
curl -s -H "X-Auth-Token: $OS_TOKEN"
-H 'Accept: application/json'
-H 'Content-Type: application/json'
-d @pgc10.json https://infra.mail.ru:8779/v1.0/ce2a41bbd1434013b85bdf0ba07c770f/clusters

Klaster ACTIVE holatiga o'tganda, barcha maydonlar joriy qiymatlarni oladi - klaster tayyor.
GUI ichida:

Keling, ulanishga va jadval yaratishga harakat qilaylik:
psql -h 89.208.87.38 -U admin -d myproddb
Password for user admin:
psql (11.1, server 10.7)
Type "help" for help.
myproddb=> CREATE TABLE log (event_id integer NOT NULL);
CREATE TABLE
myproddb=> INSERT INTO log VALUES (1),(2),(3);
INSERT 0 3
myproddb=> SELECT * FROM log;
event_id
----------
1
2
3
(3 rows)
myproddb=>

Ilovada biz PostgreSQL-ga ulanish uchun joriy sozlamalarni belgilaymiz. Biz TCP balanslagichining manzilini aniqlaymiz, shu bilan masterning manziliga qo'lda o'tish zaruratini yo'qotamiz. Keling, uni ishga tushiramiz. Ko'rib turganingizdek, voqealar ma'lumotlar bazasiga muvaffaqiyatli kiritilgan.

Rejalashtirilgan asosiy almashtirish
Endi masterni rejalashtirilgan almashtirish paytida dasturimizning ishlashini sinab ko'raylik:

Biz arizani ko'rib chiqamiz. Biz dastur haqiqatan ham to'xtatilganini ko'ramiz, lekin bu bir necha soniya davom etadi, bu alohida holatda, maksimal 9.

avtohalokat
Keling, hozirgi usta virtual mashinaning qulashini simulyatsiya qilishga harakat qilaylik. Horizon interfeysi orqali virtual mashinani shunchaki o'chirib qo'yish mumkin edi, faqat bu muntazam o'chirish bo'ladi. Bunday almashtirish barcha xizmatlar, shu jumladan Patroni tomonidan qayta ishlanadi.
Bizga oldindan aytib bo'lmaydigan yopilish kerak. Shuning uchun men ma'murlarimizdan virtual mashinani - joriy masterni g'ayritabiiy tarzda o'chirishni sinov maqsadida so'radim.

Shu bilan birga, bizning arizamiz ishlashda davom etdi. Tabiiyki, ustaning bunday favqulodda o'zgarishi e'tibordan chetda qolishi mumkin emas.
2019-03-29 10:45:56.071234
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 453
Connection closed
2019-03-29 10:45:59.205463
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 454
Connection closed
2019-03-29 10:46:02.661440
Error while connecting to PostgreSQL server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
Caught error:
local variable 'connection' referenced before assignment
……………………………………………………….. - здесь какое-то количество ошибок
2019-03-29 10:46:30.930445
Error while connecting to PostgreSQL server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
Caught error:
local variable 'connection' referenced before assignment
2019-03-29 10:46:31.954399
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 455
Connection closed
2019-03-29 10:46:35.409800
Connection opened to PostgreSQL 10.7 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
Logged a value, overall count: 456
Connection closed
^Cexit
Ko'rib turganingizdek, ilova 30 soniyadan kamroq vaqt ichida o'z ishini davom ettira oldi. Ha, ma'lum miqdordagi xizmat foydalanuvchilari muammolarni payqashga vaqtlari bo'ladi. Biroq, bu serverning jiddiy buzilishi, bu tez-tez sodir bo'lmaydi. Shu bilan birga, odam (administrator) agar u o'tish skripti bilan konsolda o'tirmasa, bu qadar tez reaksiyaga kirishishga vaqt topa olmasdi.
xulosa
Menimcha, bunday klaster ma'murlar uchun katta afzalliklarni beradi. Aslida, ma'lumotlar bazasi serverlarining jiddiy buzilishlari va nosozliklari dastur va shunga mos ravishda foydalanuvchi uchun sezilmaydi. Shoshilinch ravishda biror narsani tuzatishingiz va vaqtinchalik konfiguratsiyalar, serverlar va hokazolarga o'tishingiz shart emas. Va agar bunday yechim bulutda tayyor xizmat sifatida ishlatilsa, uni tayyorlashga vaqt sarflashning hojati bo'lmaydi. Siz qiziqroq narsani qilishingiz mumkin.
Manba: www.habr.com
