Den här bloggen startar en multi-serie som dokumenterar min resa med benchmarking av PostgreSQL i molnet.
Den första delen innehåller en översikt över benchmarkingverktyg och kickstartar det roliga med Amazon Aurora PostgreSQL.
Välja PostgreSQL-molntjänstleverantörer
För ett tag sedan stötte jag på AWS benchmark-proceduren för Aurora och tänkte att det skulle vara riktigt coolt om jag kunde ta det testet och köra det på andra molnvärdsleverantörer. Till Amazons förtjänst är AWS den enda större bidragsgivaren till PostgreSQL-utvecklingen av de tre mest kända leverantörerna av verktygsdatorer – AWS, Google och Microsoft – och den första som erbjuder hanterad PostgreSQL-tjänst (som går tillbaka i november 2013).
Medan hanterade PostgreSQL-tjänster också är tillgängliga från en uppsjö av PostgreSQL-värdleverantörer, ville jag fokusera på de tre nämnda leverantörerna av molndatorer eftersom deras miljöer är där många organisationer som letar efter fördelarna med cloud computing väljer att köra sina applikationer, förutsatt att de har den nödvändiga kunskapen om att hantera PostgreSQL. Jag är övertygad om att i dagens IT-landskap skulle organisationer som arbetar med kritiska arbetsbelastningar i molnet ha stor nytta av tjänsterna från en specialiserad PostgreSQL-tjänsteleverantör, som kan hjälpa dem att navigera i den komplexa världen av GUCS och myriader av SlideShare-presentationer.
Välja rätt benchmarkverktyg
Benchmarking PostgreSQL dyker upp ganska ofta på e-postlistan för prestanda, och som betonats otaliga gånger är testerna inte avsedda att validera en konfiguration för en verklig applikation. Det är dock viktigt att välja rätt benchmarkverktyg och parametrar för att få meningsfulla resultat. Jag förväntar mig att varje molnleverantör tillhandahåller rutiner för benchmarking av sina tjänster, särskilt när den första molnupplevelsen kanske inte börjar på rätt fot. Den goda nyheten är att två av de tre spelarna i detta test har inkluderat riktmärken i sin dokumentation. AWS Benchmark Procedure för Aurora-guiden är lätt att hitta, tillgänglig direkt på Amazon Aurora Resources-sidan. Google tillhandahåller ingen guide som är specifik för PostgreSQL, men Compute Engine-dokumentationen innehåller en belastningstestguide för SQL Server baserad på HammerDB.
Följande är en sammanfattning av benchmarkverktyg baserat på deras referenser som är värda att titta på:
- AWS Benchmark som nämns ovan är baserat på pgbench och sysbench.
- HammerDB, som också nämnts tidigare, diskuteras i ett nyligen inlägg på pgsql-hackers list.
- TPC-C-tester baserade på oltpbench som antytts i denna andra diskussion om pgsql-hackers.
- benchmarksql är ännu ett TPC-C-test som användes för att validera ändringarna av B-Tree-siddelningar.
- pg_ycsb är det nya barnet i stan, förbättras på pgbench och används redan av några av PostgreSQL-hackarna.
- pgbench-tools som namnet antyder är baserat på pgbench och även om det inte har fått några uppdateringar sedan 2016, är det produkten av Greg Smith, författaren till PostgreSQL High Performance-böcker.
- join order benchmark är ett benchmark som testar frågeoptimeraren.
- pgreplay som jag stötte på när jag läste kommandotolksbloggen är så nära det kan komma att benchmarka ett verkligt scenario.
En annan punkt att notera är att PostgreSQL ännu inte är väl lämpad för TPC-H benchmark-standarden, och som nämnts ovan måste alla verktyg (förutom pgreplay) köras i TPC-C-läge (pgbench är standard för det).
För syftet med den här bloggen tyckte jag att AWS Benchmark Procedure för Aurora är en bra start helt enkelt för att den sätter en standard för molnleverantörer och är baserad på ofta använda verktyg.
Jag använde också den senaste tillgängliga PostgreSQL-versionen vid den tiden. När du väljer en molnleverantör är det viktigt att ta hänsyn till frekvensen av uppgraderingar, särskilt när viktiga funktioner som introduceras av nya versioner kan påverka prestandan (vilket är fallet för version 10 och 11 kontra 9). När detta skrivs har vi:
- Amazon Aurora PostgreSQL 10.6
- Amazon RDS för PostgreSQL 10.6
- Google Cloud SQL för PostgreSQL 9.6
- Microsoft Azure PostgreSQL 10.5
...och vinnaren här är AWS genom att erbjuda den senaste versionen (även om det inte är den senaste, som när detta skrivs är 11.2).
Konfigurera benchmarkingmiljön
Jag bestämde mig för att begränsa mina tester till genomsnittlig arbetsbelastning av ett par anledningar:För det första är de tillgängliga molnresurserna inte identiska mellan olika leverantörer. I guiden är AWS-specifikationerna för databasinstansen 64 vCPU / 488 GiB RAM / 25 Gigabit Network, medan Googles maximala RAM för alla instansstorlekar (valet måste ställas in på "custom" i Google Calculator) är 208 GiB, och Microsofts Business Critical Gen5 med 32 vCPU kommer med endast 163 GiB). För det andra bringar pgbench-initieringen databasstorleken till 160 GiB, vilket i fallet med en instans med 488 GiB RAM sannolikt kommer att lagras i minnet.
Dessutom lämnade jag PostgreSQL-konfigurationen orörd. Anledningen till att hålla fast vid molnleverantörens standardvärden är att en hanterad tjänst förväntas prestera någorlunda bra när den stressas av ett standardriktmärke. Kom ihåg att PostgreSQL-communityt kör pgbench-tester som en del av releasehanteringsprocessen. Dessutom nämner inte AWS-guiden några ändringar av den förinställda PostgreSQL-konfigurationen.
Som förklaras i guiden applicerade AWS två patchar på pgbench. Eftersom korrigeringsfilen för antalet klienter inte gällde rent på 10.6-versionen av PostgreSQL och jag inte ville lägga tid på att fixa det, begränsades antalet klienter till maximalt 1 000.
Guiden anger ett krav på att klientinstansen ska ha utökat nätverk aktiverat – för den här instanstypen är det standard:
[[email protected] ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 0a:cd:ee:40:2b:e6 brd ff:ff:ff:ff:ff:ff
inet 172.31.19.190/20 brd 172.31.31.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::8cd:eeff:fe40:2be6/64 scope link
valid_lft forever preferred_lft forever
[[email protected] ~]$ ethtool -i eth0
driver: ena
version: 2.0.2g
firmware-version:
bus-info: 0000:00:03.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
>>> aws (master *%) ~ $ aws ec2 describe-instances --instance-ids i-0ee51642334c1ec57 --query "Reservations[].Instances[].EnaSupport"
[
true
]
Kör benchmark på Amazon Aurora PostgreSQL
Under själva löpningen bestämde jag mig för att göra ytterligare en avvikelse från guiden:istället för att köra testet i 1 timme, ställ in tidsgränsen till 10 minuter, vilket allmänt accepteras som ett bra värde.
Kör #1
Specifikationer
- Detta test använder AWS-specifikationerna för både klient- och databasinstansstorlekar.
- Kunddator:On Demand Memory Optimized EC2-instans:
- vCPU:32 (16 kärnor x 2 trådar/kärna)
- RAM:244 GiB
- Lagring:EBS-optimerad
- Nätverk:10 Gigabit
- DB-kluster:db.r4.16xlarge
- vCPU:64
- ECU (CPU-kapacitet):195 x [1,0-1,2 GHz] 2007 Opteron / Xeon
- RAM:488 GiB
- Lagring:EBS-optimerad (dedikerad kapacitet för I/O)
- Nätverk:14 000 Mbps Max bandbredd på ett 25 Gps-nätverk
- Kunddator:On Demand Memory Optimized EC2-instans:
- Databasinställningen inkluderade en replik.
- Databaslagring var inte krypterad.
Utföra tester och resultat
- Följ instruktionerna i guiden för att installera pgbench och sysbench.
- Redigera ~/.bashrc för att ställa in miljövariablerna för databasanslutningen och nödvändiga sökvägar till PostgreSQL-bibliotek:
export PGHOST=aurora.cluster-ctfirtyhadgr.us-east-1.rds.amazonaws.com export PGUSER=postgres export PGPASSWORD=postgres export PGDATABASE=postgres export PATH=$PATH:/usr/local/pgsql/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgsql/lib
- Initiera databasen:
[[email protected] ~]# pgbench -i --fillfactor=90 --scale=10000 NOTICE: table "pgbench_history" does not exist, skipping NOTICE: table "pgbench_tellers" does not exist, skipping NOTICE: table "pgbench_accounts" does not exist, skipping NOTICE: table "pgbench_branches" does not exist, skipping creating tables... 100000 of 1000000000 tuples (0%) done (elapsed 0.05 s, remaining 457.23 s) 200000 of 1000000000 tuples (0%) done (elapsed 0.13 s, remaining 631.70 s) 300000 of 1000000000 tuples (0%) done (elapsed 0.21 s, remaining 688.29 s) ... 999500000 of 1000000000 tuples (99%) done (elapsed 811.41 s, remaining 0.41 s) 999600000 of 1000000000 tuples (99%) done (elapsed 811.50 s, remaining 0.32 s) 999700000 of 1000000000 tuples (99%) done (elapsed 811.58 s, remaining 0.24 s) 999800000 of 1000000000 tuples (99%) done (elapsed 811.65 s, remaining 0.16 s) 999900000 of 1000000000 tuples (99%) done (elapsed 811.73 s, remaining 0.08 s) 1000000000 of 1000000000 tuples (100%) done (elapsed 811.80 s, remaining 0.00 s) vacuum... set primary keys... done.
- Verifiera databasstorleken:
postgres=> \l+ postgres List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description ----------+----------+----------+-------------+-------------+-------------------+--------+------------+-------------------------------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | 160 GB | pg_default | default administrative connection database (1 row)
- Använd följande fråga för att verifiera att tidsintervallet mellan kontrollpunkter är inställt så att kontrollpunkter tvingas fram under 10 min körningen:
Resultat:SELECT total_checkpoints, seconds_since_start / total_checkpoints / 60 AS minutes_between_checkpoints FROM ( SELECT EXTRACT( EPOCH FROM ( now() - pg_postmaster_start_time() ) ) AS seconds_since_start, (checkpoints_timed+checkpoints_req) AS total_checkpoints FROM pg_stat_bgwriter) AS sub;
postgres=> \e total_checkpoints | minutes_between_checkpoints -------------------+----------------------------- 50 | 0.977392292333333 (1 row)
- Kör läs-/skrivarbetsbelastningen:
Utgång[[email protected] ~]# pgbench --protocol=prepared -P 60 --time=600 --client=1000 --jobs=2048
starting vacuum...end. progress: 60.0 s, 35670.3 tps, lat 27.243 ms stddev 10.915 progress: 120.0 s, 36569.5 tps, lat 27.352 ms stddev 11.859 progress: 180.0 s, 35845.2 tps, lat 27.896 ms stddev 12.785 progress: 240.0 s, 36613.7 tps, lat 27.310 ms stddev 11.804 progress: 300.0 s, 37323.4 tps, lat 26.793 ms stddev 11.376 progress: 360.0 s, 36828.8 tps, lat 27.155 ms stddev 11.318 progress: 420.0 s, 36670.7 tps, lat 27.268 ms stddev 12.083 progress: 480.0 s, 37176.1 tps, lat 26.899 ms stddev 10.981 progress: 540.0 s, 37210.8 tps, lat 26.875 ms stddev 11.341 progress: 600.0 s, 37415.4 tps, lat 26.727 ms stddev 11.521 transaction type: <builtin: TPC-B (sort of)> scaling factor: 10000 query mode: prepared number of clients: 1000 number of threads: 1000 duration: 600 s number of transactions actually processed: 22040445 latency average = 27.149 ms latency stddev = 11.617 ms tps = 36710.828624 (including connections establishing) tps = 36811.054851 (excluding connections establishing)
- Förbered sysbench-testet:
Utdata:sysbench --test=/usr/local/share/sysbench/oltp.lua \ --pgsql-host=aurora.cluster-ctfirtyhadgr.us-east-1.rds.amazonaws.com \ --pgsql-db=postgres \ --pgsql-user=postgres \ --pgsql-password=postgres \ --pgsql-port=5432 \ --oltp-tables-count=250\ --oltp-table-size=450000 \ prepare
sysbench 0.5: multi-threaded system evaluation benchmark Creating table 'sbtest1'... Inserting 450000 records into 'sbtest1' Creating secondary indexes on 'sbtest1'... Creating table 'sbtest2'... ... Creating table 'sbtest250'... Inserting 450000 records into 'sbtest250' Creating secondary indexes on 'sbtest250'...
- Kör sysbench-testet:
Utdata:sysbench --test=/usr/local/share/sysbench/oltp.lua \ --pgsql-host=aurora.cluster-ctfirtyhadgr.us-east-1.rds.amazonaws.com \ --pgsql-db=postgres \ --pgsql-user=postgres \ --pgsql-password=postgres \ --pgsql-port=5432 \ --oltp-tables-count=250 \ --oltp-table-size=450000 \ --max-requests=0 \ --forced-shutdown \ --report-interval=60 \ --oltp_simple_ranges=0 \ --oltp-distinct-ranges=0 \ --oltp-sum-ranges=0 \ --oltp-order-ranges=0 \ --oltp-point-selects=0 \ --rand-type=uniform \ --max-time=600 \ --num-threads=1000 \ run
sysbench 0.5: multi-threaded system evaluation benchmark Running the test with following options: Number of threads: 1000 Report intermediate results every 60 second(s) Random number generator seed is 0 and will be ignored Forcing shutdown in 630 seconds Initializing worker threads... Threads started! [ 60s] threads: 1000, tps: 20443.09, reads: 0.00, writes: 81834.16, response time: 68.24ms (95%), errors: 0.62, reconnects: 0.00 [ 120s] threads: 1000, tps: 20580.68, reads: 0.00, writes: 82324.33, response time: 70.75ms (95%), errors: 0.73, reconnects: 0.00 [ 180s] threads: 1000, tps: 20531.85, reads: 0.00, writes: 82127.21, response time: 70.63ms (95%), errors: 0.73, reconnects: 0.00 [ 240s] threads: 1000, tps: 20212.67, reads: 0.00, writes: 80861.67, response time: 71.99ms (95%), errors: 0.43, reconnects: 0.00 [ 300s] threads: 1000, tps: 19383.90, reads: 0.00, writes: 77537.87, response time: 75.64ms (95%), errors: 0.75, reconnects: 0.00 [ 360s] threads: 1000, tps: 19797.20, reads: 0.00, writes: 79190.78, response time: 75.27ms (95%), errors: 0.68, reconnects: 0.00 [ 420s] threads: 1000, tps: 20304.43, reads: 0.00, writes: 81212.87, response time: 73.82ms (95%), errors: 0.70, reconnects: 0.00 [ 480s] threads: 1000, tps: 20933.80, reads: 0.00, writes: 83737.16, response time: 74.71ms (95%), errors: 0.68, reconnects: 0.00 [ 540s] threads: 1000, tps: 20663.05, reads: 0.00, writes: 82626.42, response time: 73.56ms (95%), errors: 0.75, reconnects: 0.00 [ 600s] threads: 1000, tps: 20746.02, reads: 0.00, writes: 83015.81, response time: 73.58ms (95%), errors: 0.78, reconnects: 0.00 OLTP test statistics: queries performed: read: 0 write: 48868458 other: 24434022 total: 73302480 transactions: 12216804 (20359.59 per sec.) read/write requests: 48868458 (81440.43 per sec.) other operations: 24434022 (40719.87 per sec.) ignored errors: 414 (0.69 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 600.0516s total number of events: 12216804 total time taken by event execution: 599964.4735s response time: min: 6.27ms avg: 49.11ms max: 350.24ms approx. 95 percentile: 72.90ms Threads fairness: events (avg/stddev): 12216.8040/31.27 execution time (avg/stddev): 599.9645/0.01
Insamlade mätvärden
Molnursstatistik Performance Insights Metrics Ladda ner Whitepaper Today PostgreSQL Management &Automation med ClusterControl för att veta vad du behöver veta om, övervaka, hantera och skala PostgreSQLDladda WhitepaperKör #2
Specifikationer
- Detta test använder AWS-specifikationerna för klienten och en mindre instansstorlek för databasen:
- Kunddator:On Demand Memory Optimized EC2-instans:
- vCPU:32 (16 kärnor x 2 trådar/kärna)
- RAM:244 GiB
- Lagring:EBS-optimerad
- Nätverk:10 Gigabit
- DB-kluster:db.r4.2xlarge:
- vCPU:8
- RAM:61GiB
- Lagring:EBS-optimerad
- Nätverk:1 750 Mbps Max bandbredd på en anslutning på upp till 10 Gbps
- Kunddator:On Demand Memory Optimized EC2-instans:
- Databasen innehöll ingen replik.
- Databaslagring var inte krypterad.
Utföra tester och resultat
Stegen är identiska med körning #1 så jag visar bara utdata:
-
pgbench Läs/skriv arbetsbelastning:
... 745700000 of 1000000000 tuples (74%) done (elapsed 794.93 s, remaining 271.09 s) 745800000 of 1000000000 tuples (74%) done (elapsed 795.00 s, remaining 270.97 s) 745900000 of 1000000000 tuples (74%) done (elapsed 795.09 s, remaining 270.86 s) 746000000 of 1000000000 tuples (74%) done (elapsed 795.17 s, remaining 270.74 s) 746100000 of 1000000000 tuples (74%) done (elapsed 795.24 s, remaining 270.62 s) 746200000 of 1000000000 tuples (74%) done (elapsed 795.33 s, remaining 270.51 s) ... 999800000 of 1000000000 tuples (99%) done (elapsed 1067.11 s, remaining 0.21 s) 999900000 of 1000000000 tuples (99%) done (elapsed 1067.19 s, remaining 0.11 s) 1000000000 of 1000000000 tuples (100%) done (elapsed 1067.28 s, remaining 0.00 s) vacuum... set primary keys... total time: 4386.44 s (insert 1067.33 s, commit 0.46 s, vacuum 2088.25 s, index 1230.41 s) done.
starting vacuum...end. progress: 60.0 s, 3361.3 tps, lat 286.143 ms stddev 80.417 progress: 120.0 s, 3466.8 tps, lat 288.386 ms stddev 76.373 progress: 180.0 s, 3683.1 tps, lat 271.840 ms stddev 75.712 progress: 240.0 s, 3444.3 tps, lat 289.909 ms stddev 69.564 progress: 300.0 s, 3475.8 tps, lat 287.736 ms stddev 73.712 progress: 360.0 s, 3449.5 tps, lat 289.832 ms stddev 71.878 progress: 420.0 s, 3518.1 tps, lat 284.432 ms stddev 74.276 progress: 480.0 s, 3430.7 tps, lat 291.359 ms stddev 73.264 progress: 540.0 s, 3515.7 tps, lat 284.522 ms stddev 73.206 progress: 600.0 s, 3482.9 tps, lat 287.037 ms stddev 71.649 transaction type: <builtin: TPC-B (sort of)> scaling factor: 10000 query mode: prepared number of clients: 1000 number of threads: 1000 duration: 600 s number of transactions actually processed: 2090702 latency average = 286.030 ms latency stddev = 74.245 ms tps = 3481.731730 (including connections establishing) tps = 3494.157830 (excluding connections establishing)
-
sysbench-test:
sysbench 0.5: multi-threaded system evaluation benchmark Running the test with following options: Number of threads: 1000 Report intermediate results every 60 second(s) Random number generator seed is 0 and will be ignored Forcing shutdown in 630 seconds Initializing worker threads... Threads started! [ 60s] threads: 1000, tps: 4809.05, reads: 0.00, writes: 19301.02, response time: 288.03ms (95%), errors: 0.05, reconnects: 0.00 [ 120s] threads: 1000, tps: 5264.15, reads: 0.00, writes: 21005.40, response time: 255.23ms (95%), errors: 0.08, reconnects: 0.00 [ 180s] threads: 1000, tps: 5178.27, reads: 0.00, writes: 20713.07, response time: 260.40ms (95%), errors: 0.03, reconnects: 0.00 [ 240s] threads: 1000, tps: 5145.95, reads: 0.00, writes: 20610.08, response time: 255.76ms (95%), errors: 0.05, reconnects: 0.00 [ 300s] threads: 1000, tps: 5127.92, reads: 0.00, writes: 20507.98, response time: 264.24ms (95%), errors: 0.05, reconnects: 0.00 [ 360s] threads: 1000, tps: 5063.83, reads: 0.00, writes: 20278.10, response time: 268.55ms (95%), errors: 0.05, reconnects: 0.00 [ 420s] threads: 1000, tps: 5057.51, reads: 0.00, writes: 20237.28, response time: 269.19ms (95%), errors: 0.10, reconnects: 0.00 [ 480s] threads: 1000, tps: 5036.32, reads: 0.00, writes: 20139.29, response time: 279.62ms (95%), errors: 0.10, reconnects: 0.00 [ 540s] threads: 1000, tps: 5115.25, reads: 0.00, writes: 20459.05, response time: 264.64ms (95%), errors: 0.08, reconnects: 0.00 [ 600s] threads: 1000, tps: 5124.89, reads: 0.00, writes: 20510.07, response time: 265.43ms (95%), errors: 0.10, reconnects: 0.00 OLTP test statistics: queries performed: read: 0 write: 12225686 other: 6112822 total: 18338508 transactions: 3056390 (5093.75 per sec.) read/write requests: 12225686 (20375.20 per sec.) other operations: 6112822 (10187.57 per sec.) ignored errors: 42 (0.07 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 600.0277s total number of events: 3056390 total time taken by event execution: 600005.2104s response time: min: 9.57ms avg: 196.31ms max: 608.70ms approx. 95 percentile: 268.71ms Threads fairness: events (avg/stddev): 3056.3900/67.44 execution time (avg/stddev): 600.0052/0.01
Insamlade mätvärden
Molnursstatistik Performance Insights - Counter Metrics Performance Insights - Database Load by WaitsSluta tankar
- Användare är begränsade till att använda fördefinierade instansstorlekar. Som en nackdel, om riktmärket visar att instansen kan dra nytta av ytterligare minne är det inte möjligt att "bara lägga till mer RAM". Att lägga till mer minne innebär att instansstorleken ökar, vilket kommer med en högre kostnad (kostnaden fördubblas för varje instansstorlek).
- Amazon Aurora-lagringsmotorn skiljer sig mycket från RDS och är byggd ovanpå SAN-hårdvara. I/O-genomströmningsstatistiken per instans visar att testet inte kom ännu närmare maxvärdet för de tillhandahållna IOPS SSD EBS-volymerna på 1 750 MiB/s.
- Ytterligare justering kan utföras genom att granska AWS PostgreSQL-händelserna som ingår i Performance Insights-diagrammen.
Nästa i serien
Håll ögonen öppna för nästa del:Amazon RDS för PostgreSQL 10.6.