V tomto poste predstavím výsledky benchmarku, nedávno vydananej databázy PostgreSQL verzie 10.1. DB som benchmarkoval postupne na týchto OS (všetky sú 64-bitové):
- Ubuntu 16.04, kernel 4.10.0-38-generic
- openSUSE 42.3, kernel 4.4.87-25-default
- CentOS 7.4, kernel 3.10.0-693.2.2.el7.x86_64
- Debian 9.2, kernel 4.9.0-4-amd64
- FreeBSD 11.1
Metodika testovania
Cieľom benchmarku bolo zmerať výkon PostgreSQL v podmienkach podobajúcich sa (typickému) produkčnému nasadeniu:
- klienti sa pripájajú cez connection pool, ktorý zabezpečuje, že neprichádza k ustavičným reconnectom do DB (nepoužil som connection pool, ale pri pgbench som vynechal parameter -C)
- klienti sa pripájajú po sieti a nie prostredníctvom unix socket-u
- adresár s PostgreSQL dátami je na RAID1 mirror-ovanom disku
Na každom z testovaných OS bola vytvorená benchmarking databáza vo veľkosti ~74GiB:
pgbench -i -s 5000 pgbench
Testovacia infraštruktúra pozostávala z dvoch dedikovaných serverov prepojených 1 Gbit/s linkou:
- [EX41-SSD] (https://www.hetzner.com/dedicated-rootserver/ex41-ssd): Intel i7-6700, 4 cores, 8 threads, 32GB DDR4 RAM, generujúci SQL dopyty prostredníctvom pgbench
- [PX121-SSD] (https://www.hetzner.com/dedicated-rootserver/px121-ssd): Intel Xeon E5-1650 v3, 6 cores, 12 threads, 256GB DDR4 ECC RAM, 2 x 480 GB SATA 6 Gb/s Data Center Series SSD, PostgreSQL server
Zaujímali ma tieto kombinácie testov:
- 32GiB read only: read only test (benchmarkuje iba prostredníctvom select-ov a neprichádza k modifikáciám dát v DB), dataset sa nezmestí do PostgreSQL cache
- 200GiB read only: read only test, dataset sa zmestí do PostgreSQL cache
- 32GiB TCP-B: read write, dataset sa nezmestí do PostgreSQL cache
- 200GiB TCP-B: read write, dataset sa zmestí do PostgreSQL cache
pgbench setup
Na generovanie záťaže bol použitý program pgbench vo verzii 10.1 bežiaci na separátnom FreeBSD 11.1 stroji. Testovací skript pozostával z troch častí: vacuum+warmup, read only testovanie a read write testovanie. Pri read write testovaní bol pred každým testom vykonaný vacuum pgbench tabuliek (prepínač -v). Počas testu som postupne zvyšoval počet konkurentných klientov pristupujúcich k databáze.
#!/bin/sh
THREADS=8
DURATION=1800
PGIP=192.168.1.120
# warmup
pgbench -h ${PGIP} -U pgbench -j ${THREADS} -c 10 -T ${DURATION} -S -v pgbench
for clients in 1 10 20 30 40 50 60 70 80 90 100 110 120
do
echo "RO ${clients}"
pgbench -h ${PGIP} -U pgbench -j ${THREADS} -c ${clients} -T ${DURATION} -S pgbench > pgbench_ro_${clients}.log
done
for clients in 1 10 20 30 40 50 60 70 80 90 100 110 120
do
echo "RW ${clients}"
pgbench -h ${PGIP} -U pgbench -j ${THREADS} -c ${clients} -T ${DURATION} -v pgbench > pgbench_rw_${clients}.log
done
Setup PostgreSQL servera
V prípade Linux-ových ditribúcií bol PostgreSQL nainštalovaný na súborovom systéme ext4 na SSD diskoch zapojených v RAID1 prostredníctvom Linux-ového softvérového RAID-u (mdraid) s vypnutým atime. V prípade FreeBSD bol použitý súborový systém OpenZFS na SSD diskoch zapojených v RAID1. ZFS dataset s PostgreSQL dátami bol vytvorený s naledovnými parametrami:
zfs get recordsize,logbias,primarycache,atime,compression zroot/var/db/postgres
NAME PROPERTY VALUE SOURCE
zroot/var/db/postgres recordsize 8K local
zroot/var/db/postgres logbias throughput local
zroot/var/db/postgres primarycache all default
zroot/var/db/postgres atime off inherited from zroot
zroot/var/db/postgres compression lz4 local
Nastavenie samotného PostgreSQL servera bolo na všetkých OS totožné s výnimkou ciest k adresárom s dátami (každý OS používa inú adresárovú štruktúru). Obsah postgresql.conf (iba zaujímavé časti) v prípade 32GiB inštancie bol nasledovný:
autovacuum = off
default_statistics_target = 100
maintenance_work_mem = 1GB
checkpoint_completion_target = 0.9
effective_cache_size = 24GB
work_mem = 104MB
wal_buffers = 16MB
shared_buffers = 8GB
max_connections = 300
Obsah postgresql.conf pre 200GiB inštanciu:
autovacuum = off
default_statistics_target = 100
maintenance_work_mem = 2GB
checkpoint_completion_target = 0.9
effective_cache_size = 144GB
work_mem = 640MB
wal_buffers = 16MB
shared_buffers = 48GB
max_connections = 300
Benchmarking
Benchmark PostgreSQL som postupne spúšťal na piatich rôznych operačných systémoch, v dvoch módoch - read only a TCP-B (read write) a dvoch rôznych pamäťových profiloch. Test každého OS trval približne 30 hodín (nepočítajúc čas potrebný na setup OS). Výsledky z programu pgbench boli ukladané do súborov, ktoré som následne sparsoval a vyhodnotil.
Výsledky - Read Only
Výsledky - TCP-B
Zhodnotenie
Merania ukázali, že rozdiel medzi jednotlivými GNU/Linux distribúciami nie je veľmi výrazný. V prípade read only testu s miernym náskokom viedol openSUSE 42.3, naopak FreeBSD bol približne o 40% pomalší. Žiaľ nepodarilo sa mi zistiť čím je to spôsobené, pravdepodbne to je daň za ZFS featury.
Reálnejší obraz o výkone PostgreSQL na jednotlivých OS poskytol read write (TCP-B) benchmark. Tu bol spomedzi Linux-ových distribúcií najvýkonnejší Centos 7.4, najpomalší Debian 9.2. Pozitívne prekvapil FreeBSD 11.1. Napriek tomu, že ZFS je copy-on-write súborový systém, bol výkon PostgreSQL v porovnaní s CentOS 7.4 viac ako 2 násobný. Predpokladal som, že takýto rozdiel bol spôsobený overhead-om linuxového softvérového RAID-u, a preto som vykonal ešte tri benchmarky TCP-B pri 100 konkurentných klientoch, tentokrát bez softvérového RAID-u:
- FreeBSD 11.1 + UFS: 5623.86 TPS
- FreeBSD 11.1 + ZFS: 8331.85 TPS
- CentOS 7.4 + ext4: 8987.65 TPS
Z výsledkov vidieť neefektivitu linux-ového SW RAIDU (resp. efektivitu ZFS RAID-u). Výkon CentOS 7.4 je bez použitia SW RAID-u (pri TCP-B a 100 konkurentných klientoch) len o niečo vyšší ako výkon FreeBSD 11.1 pri použití ZFS RAID-u.
EDIT: diskusia na HN