You are here

Wie verhält sich Galera Cluster mit vielen Knoten?

Kürzlich hatte ich die Gelegenheit ganz viele Linux Systeme (VMs mit Rocky Linux 9) aus einer unserer regelmässig stattfindenden Galera Cluster Schulungen eine Woche lang ganz für mich alleine zur freien Verfügung zu haben. Und auf den Maschinen war auch schon ein MariaDB 11.4.4 mit Galera Cluster installiert.

Da ich schon lange mal ausprobieren wollte, wie sich ein Galera Cluster mit zunehmender Anzahl Knoten verhält, war jetzt die Gelegenheit dies mal auszuprobieren.

Die folgenden Fragestellung sollten beantwortet werden:

  • Wie verhält sich der Durchsatz eines Galera Clusters in Abhängigkeit der Anzahl Galera-Knoten?
  • Mit welcher Konfiguration erhalten wir den grössten Durchsatz?

Insgesamt wurde mit 5 verschiedenen Versuchs-Parameter experimentiert:

  • Anzahl Galera Knoten.
  • Anzahl Client Maschinen (= Instanzen).
  • Anzahl Threads pro Client (--threads=).
  • Anzahl Galera Threads (wsrep_slave_threads).
  • Laufzeit der Tests. Dieser Parameter wurde variiert weil einige Tests während des Laufs abgebrochen sind. Möglicherweise kann mit einer kleineren Rate (--rate) im Lasttest dieser Parameter eliminiert werden. Wie sich zeigte, hatte er sehr wohl einen Einfluss auf das Resultat bzw. den gemessenen Durchsatz (z.B. Test 4b und 5 bzw. 18 und 19).

Insgesamt wurde 35 verschiedene Tests gefahren. Siehe Rohdaten.

Durchsatz in Abhängigkeit der Anzahl Galera Knoten

graph

Throughput related to # nodes
Test# gal nodes# threads/clientruntime [s]tpsruntime [s]
718180596.3180
828180567.8180
938180531.9180
1148180495.2180
1258180492.2180
1368180502.9180
1478180459.5180
1588180458.6180
1698180429.2180

Der Durchsatz im Galera Cluster nahm leicht von 600 tps auf 430 tps ab (28%) wenn die Anzahl Knoten von 1 auf 9 erhöht wurde.

Durchsatz in Abhängigkeit der Anzahl Verbindungen

Hier wurde vor allem mit der Anzahl der Clients und der Threads pro Client variiert. Bei 30 - 40 Connections scheint in diesem Setup das Optimum zu liegen. Das variieren der Anzahl Galera Threads (wsrep_slave_threads) scheint in unserem Fall nicht sonderlich viel bewirkt zu haben. Wesentlich mehr als 1200 tps scheint das System nicht herzugeben. Insbesondere haben auch die Maschinen der beschriebene Galera Knoten nicht mehr allzu viel CPU Idle Zeit gehabt.

graph

Total # connections vs. throughput
Test# client nodes# threads/client# con tot# gal threadsruntime [s]tps
161881180429.2
1728161180684.5
1838241180603.8
1938241120925.2
2038241120919.8
21483211201081.1
22584011201196.0
23584041201132.2
23b584081201106.0
245168041201233.8
2553216041201095.7

Durchsatz in Abhängigkeit aller möglichen Parametern

Mit dem weiteren Variieren der Parameter insbesondere dem Reduzieren der Anzahl Galera Knoten von 9 auf 3 konnte der Durchsatz von knapp unter 1200 auf knapp über 1400 tps weiter erhöht werden.

graph

Throughput related to various different parameters
Test# gal nodes# client nodes# threads/client# con tottps
23958401132.2
23b958401106.0
249516801233.8
2595321601095.7
2685321601132.4
2775321601207.6
286516801333.3
29558401278.6
30558401281.5
31458401374.1
32358401304.3
33368481428.9

Es scheint also, mit gegebener Hardware irgendwo ein Optimum zu geben welches sich um 3 Galera Knoten und ca 40 Connections befindet. Genauere Abklärungen wären hier spannend...

Statistische Versuchsplanung / Design of Experiments (DoE)

Hier wäre es noch spannend mit der Methode der statistischen Versuchsplanung zu arbeiten um dieses Optimum genauer zu bestimmen bzw. schneller zu finden.

Harware Spezifikation

VM's von Hetzner: CX22 (2 vCPU, 4 Gibyte RAM (effektiv: 3.5 Gibyte (warum das?)), 40 Gibyte Disk)

Architecture:             x86_64
  CPU op-mode(s):         32-bit, 64-bit
  Address sizes:          40 bits physical, 48 bits virtual
  Byte Order:             Little Endian
CPU(s):                   2
  On-line CPU(s) list:    0,1
Vendor ID:                GenuineIntel
  BIOS Vendor ID:         QEMU
  Model name:             Intel Xeon Processor (Skylake, IBRS, no TSX)
    BIOS Model name:      NotSpecified
    CPU family:           6
    Model:                85
    Thread(s) per core:   1
    Core(s) per socket:   2
    Socket(s):            1
    Stepping:             4
    BogoMIPS:             4589.21
    Flags:                fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2a
                          pic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault pti ssbd ibrs ibpb fsgsbase bmi1 avx2 smep bmi2 erms invpcid avx512f avx512dq rdseed adx smap clwb avx512cd avx512bw avx512vl xs
                          aveopt xsavec xgetbv1 xsaves arat pku ospke md_clear
Virtualization features:
  Hypervisor vendor:      KVM
  Virtualization type:    full
Caches (sum of all):
  L1d:                    64 KiB (2 instances)
  L1i:                    64 KiB (2 instances)
  L2:                     8 MiB (2 instances)
  L3:                     16 MiB (1 instance)

Benchmark-Tool / Last-Generator

Als Last-Generator wurde sysbench verwendet.

# dnf install epel-release
# dnf install sysbench

Jeder Client läuft auf seinem eigenen Schema um Galera Cluster Konflikte zu vermeiden. Dies ist in der Realität nicht in jedem Fall gegeben, stellt aber für Galera den optimalen Fall dar.

SQL> CREATE DATABASE sbtest<n>;

Jeder Client verbindet sich auf einen anderen Galera Knoten (1 - 6 Clients verteilt auf 1 - 9 Galera Knoten).

GALERA_IP=<galera_ip>
DATABASE=sbtest<n>

# sysbench oltp_common --mysql-host=${GALERA_IP} --mysql-user=app --mysql-password=secret --mysql-db=${DATABASE} --db-driver=mysql prepare
# sysbench oltp_read_write --time=180 --db-driver=mysql --mysql-host=${GALERA_IP} --mysql-user=app --mysql-password=secret --mysql-db=${DATABASE} --threads=8 --rate=1000 --report-interval=1 run
# sysbench oltp_common --mysql-host=${GALERA_IP} --mysql-user=app --mysql-password=secret --mysql-db=${DATABASE} --db-driver=mysql cleanup

MariaDB und Galera Konfiguration

[server]

binlog_format = row
innodb_autoinc_lock_mode = 2
innodb_flush_log_at_trx_commit = 2
query_cache_size = 0
query_cache_type = 0

wsrep_on = on
wsrep_provider = /usr/lib64/galera-4/libgalera_smm.so
wsrep_cluster_address = "gcomm://10.0.0.2,10.0.0.3,10.0.0.4,10.0.0.5,10.0.0.6,10.0.0.7,10.0.0.8,10.0.0.9,10.0.0.10,10.0.0.11,10.0.0.12,10.0.0.13,10.0.0.14,10.0.0.15,10.0.0.16,10.0.0.17"
wsrep_cluster_name = 'Galera Cluster'
wsrep_node_address = 10.0.0.2
wsrep_sst_method = rsync
wsrep_sst_auth = sst:secret

Rohdaten