Vorige week in de CHAR(10) conferentie hadden we een workshop over "Cloud Databases". Simpel gezegd:wat te doen als de use case-vereisten de beschikbare bronnen op de databaseserver overschrijden.
Dit was een hoofdonderwerp van de hele conferentie en er zijn gedurende de dag verschillende oplossingen geïllustreerd. Een gemeenschappelijk thema was dat geen enkele oplossing geschikt is voor alle gebruiksscenario's en dat elke oplossing zijn kosten met zich meebrengt; daarom moet u de oplossing kiezen die uw gebruikscasus zich kan veroorloven.
Een ander veelvoorkomend (zij het impliciet) punt was de focus op oplossingen op "hoog niveau", dat wil zeggen:het verbinden van meerdere databaseservers op een hoger niveau om een enkele server met grotere bronnen te emuleren.
Een duidelijk voordeel is dat u de goed onderzochte PostgreSQL-code niet hoeft te wijzigen; een nadeel is dat als je meerdere databaseservers met hun onafhankelijke tijdlijnen gebruikt, je een aantal nuttige eigenschappen verliest. Twee voorbeelden:het gedeeltelijke verlies van transactionele semantiek genereert conflicten; het voorbereiden van elke query buiten de database introduceert beperkingen op de geaccepteerde query's.
De discussie was best interessant, en toen Dimitri Fontaine externe tablespaces noemde, begon ik me af te vragen rond een verwant maar duidelijk idee, namelijk:of een benadering op een lager niveau aan het probleem van het bundelen van middelen zou echt onpraktisch zijn. Voordat ik de details kon uitwerken, eindigde de workshop en kon ik het idee alleen schetsen voor enkele van de mensen die rond het whiteboard waren (waaronder Gabriele Bartolini, Nic Ferrier, Marko Kreen, Hannu Krosing, Greg Smith) samen met de basis vragen “ziet het er haalbaar uit?” en "lijkt dat op iets dat je al weet?".
Een korte schets:een applicatie-stack kan op deze manier worden weergegeven
(application) --> (connection) --> (db server) --> (resources)
waarbij de bronnen die door de database worden gebruikt opslag, RAM en CPU's omvatten. Het doel is om de applicatie meer middelen te laten gebruiken om de capaciteit en snelheid te vergroten. "Slimme" applicaties die meerdere databases beheren, kunnen worden weergegeven als
(application) --> (connection) --> (db server) --> (resources) | +---------> (connection) --> (db server) --> (resources)
terwijl oplossingen voor "connection pooling" kunnen worden weergegeven als
(application) --> (connection) --> (db server) --> (resources) | +---------> (db server) --> (resources)
met "lagere" oplossingen bedoel ik zoiets als
(application) --> (connection) --> (db server) --> (resources) | +---------> (resources)
die op iets bekends lijkt, maar dat is niet wat ik hier voorstel. Om het verschil uit te leggen kan ik de details vergroten en schrijven
(resources) = (virtual resources) --> (physical resources)
om het feit weer te geven dat je op het laagste niveau een niet-triviale afbeelding kunt hebben tussen fysieke objecten en virtuele. SAN-opslag of RAID-striping kan bijvoorbeeld grotere virtuele schijven bieden door kleinere fysieke schijven aan elkaar te koppelen. Dergelijke gevallen kunnen worden afgebeeld als
(application) --> (connection) --> (db server) --> (virt.res.) --> (ph.res.) | +--------> (ph.res.)
Mijn voorstel is om middelen te bundelen op de databaseserver niveau, zodat we een efficiëntere "virtualisatie" kunnen hebben door gebruik te maken van de kennis van de specifieke gebruiksgevallen voor elke bron (CPU, RAM, schijf), en tegelijkertijd kunnen we de moeilijkheden van het transactieparadigma vermijden. De foto zou zijn:
(application) --> (connection) --> (db server) --> (virt.res.) --> (ph.res.) | +--------> (virt.res.) --> (ph.res.)
Het voordeel is dat we niet alle mogelijke use-cases voor elke virtuele resource hoeven te beheren; we moeten alleen de use-cases beheren (en optimaliseren voor) die PostgreSQL echt nodig heeft. Bijvoorbeeld:WAL moet nog steeds worden geschreven in lokale "niet-gevirtualiseerde" opslag, de bgwriter zal toegang krijgen tot lokale en externe bronnen (RAM en schijf), enz.
Enkele laatste woorden over betrouwbaarheid. Om goed te kunnen functioneren heeft het hele systeem elk subsysteem nodig; gedeeltelijke storingen worden niet beheerd, omdat deze architectuur niet redundant is. Het is een gedistribueerd systeem, maar niet gedeeld. Als deze architectuur goedkope en eenvoudige schaalbaarheid zou kunnen bieden via een virtuele databaseserver die functioneel equivalent is aan een fysieke server met grotere bronnen, dan zou op de standaard manier een hoge beschikbaarheid kunnen worden verkregen door twee identieke virtuele servers in een Hot Standby-configuratie op te zetten.
Netwerkkwaliteit heeft een grote invloed op de algehele prestaties; dit ontwerp kan alleen nuttig zijn als u een reeks machines in hetzelfde LAN hebt, niet alleen om snelheidsredenen, maar ook omdat een netwerkstoring eigenlijk een systeemstoring zou zijn. Zelfs met deze beperkingen ben ik van mening dat het heel handig zou zijn om deze optie te hebben.
Dit is nog steeds een schets, die moet worden gebruikt als referentie voor verdere discussie. Volgende mogelijke stappen:
- om een gedetailleerde lijst te maken van de gebruiksscenario's van bronnen
- om te beslissen welke technologieën in elk geval het beste kunnen helpen
- om de werkelijke prestatie-/ontwikkelingskosten te schatten