Re: PostgreSQL Cluster

Andreas Kretschmer <[email protected]> Fri, 11 May 2018 09:46:14 +0200
Newsgroups gmane.comp.db.postgresql.german
Message-ID <[email protected]>
Moin,


Am 10.05.2018 um 11:11 schrieb Andreas Kretschmer:
> On 10 May 2018 10:27:51 CEST, Michael Post <[email protected]> wrote:
>> Hallo,
>>
>> ich versuche einen PostgreSQL-Cluster mit aktuell zwei Nodes
>> aufzubauen.
>> Ziel ist es, eine ausfallsichere Umgebung aufzubauen, so dass
>> theoretisch jederzeit ein Node wegbrechen kann und die Umgebung dennoch
>> korrekt weiterläuft (auch ohne Eingriff eines Administrators).
>> Gleichzeitig ist ein Loadbalancing über alle verfügbare Nodes
>> gewünscht.
>>
>> Ich habe mich mit pgpool2 beschäftigt. Aber irgendwie ist mir das
>> Prinzip noch nicht ganz klar, wie die Nodes synchron gehalten werden
>> und
>> wie ein zuvor weggebrochender Node wieder mit dem vorher existierenden
>> Node synchronisiert wird (evtl. automatisch?).
>>
>> Ich baue eine komplett neue Umgebung damit auf und kann daher gleich
>> auf
>> PostgreSQL 10 aufsetzen.
>>
>> Habt Ihr einen Hinweis oder eine gute Doku für mich, die auf PostgreSQL
>> 10 aufsetzt und mich an das Thema besser einführt?
>>
>> Vielen Dank für Eure Unterstützung,
>>
>> Michael
> Ich antworte dir morgen ausführlich ;-)

Du willst einen Cluster, wo jeder Knoten stets die gleichen Daten hat. 
Dazu bietet sich Replikation an.
Vor PostgreSQL 9.0 gab es keine eingebaute Replikation, was dazu führte, 
daß es verschiedene Ansätze (externe Lösungen) gab, dies zu realisieren.

so gab (und gibt es) TRIGGER-basierte Lösungen (Slony, Londiste, ...) 
die bei z.B. einem INSERT dafür sorgten, daß dieser Datensatz auch in 
einer weiteren DB
eingetragen wurde. Nachteil: erhöhter Aufwand auf dem Master (TRIGGER 
sind 'teuer'), allerdings gibt es auch einen Vorteil: das funktioniert 
auch versionsübergreifend.

Andere Lösung: man schaltet eine Instanz davor, die, wenn sie eine 
schreibende Operation erkennt, diese auf 2 oder mehr der angeschlossenen 
Instanzen
ausführt. Bestes Beispiel dafür ist pgpool2. Nachteil: diese Instanz 
davor muß jede ankommende Query erst einmal selber zerlegen und prüfen, 
was diese macht.
Bei einem INSERT ist das noch trivial, bei Funktionen aber nicht mehr. 
Insbesondere dann, wenn man selber Stored Procedures schreibt. Ein 
"Select * from my_function(10,100)"
macht genau was? Richtig, ohne diese Funktion zu kennen kann man das 
nicht sagen. Vor genau diesem Problem steht auch pgpool2.

Seit PostgreSQL 9.0 gibt es die eingebaute "Streaming Replication" (SR). 
Diese sorgt für ein binärgleiches Abbild des Masters auf den Standbys. 
Dazu werden alle physischen Änderungen (das Transaktionslog)
zu dem oder den Standbys übertragen. Vorteil: (nahezu) keine extra 
Belastung auf dem Master, Nachteil: geht nicht versionsübergreifend.

Mit dieser Streaming Replication sind eigentlich die anderen Lösungen 
obsolet, weil die Vorteile von SR überwiegen. Nachteil ist, daß es nicht 
möglich ist, nur einen Teilset der DB zu replizieren und daß es nicht 
möglich ist, das versionsübergreifend zu replizieren.

Um diese Nachteile noch zu lösen, hat insbesondere (aber nicht nur) ein 
Team von 2ndQuadrant die physische Replikation von SR (es werden quasi 
physische Diffs von Binärdateien übertragen) zu einer logischen 
Replikation erweitert. Dazu wird dieser Stream von physischen Diffs 
wieder in logische SQL-Befehle übersetzt. Vorteil: damit ist es sowohl 
möglich, nur definierte Teile der Gesamtdatenbank zu replizieren als 
auch versionsübergreifend zu replizieren. Dazu kommt noch, daß die DB, 
in die repliziert wird, weiter schreibbar ist.

Von dieser logischen Replikation gibt es 3 grundlegende Realisierungen:

* logical replication: eingebaut in PG 10. Diese erlaubt z.B. die 
Replikation von Tabellen, allerdings keine Filterung (auswahl der zu 
replizierenden Datensätze) und auch kein Konflikthandling. Eigene 
Befehle wie z.B. CREATE PUBLICATION, CREATE SUBSCRIPTION etc. 
https://www.postgresql.org/docs/10/static/logical-replication.html
* pglogical: extra Modul, verfügbar ab PG 9.4. mehr Funktionen als 
logical replication in PG10, aber nicht im Kern der DB, daher alle 
Aufrufen via Function Calls, z.B. pglogical.create_subscription(), siehe 
https://www.2ndquadrant.com/en/resources/pglogical/pglogical-docs/
* BDR: Bi-Directional Replication. Das ist eine volle 
Multi-Master-Lösung, für wohl maximal 48 gleichzeitige aktive Master. 
Ideal für geographisch weit verteilte Systeme, wir haben Kunden mit BDR 
und Servern in Amerika, Europa und Asien und eben volle 
Multi-Master-Replikation dazwischen. BDR Version 1 ist weiter unter 
Support, aber keine neuen Features mehr. Version2 und Version 3(derzeit 
Beta, ab Ende Mai wohl verfügbar) sind die aktiv in Entwicklung 
befindlichen Versionen.


Was Du brauchst bzw. suchst ist offenbar eine Master-Standby-Lösung 
mittels SR. Die Applikation schreibt alle Änderungen in den Master (A) 
und kann die Daten auch auf dem Standby (S) lesen.
Falls der Master ausfällt, sollen die Zugriffe auf den Standby gehen und 
dieser auch zum Master promotet werden. (man muß noch zwischen 
synchroner und asynchroner Replikation unterscheiden)

Zum Aufsetzen einer solchen Replikation empfehlen wir ein Tool, was wir 
auch dafür entwickelt haben: repmgr https://repmgr.org/ . Wenn das 
korrekt eingerichtet ist, kannst Du via "repmgr standby switchover" z.B. 
für eine geplante Wartung am Master die Rollen Master <-> Standby 
einfach tauschen. Das ist aber noch keine HA, kein automatisches 
Failover. Dazu kann man on top von repmgr noch den passenden Deamon 
nutzen, den repmgrd. Dieser überwacht von dem/den Standby(s) den Master 
und sorgt bei dessen Ausfall für das automatische Promoten eines Standbys.

Was noch fehlt: wie erfährt das die Applikation? Dafür gibt es, Du ahnst 
es, wieder verschiedene Möglichkeiten. JDBC-basierte Applikationen 
können das im JDBC-Treiber einstellen, dieser hat ein eingebautes 
Auto-Failover. Dazu nennt man in connection-string alle Server (Master 
und alle Standbys) und gibt an, was man haben will: den Master oder 
'nur' einen Standby. PostgreSQL 10 hat dies nun in der libpq auch.
Damit kannst Du also in der Applikation sagen: es gibt server1, server2, 
server3 - bitte suche mir den aktuellen Master und verbinde Dich damit. 
Damit hast allerdings noch keine Lastvrteilung, Du landest IMMER auf dem 
Master. Ist Deine Applikation schlau genug zu wissen, daß die folgenden 
Abfragen alle nur rein lesend sind, könnte diese auch eine weitere 
Verbindung zur DB aufbauen und dabei angeben, daß ein ReadOnly-Server, 
also Standby, ausreicht.

Ein Wort noch zu pgpool2: dieses kann einfaches connection-pooling, aber 
auch Verteilung schreibender Zugriffe auf mehrere Knoten. Das brauchst 
Du aber bei SR nicht wirklich. Was bleibt, ist, daß pgpool2 relativ viel 
Code ist und relativ aufwendig ist, für etwas, was man eigentlich nicht 
braucht. Ein connection-pooler kann aber dennoch durchaus sinnvoll sein. 
Die von uns dafür unterstützte Lösung ist pgbouncer.


So, ich hoffe, nun bist Du völlig verunsichert und brauchst eine 
weitergehende Beratung von uns ;-)

tl;dr

* nehmt PG10
* nutzt die eingebaute SR
* schaut Euch repmgr an https://repmgr.org/
* prüft, wie sich die Applikation verbindet (libpq, JDBC) und nutzt 
dessen Features für Autofailover
* schaut Euch noch Barman an https://www.pgbarman.org/index.html um auch 
eine gute Lösung für Backup zu haben
* repmgr und Barman sind von uns entwickelt und werden natürlich durch 
uns supportet, sind aber frei nutzbar
* falls ihr einen 24*7*365-Support braucht, fragt uns (bzw. mich)


Falls ihr der Meinung seid, ihr braucht BDR: Version 1 ist frei 
verfügbar, würde ich aber nicht (mehr) empfehlen. Versionen 2 und 3 
benötigen einen Supportvertrag mit uns. Kein Schnäppchen, aber 
erstklassig und auch wirklich sinnvoll. Wir entdecken durch BDR z.B. 
immer mal wieder Bugs direkt im PG-Core, und wer BDR einsetzt hat dazu 
auch eine kritische Anwendung und braucht dazu auch den Support von uns.
Natürlich finanzieren wir auch die weitere Entwicklung von BDR durch 
solche Supportverträge.


Andreas

-- 
2ndQuadrant - The PostgreSQL Support Company.
www.2ndQuadrant.com