Wer meiner kleinen Reise in den Hasenbau aus Patroni, pg_auto_failover und Citus bis hierhin gefolgt ist, konnte sich ungefähr denken, was jetzt noch kommen muß: Benchmarking. Und auch dafür gibt es etwas im Citus Repository: Citus-Benchmark.
Die Installation erfolgt einfach nach Readme z. B. in einer Ubuntu Focal VM. Citus-Benchmark verwendet den HammerDB Benchmark und den CHbenCHmark in einem Rutsch. Der HammerDB Benchmark wird i. W. über die Anzahl der Warehouses und die Anzahl der virtuellen User parameterisiert. Für einen schnellen Durchlauf sollte man diese Werte anpassen - sonst vergeht sehr viel Zeit mit dem Anlegen der Warehouses und der User. Das entspricht den Werten
pg_count_ware
pg_num_vu
Am Ende wirft Citus-Benchmark im Log eine Zeile aus, die bei mir beim ersten Lauf so aussah:
Vuser 1:TEST RESULT : System achieved 3199 NOPM from 7441 PostgreSQL TPM
NOPM entspricht "New Operations per Minute" und TPM "Transactions per Minute". Dabei liegt NOPM meist bei einem Drittel bis zu 45% vom TPM Wert.
Den ersten Wert hatte ich mit einem Citus HA-Setup mit drei Worker-Clustern erreicht, wobei die Worker 2 GB Memory und eine unbehandelte Postgres-Konfiguration hatten.
Die SmartOS Container verwenden ZFS als Filesystem. Die ZFS-Parameter lassen sich in Triton für die einzelne Zone nicht verändern und sehen so aus:
[root@meinserver2 (my-dc-2) ~]# zfs get all /zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca
NAME PROPERTY VALUE SOURCE
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca type filesystem -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca creation Fr. Apr. 28 13:17 2023 -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca used 18,3M -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca available 200G -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca referenced 950M -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca compressratio 3.74x -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca mounted yes -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca origin zones/8b416b22-3421-4c0f-b299-99a72832df6d@final -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca quota 200G local
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca reservation none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca recordsize 128K default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca mountpoint /zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca sharenfs off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca checksum on default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca compression lz4 inherited from zones
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca atime off inherited from zones
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca devices off local
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca exec on default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca setuid on default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca readonly off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca zoned off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca snapdir hidden default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca aclmode discard default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca aclinherit restricted default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca createtxg 30632339 -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca canmount on default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca xattr on default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca copies 1 default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca version 5 -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca utf8only off -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca normalization none -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca casesensitivity sensitive -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca vscan off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca nbmand off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca sharesmb off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca refquota none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca refreservation none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca guid 7176302598233027976 -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca primarycache all default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca secondarycache all default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca usedbysnapshots 0 -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca usedbydataset 18,3M -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca usedbychildren 0 -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca usedbyrefreservation 0 -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca logbias latency default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca dedup off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca mlslabel none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca sync standard default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca dnodesize legacy default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca refcompressratio 2.20x -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca written 18,3M -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca logicalused 63,4M -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca logicalreferenced 1,97G -
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca filesystem_limit none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca snapshot_limit none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca filesystem_count none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca snapshot_count none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca redundant_metadata all default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca special_small_blocks 0 default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca encryption off default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca keylocation none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca keyformat none default
zones/0b0f3858-a66b-4773-bdf3-1f77f70063ca pbkdf2iters 0 default
Die meisten Parameter, die im Zusammenhang mit den Betrieb von Postgres genannt werden, haben schon die richtige Einstellung (recordsize
, compression
, etc.). Auf Datenbankseite wurden folgende Werte zur Leistungsverbesserung empfohlen:
max_connections
habe ich auf von 100 auf 400 gesetztfull_page_writes
aufoff
max_prepared_transactions
habe ich auf 400 gesetzt, weil Patroni sonst offenbar dort 400400 einträgt (möglicherweise ein Patroni Bug)- 8 GB Memory statt 2 GB - danach dann
shared_buffers
auf2GB
hochgesetzt wal_sync_method
auffdatasync
- wurde für Solaris/SmartOS empfohlen
Die Werte trägt man einfach in die patroni.yml
Datei bzw. das entsprechende Template ein:
scope: ${consul_scope}
namespace: ${consul_namespace}
name: ${hostname}
restapi:
listen: ${listen_ip}:8008
connect_address: ${listen_ip}:8008
consul:
host: localhost:8500
register_service: true
citus:
group: 3
database: citus
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
parameters:
max_connections: '400'
full_page_writes: 'off'
max_prepared_transactions: '400'
shared_buffers: '2GB'
wal_sync_method: 'fdatasync'
Patroni trägt die Werte dann in die postgresql.conf
ein und initialisiert die Datenbank dann damit.
Auf diese Weise kam bei drei Worker Clustern dann folgender Wert zustande:
Vuser 1:TEST RESULT : System achieved 26708 NOPM from 61595 PostgreSQL TPM
Ich habe jetzt noch ein viertes Cluster dazugestellt und den Test nochmal angeworfen...
Es war gar nicht so einfach, den Wert nochmal zu erreichen. Ohne Änderung - einfach nur mit einem vierten Worker-Cluster - hat er sich sogar auf ca. 24000 NOPM
verschlechtert. Ein Upgrade auf Citus 11.3.0 hat auch keine Veränderung gebracht. Eine Erhöhung der shared_buffers
auf 500MB auf den Coordinator Nodes brachte auch keine Verbesserung.
Erst als ich für die Coordinator Nodes 4GB Arbeitsspeicher eingestellt und damit dann 1GB für shared_buffers
konfigurieren konnte, ließ sich der Wert (fast) wieder erreichen: Vuser 1:TEST RESULT : System achieved 26423 NOPM from 60946 PostgreSQL TPM
.
Es scheint also nicht automatisch so zu sein, daß mit mehr Worker Clustern bei gleichbleibender Workload mehr zu schaffen ist. Mal sehen, wie das mit mehr Warehouses und mehr virtuellen Usern aussieht.
Auch da ergibt sich kein anderes Bild: Mehr User (250) und mehr Warehouses (300) ergeben bei vier Worker Clustern Vuser 1:TEST RESULT : System achieved 20989 NOPM from 48403 PostgreSQL TPM
. Möglicherweise muß man da noch mehr Parameter ändern.
Ok - nun habe ich das Setup in die erste OpenStack-Umgebung repliziert. Dort kann ich erstmal nur VMs provisionieren. Ich habe mich für Debian 11 mit acht GB RAM und 8 vCPUs entschieden. Das einzige Tuning, das ich vorgenommen habe ist, shared_buffers
auch auf zwei Gigabyte zu setzen. Weitere Tuning-Tipps muß ich erst noch ermitteln. Das Ergebnis war dementsprechend ernüchternd: Vuser 1:TEST RESULT : System achieved 8148 NOPM from 18827 PostgreSQL TPM
.
Bessere Hardware bringt aber offenbar auch bessere Ergebnisse. Dasselbe Setup in einer produktiven OpenStack-Umgebung liefert: TEST RESULT : System achieved 31667 NOPM from 72774 PostgreSQL TPM
. Wie gesagt - Postgres noch weitgehend ungetuned.