Razotkrivanje replikacije baze podataka: strategije za otporne sustave
Replikacija baze podataka zvuči jednostavno sve dok prvi incident u produkciji ne nametne teže pitanje: što zapravo znači “ažurno”? Druga kopija podataka može zaštititi dostupnost, poboljšati performanse čitanja i podržati oporavak. Također može neprimjetno posluživati zastarjele rezultate, umnožiti operativnu složenost i pretvoriti mrežni zastoj u kvar cijele aplikacije.
Korisno je o replikaciji razmišljati ne kao o potvrdnom okviru u konzoli baze podataka. Ona je skup kompromisa vezanih uz konzistentnost, latenciju, prebacivanje u slučaju kvara i vrste pogrešaka koje vaš sustav može sigurno tolerirati.
Replikacija ima različite zadaće
Prije odabira topologije, imenujte problem koji mora riješiti. “Trebamo replike” previše je neodređeno da bi rezultiralo pouzdanim dizajnom.
- Skaliranje čitanja: raspodjela prometa s mnogo čitanja kako jedan primarni poslužitelj ne bi bio odgovoran za svaki upit.
- Visoka dostupnost: zadržavanje kopije koju je moguće promovirati kada trenutačni poslužitelj za pisanje postane nedostupan.
- Oporavak od katastrofe: čuvanje podataka u zasebnoj domeni kvara, često uz namjernu udaljenost ili odgodu.
- Izolacija izvještavanja: zaštita transakcijskih radnih opterećenja od skupih analitičkih upita.
Jedna replika ponekad može služiti za više od jedne svrhe, ali kombiniranje uloga povećava rizik. Radno opterećenje izvještavanja koje preplavi jedinog kandidata za prebacivanje u slučaju kvara nije otporan dizajn. Kada rizik to opravdava, odvojite operativne replike od replika za izvještavanje ili oporavak.
Namjerno odaberite model konzistentnosti
Većina poznatih konfiguracija primarni poslužitelj–replika promjene replicira asinkrono. Primarni poslužitelj potvrđuje zapis, klijentu šalje potvrdu, a replike tu promjenu primjenjuju kasnije. To održava nisku latenciju pisanja, ali stvara zaostatak replikacije: čitanje poslano odmah replici možda neće vidjeti uspješan zapis.
To je prihvatljivo za mnoge zaslone. Katalog proizvoda, feed aktivnosti ili nadzorna ploča često mogu tolerirati kratko kašnjenje. Opasno je za tijek koji potvrđuje plaćanje, mijenja dozvolu računa ili prikazuje rezultat ažuriranja koje je isti korisnik upravo napravio.
Klasičan simptom je pogreška čitanja nakon pisanja:
$orderId = $orders->create($payload);
// A replica may not have applied the new row yet.
$order = $replicaConnection->findOrder($orderId);
Pragmatično rješenje jest usmjeravati čitanja nakon pisanja na primarni poslužitelj tijekom kratkog, izričito definiranog razdoblja ili do završetka granice zahtjeva. Druga je mogućnost pročitati novostvoreni zapis s primarnog poslužitelja i izravno ga vratiti. Važno je pravilo učiniti vidljivim u arhitekturi aplikacije, umjesto nadati se da do zaostatka nikada neće doći.
Sinkrona replikacija može smanjiti rizik da potvrđeni zapisi nedostaju na replici, ali povećava latenciju i može smanjiti dostupnost kada su replike spore ili nedostupne. Nije automatski “bolja”. Prikladna je samo kada poslovna operacija zahtijeva to jače jamstvo i sustav može podnijeti njezin operativni trošak.
Neka pisanja budu jednostavna
Najjednostavnija otporna topologija obično ima jednog autoritativnog zapisivača u određenom trenutku. Aplikacije šalju pisanja tom primarnom poslužitelju, a prihvatljiva čitanja usmjeravaju na replike. Time se izbjegavaju sukobi pri pisanju i semantiku transakcija lakše je razumjeti.
Dizajni s više primarnih poslužitelja ili više zapisivača mogu biti valjani, osobito kada se zapisi moraju prihvaćati na više lokacija. No zahtijevaju izričito rješavanje sukoba, pravila generiranja ključeva i jasan odgovor na pitanje što se događa kada dva čvora promijene isti logički zapis. Ako aplikacija nema dobro definiranu politiku spajanja, topologija baze podataka ne može je sigurno izmisliti.
Započnite s jednim zapisivačem, osim ako stvarni zahtjev proizvoda ne nalaže drukčije. Skaliranje čitanja razmjerno je jednostavno; usklađivanje sukobljenih pisanja nije.
Usmjeravanje učinite pravilom, a ne raspršenim uvjetima
U PHP aplikaciji odabir baze podataka trebao bi biti smješten iza male granice koju je moguće testirati. Kontroleri i domenske usluge ne bi trebali neovisno odlučivati je li upit “dovoljno siguran” za repliku. To stvara nedosljedno ponašanje tijekom incidenata i poskupljuje buduće promjene.
final class ConnectionRouter
{
public function forRead(bool $requiresFreshData): Connection
{
return $requiresFreshData
? $this->primary
: $this->replica;
}
public function forWrite(): Connection
{
return $this->primary;
}
}
Točna integracija okvira razlikovat će se, ali pravilo bi trebalo biti stabilno: pisanja koriste primarni poslužitelj; čitanja osjetljiva na svježinu koriste primarni poslužitelj; čitanja s replika koriste se samo ondje gdje su zastarjeli podaci prihvatljivi. Ako aplikacija koristi transakcije, zadržite sve upite koji sudjeluju u transakciji na istoj primarnoj vezi. Dijeljenje transakcije između čvorova poništava razlog za postojanje transakcije.
Planirajte kvar replike
Replika bi trebala biti opcionalna za dostupnost, a ne nova jedinstvena točka kvara. Ako replika za čitanje nije dostupna, mnogi bi se sustavi trebali vratiti na primarni poslužitelj, uz prekidanje kruga ili privremene promjene usmjeravanja kako bi se izbjegli ponovljeni spori pokušaji povezivanja. Taj povratak mijenja kapacitet za ispravnost i kontinuitet, što je obično ispravan kompromis tijekom djelomičnog prekida rada.
Nemojte neprimjetno ponovno pokušavati proizvoljna pisanja na drugom poslužitelju. Istek vremena ne dokazuje da izvorno pisanje nije uspjelo. Ponovni pokušaj može stvoriti duplikate, osim ako je operacija osmišljena kao idempotentna. Koristite jedinstvene identifikatore zahtjeva, trajne zapise o idempotentnosti gdje su potrebni i jasno rukovanje pogreškama pri dvosmislenim ishodima.
Prebacivanje u slučaju kvara proces je, a ne događaj
Promicanje replike mijenja izvor istine sustava. Vjerodostojan plan prebacivanja u slučaju kvara treba više od naredbe koja mijenja uloge. Potreban mu je način za zaustavljanje ili ograđivanje starog primarnog poslužitelja, ažuriranje povezivosti aplikacije, potvrdu da novi primarni poslužitelj prihvaća pisanja i sprječavanje podijeljenog mozga, kada dva čvora prihvaćaju sukobljena pisanja.
Vaš operativni priručnik trebao bi odgovoriti na praktična pitanja:
- Kako se otkriva kvar primarnog poslužitelja i tko ili što smije promovirati zamjenu?
- Kako se sprječavaju pisanja na bivšem primarnom poslužitelju prije njegova povratka?
- Kako aplikacije otkrivaju novu krajnju točku zapisivača?
- Koji je prozor gubitka podataka moguć uz asinkronu replikaciju?
- Kako se popravljeni čvor ponovno priključuje i provjerava?
Automatizacija pomaže, ali ne uklanja potrebu za tim odlukama. Automatizirano prebacivanje u slučaju kvara bez ograđivanja može brže proizvesti nedosljedne podatke. Testirajte operativni priručnik u izoliranom okruženju i uvježbajte ponašanje aplikacije, a ne samo promjenu uloge baze podataka.
Pratite signale koji mijenjaju odluke
Zelena provjera procesa nije dovoljna. Pratite zaostatak replikacije, pogreške replikacije, zasićenost vezama, kapacitet diska, latenciju upita i zdravlje prijenosa replikacije. Upozorenja bi trebala razlikovati repliku koja kratkotrajno zaostaje od one koja je potpuno prestala primjenjivati promjene.
Zaostatak također zaslužuje vidljivost na razini aplikacije. Ako usluga obećava svježe podatke, ali njezina politika usmjeravanja ta čitanja šalje replikama, samo infrastrukturne metrike neće otkriti prekršeni ugovor. Instrumentirajte koja je klasa veze obradila važne zahtjeve, osobito oko pisanja, autentifikacije, stanja, zaliha i dozvola.
Otpornost proizlazi iz izričitih granica
Replikacija je moćna jer sustavu omogućuje nastavak rada kada pojedinačni strojevi, mreže ili radna opterećenja zakažu. Njezina je cijena to što više ne postoji jedna trenutačno identična kopija stvarnosti posvuda. Dobar dizajn pozadinskog sustava otvoreno priznaje tu činjenicu.
Definirajte koja čitanja smiju biti zastarjela, zadržite jedan jasan autoritet za pisanje, tretirajte prebacivanje u slučaju kvara kao uvježban tijek rada i neka pravila usmjeravanja budu dio dizajna aplikacije. Kada su te granice izričite, replikacija prestaje biti magija baze podataka i postaje ono što bi trebala biti: pouzdan inženjerski alat za izgradnju sustava koji se pod opterećenjem savijaju, a ne lome.