Enterprise Grade High Availability mit Patroni - DOAG

Die Seite wird erstellt Ben Haupt
 
WEITER LESEN
Enterprise Grade High Availability mit Patroni - DOAG
Datenbank

     Enterprise Grade High
     Availability mit Patroni
                                                                                                               Julia Gugel, dbi services

     Mit Patroni steht im Bereich PostgreSQL eine hochverfügbare Open-Source-Lösung mit vielen Vorteilen
     zur Verfügung. Die kostenlose Lösung fodert allerdings ein gewisses Maß an Bastelfreude, denn sie liefert
     definitv keine „one-size-fits-all“- oder „plug-and-play“-Lösung. Eine Betrachtung des Setups und der wich-
     tigsten Operationen gibt Aufschluss über die Vor- und Nachteile dieser Lösung, insbesondere für Produk-
     tivumgebungen, die nahezu keine Ausfallzeiten erlauben.

     Wie oft im Open-Source-Bereich, gibt es    greSQL-Cluster zu erstellen und zu admi-     Aufbau eines Patroni-
     für PostgreSQL viele Möglichkeiten für     nistrieren. Entwickelt vom Zalando Tech      Clusters
     den Aufbau einer hochverfügbaren Lö-       Team, bewährt es sich auch für große
     sung. Je nachdem, welche Anforderungen     Cluster-Umgebungen. Patroni lässt sich       Patroni bietet für den Aufbau eines Clus-
     sich an das System ergeben, erweisen       mit einigen Konfigurationsparametern         ters eine hohe Flexibilität. Vom einfachen
     sich viele davon als schwer zu implemen-   als Backup, Replication und Restore Tool     Primary – Replica bis hin zu Primary – n
     tieren und zu administrieren.              einsetzen und hält im Zusammenspiel mit      Replicas ist patroniseitig alles möglich.
                                                etcd und HAProxy vielen Anforderungen        Mein Favorit als optimaler Minimal-Clus-
                                                einer Hochverfügbarkeitslösung stand.        ter: eine Lösung mit drei Servern, eine Pri-
     Was ist Patroni?                              Dabei ist Patroni keine Out-of-the-Box-   mary und zwei Replica-Datenbanken (sie-
                                                Lösung, sondern ein Template, das sich an    he Abbildung 1).
     Patroni ist ein Python-basiertes Open      die Bedürfnisse der entsprechenden Umge-        Für eine möglichst reibungslose Funk-
     Source Tool, um hochverfügbare Post-       bung und des Anwenders anpassen lässt.       tionsweise benötigt Patroni einige Tools:

40    www.aoug.at • www.doag.org • www.soug.ch
Enterprise Grade High Availability mit Patroni - DOAG
•   Distriburted Key Value Store
    Um Patroni als hochverfügbares Clus-
    ter zu nutzen, benötigt es einen Dis-
    tributed Key Value Store. Hierbei ste-
    hen etcd, zookeeper und consul zur
    Auswahl. Seit Version 2.0 kann Patroni
    auch mit pure Raft installiert werden.
    Da sich etcd als leicht zu initialisieren
    und administrieren erwiesen hat, ist
    es für mich die erste Wahl. Zu beach-
    ten: etcd benötigt immer eine ungera-
    de Anzahl von Servern, damit im Falle
    eines Ausfalls die neue Primary durch
    ein Quorum gewählt werden kann.
    Drei Server sind Minimum, nach oben
    gibt es keine Grenzen, solange die Zahl
    der etcd-Server ungerade ist.

•   Load Balancer
    Eine weitere Komponente für maxima-
    le Hochverfügbarkeit: ein Load Balan-
    cer. Patroni unterstützt jede Art von
    Load Balancer und bietet in der Doku-
    mentation eine Konfiguration für HAP-       Abbildung 1: Aufbau eines Patroni-Clusters (© Julia Gugel, dbi services)
    roxy an, mit dem sich ein „Single Point
    of Entry“ schaffen lässt.
                                                Setup eines Patroni-Clusters                           In den folgenden Schritten gehe ich
•   Watchdog                                                                                        von einem Cluster mit drei Knoten aus,
    Das Schlimmste für einen hochverfüg-        Das Setup eines Patroni-Clusters ist in             auf dem die PostgreSQL Binaries bereits
    baren Patroni-Cluster wären Trans-          wenigen Schritten erledigt. Es kann so-             installiert sind. All diese Knoten werden
    aktionen, die aufgrund mehrerer Pri-        wohl aus Packeten im Community Repo-                gleich aufgesetzt – mit entsprechender
    mary-Instanzen verloren gehen. Die          sitory als auch manuell installiert werden.         Vorbereitung lässt sich dies mit einem
    Ursachen für dieses „Split-Brain“-Pro-      Um maximale Flexibilität zu behalten, be-           Automatisierungstool umsetzen.
    blem liegen unter anderem in einem          vorzuge ich das manuelle Setup. Es benö-               Vorab werden einige Pakete für die
    Patroni Crash, einem zu langsamen           tigt mehrere manuelle Schritte und die              Einrichtung von Patroni installiert, diese
    Shutdown oder Memory-Problemen.             Erstellung von Konfigurationsdateien.               unterscheiden sich gegebenenfalls – je
    Um dies zu verhindern, muss Patroni
    gewährleisten, dass PostgreSQL kei-
    ne Transaktions-Commits annimmt,             yum install python3-pip python3-pyyaml bind-utils keepalived haproxy
    nachdem der DCS Leader Key abgelau-          chrony watchdog
    fen ist. Um dies zu garantieren, unter-
    stützt Patroni Watchdog Devices, die        Listing 1: Benötigte Packages für Patroni Setup
    ermöglichen, dass beispielsweise das
    komplette System zurückgesetzt wird,
    falls in einem vordefinierten Zeitrah-       192.168.22.201 Patroni1
    men keine Rückmeldung vom System             192.168.22.202 Patroni2
    eingeht. Für die meisten Use Cases ist       192.168.22.203 Patroni3
    die im Linux Kernel implementierte
    Software ausreichend.                       Listing 2: /etc/hosts-Datei

    cd ~
    wget https://github.com/etcd-io/etcd/releases/download/v{{etcd_version}}/etcd-v{{ etcd_version }}-linux-amd64.
    tar.gz
    tar axf etcd-v{{etcd_version}}--linux-amd64.tar.gz
    mkdir /u02/pgdata/etcd
    chmod 700 /u02/pgdata/etcd

Listing 3: Installation etcd

                                                                                                              Red Stack Magazin 04/2021          41
Enterprise Grade High Availability mit Patroni - DOAG
Datenbank

      name: Patroni1
      data-dir: /u02/pgdata/etcd
      enable-v2: true

      initial-advertise-peer-urls: http://192.168.22.201:2380
      listen-peer-urls: http://192.168.22.201:2380
      listen-client-urls: http://192.168.22.201:2379,http://localhost:2379
      advertise-client-urls: http://192.168.22.201:2379
      initial-cluster: patroni1=http://192.168.22.201:2380,patroni2=http://192.168.22.202:2380,patroni3=http:
      //192.168.22.203:2380

     Listing 4: etcd.conf-Datei

      su -
      cat /etc/systemd/system/etcd.service

      [Unit]
      Description=dbi services etcd service
      After=network.target

      [Service]
      User=postgres
      Type=notify
      ExecStart=/u01/app/postgres/local/dmk/bin/etcd --config-file /u01/app/postgres/local/dmk/etc/etcd.conf
      Restart=always
      RestartSec=10s
      LimitNOFILE=40000

      [Install]
      WantedBy=multi-user.target

     Listing 5: etcd-Service

     nach gewähltem Betriebssystem (siehe                 gibt keinen festen beziehungsweise vorge-            Hiermit sind alle Vorbereitungsschritte
     Listing 1).                                          schriebenen Platz.                                abgeschlossen, es kann mit der Installa-
         Im nächsten Schritt benötigt es Einträ-              Für die Konfiguration wird die etcd.          tion von Patroni selbst gestartet werden.
     ge im /etc/hosts-File, hierzu werden alle            conf-Datei erstellt (siehe Listing 4).            Dies ist vermutlich der heikelste Teil der
     Cluster-Knoten mit IP ergänzt (siehe Lis-                Dabei muss darauf geachtet werden,            Installation, da beachtet werden muss,
     ting 2). Alternativ dazu sind die entspre-           dass in Zeile 1 der Hostname des Servers          welches Kommando mit welchem Be-
     chenden Einträge im DNS.                             korrekt ist, zum Beispiel patroni1 für Knoten     nutzer ausgeführt wird. Sobald es hier zu
         Sind die Pakete in Listing 1 installiert, wird   1, patroni2 für Knoten 2 und so weiter. Die       Verwechslungen kommt, funktioniert die
     mit der Installation des Key Value Store be-         Datei kann an jedem beliebigen Ort abge-          Installation nicht wie gewünscht (siehe Lis-
     ziehungsweise etcd fortgefahren. Das Pa-             legt werden. Ich empfehle, die Berechtigung       ting 7).
     ket für etcd kann dazu von der GitHub-Seite          auf 0600 zu setzen. Anschließend wird der            Beim letzten Komando wird angege-
     von etcd-io heruntergeladen und anschlie-            etcd-Service erstellt, in dem die Konfigura-      ben, welcher Key Value Store verwendet
     ßend entpackt werden (siehe Listing 3).              tionsdatei referenziert wird (siehe Listing 5).   wird. Per Default werden die Patroni Bi-
         All das wird von dem Benutzer gemacht,               Sobald dieser erstellt ist, wird die sys-     naries im Home-Verzeichnis des Owners
     dem der Cluster später gehört, nicht als             temd-Konfiguration neu geladen und alle           unter ~/.local/bin abgelegt. Dieser Pfad
     root. Wo genau die Binaries entpackt wer-            benötigten Services können gestartet wer-         sollte dementsprechend in die PATH-Va-
     den, lässt sich individuell entscheiden. Es          den (siehe Listing 6).                            riable mit aufgenommen oder in einen

      systemctl      daemon-reload                         sudo su     –
      systemctl      enable etcd                           python3     -m pip install       --upgrade pip
      systemctl      enable watchdog                       sudo su     – postgres
      systemctl      start watchdog                        python3     -m pip install       --upgrade --user setuptools
      systemctl      start chronyd                         python3     -m pip install       --user psycopg2-binary
      systemctl      start etcd                            python3     -m pip install       --user Patroni[etcd]

     Listing 6: Starten aller benötigten Services         Listing 7: Installation Patroni

42     www.aoug.at • www.doag.org • www.soug.ch
Enterprise Grade High Availability mit Patroni - DOAG
scope: PG1
 name: patroni1

 restapi:
   listen: 192.168.22.201:8008
   connect_address: 192.168.22.201:8008

 etcd:
    hosts: 192.168.22.201:2379, 192.168.22.202:2379, 192.168.22.203:2379

 bootstrap:
   dcs:
 		    ttl: 30
 		    loop_wait: 10
 		    retry_timeout: 10
 		    maximum_lag_on_failover: 1048576
 		    postgresql:
 			       use_pg_rewind: true
 			use_slots: true
 			parameters:
 				          wal_level: 'hot_standby'
 				          hot_standby: "on"
 				          wal_keep_segments: 8
 				          max_replication_slots: 10
 				          wal_log_hints: "on"
 				          listen_addresses: '*'
 				          port: 5432
 				          logging_collector: 'on'
 				          log_truncate_on_rotation: 'on'
 				          log_filename: 'postgresql-%a.log'
 				          log_rotation_age: '1440'
 				          log_line_prefix: '%m - %l - %p - %h - %u@%d - %x'
 				          log_directory: 'pg_log'
 				          log_min_messages: 'WARNING'
 				          log_autovacuum_min_duration: '60s'
 				          log_min_error_statement: 'NOTICE'
 				          log_min_duration_statement: '30s'
 				          log_checkpoints: 'on'
 				          log_statement: 'ddl'
 				          log_lock_waits: 'on'
 				          log_temp_files: '0'
 				          log_timezone: 'Europe/Zurich'
 				          log_connections: 'on'
 				          log_disconnections: 'on'
 				          log_duration: 'on'
 				          client_min_messages: 'WARNING'
 				          wal_level: 'replica'
 				          hot_standby_feedback: 'on'
 				          max_wal_senders: '10'
 				          shared_buffers: '128MB'
 				          work_mem: '8MB'
 				          effective_cache_size: '512MB'
 				          maintenance_work_mem: '64MB'
 				          wal_compression: 'off'
 				          max_wal_senders: '20'
 				          shared_preload_libraries: 'pg_stat_statements'
 				          autovacuum_max_workers: '6'
 				          autovacuum_vacuum_scale_factor: '0.1'
 				          autovacuum_vacuum_threshold: '50'
 				          archive_mode: 'on'
 				          archive_command: '/bin/true'
 				          wal_log_hints: 'on'
 #			      recovery_conf:
 #				         restore_command: cp ../wal_archive/%f %p

Listing 8, Teil 1: patroni.yml                                                        Siehe nächste Seite ->

                                                                           Red Stack Magazin 04/2021           43
Datenbank

          initdb:
          - encoding: UTF8
          - data-checksums

          pg_hba
          - host replication replicator 192.168.22.0/24 md5
          - host all all 192.168.22.0/24 md5

       users:
      		 admin:
      			password: admin
      			options:
      				        - createrole
      				        - createdb
      		 replicator:
      			     password: postgres
      			options:
      				        - superuser

      postgresql:
        listen: 192.168.22.201:5432
        connect_address: 192.168.22.201:5432
        data_dir: /u02/pgdata/13/PG1/
        bin_dir: /u01/app/postgres/product/13/db_2/bin
        pgpass: /u01/app/postgres/local/dmk/etc/pgpass0
        authentication:
      		 replication:
      			username: replicator
      			       password: postgres
      		 superuser:
      			       username: postgres
      			       password: postgres
        parameters:
      		    unix_socket_directories: '/tmp'

      watchdog:
        mode: automatic
        device: /dev/watchdog
        safety_margin: 5

      tags:
      		       nofailover: false
      		       noloadbalance: false
      		       clonefrom: false
      		       nosync: false

     Listing 8, Teil 2: patroni.yml

     Ordner verlinkt werden, der bereits in der      gurierten Parametern gestartet und die           Abbildung 3 gibt eine Übersicht darü-
     PATH- Variable aufgeführt ist.                  Installation des Patroni-Clusters ist abge-   ber, wie ein Switchover von Node 1 auf
         Im letzten Schritt werden nun die           schlossen.                                    Node 2 aussehen kann. Bei einem Reboot
     Patroni-Konfiguration und der Patroni-             Sobald der Service auf allen (drei) Ser-   des Primary Node wird sofort ein Failover
     Service erstellt. Hierzu wird in einem          vern gestartet ist, können der Patroni und    gemacht; der ehemalige Leader wird, so-
     beliebigen Verzeichnis (zum Beispiel /          der etcd-Status überprüft werden (siehe       bald er wieder gestartet ist, als neue Repli-
     etc/patroni) auf allen drei Servern eine        Abbildung 2).                                 ca wieder eingebunden und der WAL (wri-
     YAML-Datei erstellt. Diese enthält alle                                                       te ahead log) Lag sollte nicht zu groß sein.
     notwendigen Details über den Aufbau
     des etcd-Clusters und auch die Parame-          Patroni Operations
     ter für die PostgreSQL-Instanzen (siehe                                                       Patroni – „Enterprise Grade“?
     Listing 8).                                     Die wohl wichtigsten Operationen bei
         Mit der Erstellung des Patroni-Service      einem Patroni-Cluster sind definitiv der      Was genau macht Patroni jetzt aber zu der
     (siehe Listing 9) und anschließendem Start      Switchover und der Failover. Beide wer-       Open-Source-Enterprise-Grade-Lösung?
     des Service (siehe Listing 10) wird der Post-   den mit einem sehr ähnlichen Befehl aus-      Dafür gibt es mehrere Punkte, die genannt
     greSQL-Cluster mit den in Listing 8 konfi-      geführt (siehe Listing 11).                   werden können.

44     www.aoug.at • www.doag.org • www.soug.ch
/etc/systemd/system/patroni.service

 [Unit]
 Description=dbi services patroni service
 After=etcd.service syslog.target network.target

 [Service]
 User=postgres
 Group=postgres
 Type=simple
 ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog
 ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog
 ExecStart=/u01/app/postgres/local/dmk/bin/patroni /u01/app/postgres/local/dmk/etc/patroni.yml
 ExecReload=/bin/kill -s HUP $MAINPID
 KillMode=process
 Restart=no
 TimeoutSec=30

 [Install]
 WantedBy=multi-user.target

Listing 9: patroni.service

 systemctl daemon-reload                             patronictl -d etcd://192.168.22.203:2379 switchover PG1
 systemctl enable patroni                            patronictl -d etcd://192.168.22.202:2379 failover PG1
 systemctl start patroni
                                                   Listing 11: Switchover and Failover des Patroni-Clusters
Listing 10: Starten und Initialisieren des
Patroni-Clusters
                                                   Replica automatisch wieder nachgefah-               zu einer Replica. Hierfür werden keinerlei
                                                   ren. Sollte der Unterschied zwischen Pri-           manuelle Schritte benötigt, wie zum Bei-
    Sollte die Verbindung aufgrund eines           mary und Replica zu groß geworden sein,             spiel einen recovery_command ins post-
Switchover oder Failover verloren gehen,           ist es allerdings möglich, dass die Replica         gresql.conf zu schreiben, damit die Ins-
gibt es eine kurze Meldung, dass die Ver-          sich nicht mehr automatisch aktualisiert.           tanz im Recovery Mode gestartet wird.
bindung fehlgeschlagen ist. Anschließend           Dann muss die alte Instanz gelöscht und             Auch dies gilt, wie oben, solange der WAL
wird mit dem nächsten SQL Statement                die Replica neu initialisiert werden. Dies          Gap nicht zu groß geworden ist.
die Verbindung sofort wieder neu aufge-            erfolgt mit dem Restart des Patroni-Ser-               Patroni-Cluster sind horizontal skalier-
baut. Voraussetzung hierfür ist lediglich          vice. Ich empfehle vor dem erneuten Re-             bar. Eine weitere Instanz kann problem-
die Anmeldung über die im HAProxy de-              initialisieren zu überprüfen, welche Para-          los in das bereits bestehende Cluster auf-
finierte Host-Port-Kombination.                    meter seit dem initialen Setup geändert             genommen werden.
    Für den Fall, dass eine Replica für eine       wurden.                                                Besteht bereits ein etcd-Cluster auf ei-
bestimmte Zeit nicht mit der Primary kom-              Anders als bei anderen Lösungen wird            nem Server, kann parallel dazu ohne gro-
munizieren kann (zum Beispiel aufgrund             die alte Primary nach einem Failover be-            ßen Aufwand ein zweiter Patroni-Clus-
einer Netzwerkunterbrechung), wird die             ziehungsweise Switchover automatisch                ter aufgebaut werden. Hierzu kann die

Abbildung 2: Statusabfrage Patroni und etcd (© Julia Gugel, dbi services)

                                                                                                               Red Stack Magazin 04/2021             45
Datenbank

     Abbildung 3: Switchover Patroni (© Julia Gugel, dbi services)

     bestehende etcd-Konfiguration genutzt               ring des WAL Gap, um schnell reagieren         Namespace: /service/
     werden. Es benötigt einzig einen eindeu-            zu können.
     tigen Eintrag im patroni.yml (siehe Listing                                                       Listing 12: Eintrag für parallele Patroni-Cluster
     12) des bestehenden Patroni-Clusters, ein
     zweites patroni.yml mit eindeutigem Na-             Zusammenfassung
     men und einen zweiten Service, ebenfalls
     mit einem anderen Namen.                            Patroni ist mit seinem Aufbau und der ein-
        Durch den einfachen Switchover von               fachen Administration ein stabiles Werk-
     einem Node auf einen anderen können                 zeug zur Erstellung einer hochverfügbaren
     Minor-Version-Updates ohne Downtime                 Datenbankumgebung im Open-Source-Be-
     durchgeführt werden. Es kann ein Knoten             reich. Es verwendet dabei bereits etablier-
     nach dem anderen aktualisiert und im-               te Linux-Programme. Mag die Installation
     mer auf den Knoten gewechselt werden,               etwas aufwendiger sein, läuft das System
     der gerade nicht im Fokus des Upgrades              anschließend sehr zuverlässig. Patroni ist
     steht. Es sollte darauf geachtet werden,            defintiv in der Lage, den wachsenden An-
     ob sich Postgres-Parameter geändert ha-             forderungen des Business standzuhalten.
     ben, zum Beispiel beim Wechsel von Post-            Speziell aufgrund des unproblematischen
     greSQL Version 12 auf 13.                           Switchover und Failover zu einer anderen
                                                         Instanz ergibt diese kostenfreie Lösung,
                                                         meiner Meinung nach, auch für große Da-
     Grenzen                                             tenbanklandschaften Sinn.

     Wie auch bei PostgreSQL generell ist
     eine Primary-Primary-Architektur auch               Über die Autorin
     mit Patroni nicht möglich. Des Weiteren
     kann es auch bei einem entsprechend                 Julia Gugel ist Consultant im Open-Infra-
     großen WAL Gap nicht mehr automa-                   structure-Team und spezialisiert auf die
     tisch nachgefahren werden und die Re-               Bereiche PostgreSQL und Patroni sowie
     plica muss neu aufgebaut werden. Ich                Linux, davor war sie im Bereich Oracle-                        Julia Gugel
     empfehle ein entsprechendes Monito-                 Datenbanken tätig.                                   julia.gugel@dbi-services.com

46     www.aoug.at • www.doag.org • www.soug.ch
Sie können auch lesen