sql >> Database >  >> RDS >> Mysql

PlanetScale &Vitess:referentiële integriteit met legacy Sharded-databases

Ik ben dol op serverloze technologie. Ik speel wat rond en maak veel verschillende serverloze applicaties om te experimenteren met andere coole technologie. Binnen het enorme cluster van technologieën waarmee ik gebruik/experimenteer, was PlanetScale was de database die ik voornamelijk gebruikte voor mijn persoonlijke nevenprojecten, omdat er geen andere "goede" optie was die de Prisma ORM ondersteunde .

PlanetScale is een MySQL-serverloos platform dat eenvoudigweg Vitess verkoopt, een databaseclustersysteem voor het horizontaal schalen van MySQL. Ze hebben hun eigen database niet geschreven - mogelijk daaraan bijgedragen, maar ze hebben het niet geschreven. Uit de Vitess-documentatie:

Vitess is gemaakt in 2010 om de MySQL-schaalbaarheidsuitdagingen op te lossen waarmee het team van YouTube te maken had.

In dit artikel gaan we op weg naar het begrijpen van de structuur van deze niet-ACID legacy shard-databases, waarom ze niet in staat zijn om zoiets cruciaals als referentiële integriteit te ondersteunen, en waarom we het gebruik ervan in onze applicaties moeten vermijden. Dit artikel gaat meer over de technologie van Vitess, hoewel ik PlanetScale in de titel heb opgenomen omdat, zoals ik hierboven al zei, het Vitess (met wat tooling) gewoon als een service verkoopt en ze in de volgende maanden grip hebben gekregen als zijnde een "betrouwbare" serverloze database.

Achtergrond

Mijn eerste vraag was waarom er staat dat het onmogelijk is om een ​​PlanetScale-database te schalen met referentiële integriteit, aangezien in hun documentatie staat dat:

De manier waarop FOREIGN KEY beperkingen zijn geïmplementeerd in MySQL (of liever gezegd in de InnoDB-opslagengine) interfereert met Online DDL-bewerkingen. Lees meer in deze Vitess-blogpost.

Beperkt tot één MySQL-serverbereik, FOREIGN KEY beperkingen zijn onmogelijk te handhaven als uw gegevens eenmaal groeien en zijn verdeeld over meerdere databaseservers. Dit gebeurt meestal wanneer u functionele partitionering/sharding en/of horizontale sharding introduceert.

Dit bracht me ertoe te denken:doe FOREIGN KEY beperkingen van invloed op de schaalbaarheid in het algemeen? en zo ja, hoe?

Ik denk dat het belangrijk is om te beseffen dat SQL-tabel-joins behoorlijk duur zijn, maar voor zover ik weet werd het niet veel beïnvloed door referentiële integriteit? Nu, als we zoiets als data-analyse doen, hebben we natuurlijk geen behoefte aan referentiële integriteit, omdat we onze gegevens gewoon in een enkele tabel willen dumpen, maar PlanetScale en Vitess scheppen op dat ze worden gebruikt door grote webapplicaties zoals YouTube.

Hierdoor raakte ik in de war over waarom ze de FOREIGN KEY . zouden laten vallen beperking aangezien databases zoals CockroachDB en Spanner nog steeds referentiële integriteit behouden en schaalbaar zijn.

Wat is referentiële integriteit en waarom is het belangrijk?

Laten we beginnen met de basis, voor het geval je nieuw bent. Ik vermoed dat de meeste mensen die dit bericht lezen een goed idee hebben van waar ze het over hebben, maar ik zal het uitleggen als een formaliteit. In eenvoudige bewoordingen, een FOREIGN KEY constraint is een databasesleutel die we kunnen gebruiken om relaties tussen twee verschillende tabellen te maken door te verwijzen naar een kolom of een reeks kolommen. Referentiële integriteit verwijst eenvoudigweg naar de staat van de database waarin alle waarden van alle sleutels geldig zijn.

Waarom is het belangrijk?

Nu we een beetje een idee hebben van wat ze zijn, gaan we naar het tweede deel:waarom zijn ze belangrijk?

Referentiële integriteit is belangrijk omdat het u ervan weerhoudt nieuwe fouten in uw database te introduceren. Het is een functie die vaak wordt geboden door relationele databases die voorkomen dat gebruikers of toepassingen inconsistente gegevens in de database invoeren. Dit leidt tot verbeterde gegevenskwaliteit, snellere ontwikkeling, veel minder bugs en consistentie in uw applicatie.

Waarom heeft Vitess het niet?

Dus om te begrijpen waarom Vitess referentiële integriteit niet kan ondersteunen, moeten we een duik nemen in de architectuur van de database. Vitess is een gesharde niet-ACID SQL-database, geen echte gedistribueerde ACID SQL-database.

Nu vraag je je vast af wat die termen zijn. Laat me ze voor je opsplitsen:ACID is een acroniem van Atomiciteit, Consistentie, Isolatie en Duurzaamheid.

Hier verwijst atomiciteit naar een actie die ofwel volledig wordt voltooid ofwel mislukt - geen gedeeltelijke voltooiing van een transactie. Consistentie verwijst naar de transactie die de database in een geldige staat achterlaat. Isolatie betekent simpelweg dat twee transacties worden uitgevoerd zonder enige interferentie met elkaar, en duurzaamheid betekent dat de wijzigingen van de transactie worden opgeslagen.

Een shard is een horizontale partitie van gegevens in een database en elke shard wordt op een afzonderlijke databaseserver-instantie gehouden om de belasting te spreiden. Dus als we het hebben over een database die shard is, hebben we het over zoiets als dit. Zoals ik al eerder zei, is Vitess een gesharde niet-ACID SQL-database, wat in feite betekent dat het GEEN ACID-eigenschappen van transacties garandeert.

Waarom laten vallen?

Welnu, het probleem begint wanneer je een MySQL-database hebt met een goed gedefinieerd schema, en je service wordt populair door het probleem van te veel reads die de database raken. Wat de meeste mensen hier doen, is dat ze vaak uitgevoerde zoekopdrachten in de cache gaan opslaan, maar de uitlezingen zijn niet langer ACIDic.

Naast te veel leesbewerkingen, is het hebben van een teveel aan schrijfbewerkingen naar uw database een serieus probleem waarmee velen te maken kunnen krijgen. Laten we zeggen dat we klaar zijn om onze portemonnee in brand te steken - we kunnen verticaal schalen, meer RAM toevoegen, een 16-coreprocessor en heel veel echt snelle solid-state schijven.

We hebben natuurlijk nog steeds het probleem dat SQL-tabeljoins steeds complexer worden, dus je begint met denormaliseren om joins tussen tabellen te vermijden.

Ik heb een tijdje geleden een lezing gegeven op de Prisma Meetup, waar ik de basisprincipes van het ontwerpen van een relationele database heb uitgelegd. Een onderwerp dat ik hier behandelde was denormalisatie, als je geïnteresseerd bent, kijk dan hier zeker eens naar.

Maar denormalisatie is in feite het proces waarbij u overtollige gegevens toevoegt aan tabellen in uw database, wat de prestaties ten opzichte van de kosten van schijfruimte verbetert, aangezien u geen CPU-kracht meer gebruikt voor joins. Hoewel denormalisatie de leessnelheid verbetert, is het belangrijk om te beseffen dat het schrijven langzamer gaat.

Ondanks dit alles is onze database echter nog steeds traag, dus we verplaatsen databaseberekeningen naar de client, bijvoorbeeld door een UUID te genereren of een datum toe te wijzen.

Zelfs na dit alles zullen query's nog steeds traag zijn - dus houden we het resultaat van de meest opgevraagde gegevens gereed in een proces dat bekend staat als database-materialisatie. Nu gaat het lezen misschien sneller, maar het schrijven wordt met de dag langzamer. De enige logische situatie is nu om secundaire indexen te laten vallen.

Dus op dit moment heeft onze database

  • Geen ACID-eigenschappen vanwege caching
  • Geen genormaliseerd schema
  • Geen triggers
  • Geen databaseberekeningen
  • Geen secundaire indexen

Dit maakte de weg vrij voor Vitess- en NoSQL-databases, omdat bedrijven problemen hadden met het schalen van hun database. Door de manier waarop het was ontworpen, waren ze niet in staat om de gegevensconsistentie, een ACID-eigenschap, te behouden wanneer transacties verschillende shards overspannen. Referentiële integriteit heeft alles te maken met consistentie wanneer gegevens zich over meerdere shards uitstrekken, daarom is het logisch dat ze dit niet goed kunnen ondersteunen.

We kunnen diep ingaan op de structuur van NoSQL-databases zonder FOREIGN KEY beperking en problemen waarmee we te maken zullen krijgen bij het aannemen van dat model, maar dat is het onderwerp voor een ander bericht.

Het is niet alleen Vitess, het is een standaardpraktijk voor shard-databases om referentiële integriteit te vermijden, omdat er gewoon geen andere keuze is. In termen van het ACID-model staat in hun documentatie dat ze atomiciteit maar geen isolatie garanderen, en zelfs zo ver gaan om te zeggen:

Het garanderen van ACID Isolatie is zeer omstreden en heeft hoge kosten. Als dit standaard zou zijn, zou Vitess onpraktisch zijn geworden voor de meest voorkomende gebruikssituaties.

Laten we het kort hebben over wat ACID Isolatie is. Er zijn vier niveaus (volgens de SQL-92-standaarden), waaronder serialisatie, read commit, read uncommitted en herhaalbare reads. Dat gezegd hebbende, zijn er meer isolatieniveaus, zoals Snapshot-isolatie, die geen SQL-standaard is, hoewel deze door verschillende databases zoals Firebase of MongoDB wordt gebruikt. Als je hier verder in geïnteresseerd bent, raad ik je aan dit bericht te lezen. Om het kort te houden, ga ik niet bespreken wat elk isolatieniveau doet/betekent, maar als je daar meer over wilt lezen, bekijk dan deze pagina van de MySQL-documentatie.

ACID-isolatie verwijst naar de databasetransacties die ACIDic zijn, wat belangrijk is omdat ze garanderen dat bewerkingen zich gedragen zoals ontwikkelaars verwachten. Ik weet niet zeker wat ze bedoelen als ze zeggen:"Het garanderen van ACID-isolatie is zeer controversieel en heeft hoge kosten", maar of ze bedoelen dat het garanderen van ACID-isolatie hoge kosten met zich meebrengt voor elk product , ze hebben het mis. Verschillende gedistribueerde ACID-compatibele databases hebben het hoogste niveau van isolatie (serialiseerbare transacties) terwijl ze toch presteren met hoge lees-/schrijfsnelheden. In de context van Vitess hebben ze echter geen ongelijk, aangezien transacties met meerdere shards geen enkel niveau van isolatie kunnen bereiken.

Conclusie

Bij dit alles moet je je afvragen:waarom zou iemand PlanetScale of Vitess willen gebruiken? Nou, ik vraag me hetzelfde af. Bij veel bedrijven en websites was de reden dat ze Vitess terug kozen toen er geen betere opties waren. Als u naar het begin van het artikel gaat, ziet u hoe het in 2010 is gemaakt. Nu we kunnen genieten van een ACID-compatibele schaalbare database met referentiële integriteit, zou het in ons eigen belang zijn om over te schakelen naar deze nieuwe databases, en ik ben er al mee begonnen! Technologie verandert snel en het up-to-date houden van uw database is een cruciaal onderdeel van elke toepassing.


  1. ORA-01843 geen geldige maand - Datums vergelijken

  2. Verhindert SELECT FOR UPDATE dat andere verbindingen worden ingevoegd wanneer de rij niet aanwezig is?

  3. Hoe u alle weergaven in een PostgreSQL-database kunt weergeven

  4. Orakel. Hoe de datum en tijd uit te voeren?