PostgreSQL benchmark na FreeBSD, CentOS, Ubuntu Debian a openSUSE

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:

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