Celem benchmarkingu bazy danych jest nie tylko sprawdzenie możliwości bazy danych, ale także zachowanie konkretnej bazy danych w stosunku do Twojej aplikacji. Różne sprzęty zapewniają różne wyniki w zależności od ustawionego planu testów porównawczych. Bardzo ważne jest odizolowanie serwera (rzeczywistego testowanego) od innych elementów, takich jak serwery napędzające obciążenie lub serwery używane do zbierania i przechowywania metryk wydajności. W ramach ćwiczenia porównawczego musisz uzyskać takie cechy aplikacji, jak:a) Czy aplikacja intensywnie odczytuje lub zapisuje? lub b) jaki jest podział odczytu/zapisu (np. 80:20)? lub c) Jak duży jest zbiór danych?, czy dane i struktura są reprezentatywne dla rzeczywistej produkcyjnej bazy danych itp.
PostgreSQL to najbardziej zaawansowana na świecie baza danych typu open source. Jeśli jakikolwiek klient RDBMS w przedsiębiorstwie chce migrować swoją bazę danych do opensource, PostgreSQL będzie pierwszą opcją do oceny.
Ten post obejmuje następujące tematy:
- Jak przetestować PostgreSQL
- Jakie są kluczowe czynniki wydajności w PostgreSQL
- Jakie są dźwignie, które możesz pociągnąć, aby zwiększyć wydajność
- Jakie są pułapki wydajnościowe, których należy unikać
- Jakie błędy popełniają ludzie?
- Skąd wiesz, czy Twój system działa? Jakich narzędzi możesz użyć?
Jak porównywać PostgreSQL
Standardowym narzędziem do testowania PostgreSQL jest pgbench. Domyślnie testy pgbench są oparte na TPC-B. Obejmuje 5 poleceń SELECT, INSERT i UPDATE na transakcję. Jednak w zależności od zachowania aplikacji możesz napisać własne pliki skryptów. Przyjrzyjmy się domyślnym i niektórym wynikom testów zorientowanych na skrypt. Do tych testów użyjemy najnowszej wersji PostgreSQL, czyli PostgreSQL 10 w momencie pisania tego tekstu. Możesz go zainstalować za pomocą ClusterControl lub korzystając z instrukcji tutaj:https://www.openscg.com/bigsql/package-manager/.
Specyfikacja maszyny
Wersja:RHEL 6 - 64 bity
Pamięć:4GB
Procesory:4
Pamięć:50G
Wersja PostgreSQL:10.0
Rozmiar bazy danych:15G
Zanim uruchomisz test porównawczy za pomocą narzędzia pgbench, musisz zainicjować je poniżej poleceniem:
-bash-4.1$ ./pgbench -i -p 5432 -d postgres
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 100000 tuples (100%) done (elapsed 0.18 s, remaining 0.00 s)
Vacuum…
set primary keys…
done.
Jak pokazano w komunikatach NOTICE, tworzy tabele pgbench_history, pgbench_tellers, pgbench_accounts i pgbench_branches w celu uruchomienia transakcji w celu przeprowadzenia testów porównawczych.
Oto prosty test z 10 klientami:
-bash-4.1$ ./pgbench -c 10
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 10
number of transactions actually processed: 100/100
latency average = 13.516 ms
tps = 739.865020 (including connections establishing)
tps = 760.775629 (excluding connections establishing)
Jak widać, działał z 10 klientami i 10 transakcjami na klienta. Dało 739 transakcji/s. Dało 739 transakcji/s. Jeśli chcesz uruchomić go przez określony czas, możesz użyć opcji "-T". Ogólnie rzecz biorąc, wystarczy 15 minut lub 30 minut biegu.
Na razie rozmawialiśmy o tym, jak uruchomić pgbench, ale nie o tym, jakie powinny być opcje. Przed rozpoczęciem testu porównawczego należy uzyskać odpowiednie informacje od zespołu ds. aplikacji:
- Jaki rodzaj obciążenia?
- Ile jednoczesnych sesji?
- Jaki jest średni zestaw wyników zapytań?
- Jakie są oczekiwane tps (transakcje na sekundę)?
Oto przykład obciążenia pracą tylko do odczytu. Możesz użyć opcji "-S", aby używać tylko SELECTów, które należą do kategorii tylko do odczytu. Zauważ, że -n oznacza pominięcie odkurzania na stołach.
-bash-4.1$ ./pgbench -c 100 -T 300 -S -n
transaction type: <builtin: select only>
scaling factor: 1000
query mode: simple
number of clients: 100
number of threads: 1
duration: 300 s
number of transactions actually processed: 15741
latency average = 1916.650 ms
tps = 52.174363 (including connections establishing)
tps = 52.174913 (excluding connections establishing)
-bash-4.1$
Opóźnienie tutaj to średni czas transakcji, który upłynął dla każdego wyciągu wykonanego przez każdego klienta. Daje 52 tps przy podanym sprzęcie. Ponieważ ten test dotyczy środowiska tylko do odczytu, spróbujmy poprawić parametry shared_buffers i Effective_cache_size w pliku postgresql.conf i sprawdźmy liczbę tps. W powyższym teście mają wartości domyślne, spróbuj zwiększyć wartości i sprawdź wyniki.
-bash-4.1$ ./pgbench -c 100 -T 300 -S -n
transaction type: <builtin: select only>
scaling factor: 1000
query mode: simple
number of clients: 100
number of threads: 1
duration: 300 s
number of transactions actually processed: 15215
latency average = 1984.255 ms
tps = 68.396758 (including connections establishing)
tps = 68.397322 (excluding connections establishing)
Zmiana parametrów poprawiła wydajność o 30%.
pgbench zazwyczaj uruchamia transakcje na własnych tabelach. Jeśli masz obciążenie 50% odczytów i 50% zapisów (lub środowisko 60:40), możesz utworzyć plik skryptu z zestawem instrukcji, aby osiągnąć oczekiwane obciążenie.
-bash-4.1$ cat /tmp/bench.sql
INSERT INTO test_bench VALUES(1,'test');
INSERT INTO test_bench VALUES(1,'test');
SELECT * FROM test_bench WHERE id=1;
SELECT * FROM test_bench WHERE id=2;
-bash-4.1$ ./pgbench -c 100 -T 300 -S -n -f /tmp/bench.sql
transaction type: multiple scripts
scaling factor: 1000
query mode: simple
number of clients: 100
number of threads: 1
duration: 300 s
number of transactions actually processed: 25436
latency average = 1183.093 ms
tps = 84.524217 (including connections establishing)
tps = 84.525206 (excluding connections establishing)
SQL script 1: <builtin: select only>
- weight: 1 (targets 50.0% of total)
- 12707 transactions (50.0% of total, tps = 42.225555)
- latency average = 914.240 ms
- latency stddev = 558.013 ms
SQL script 2: /tmp/bench.sql
- weight: 1 (targets 50.0% of total)
- 12729 transactions (50.0% of total, tps = 42.298662)
- latency average = 1446.721 ms
- latency stddev = 765.933 ms
Pobierz oficjalny dokument już dziś Zarządzanie i automatyzacja PostgreSQL za pomocą ClusterControlDowiedz się, co musisz wiedzieć, aby wdrażać, monitorować, zarządzać i skalować PostgreSQLPobierz oficjalny dokument Jakie są kluczowe czynniki wydajności w PostgreSQL
Jeśli weźmiemy pod uwagę rzeczywiste środowisko produkcyjne, jest ono skonsolidowane z różnymi komponentami na poziomie aplikacji, sprzętem, takim jak procesor i pamięć, oraz bazowym systemem operacyjnym. Instalujemy PostgreSQL na górze systemu operacyjnego, aby komunikować się z innymi komponentami środowiska produkcyjnego. Każde środowisko jest inne, a ogólna wydajność ulegnie pogorszeniu, jeśli nie zostanie odpowiednio skonfigurowana. W PostgreSQL niektóre zapytania działają szybciej, inne wolniej, jednak zależy to od ustawionej konfiguracji. Celem optymalizacji wydajności bazy danych jest maksymalizacja przepustowości bazy danych i minimalizacja połączeń w celu osiągnięcia największej możliwej przepustowości. Poniżej znajduje się kilka kluczowych czynników wydajności, które wpływają na bazę danych:
- Obciążenie pracą
- Zasób
- Optymalizacja
- Spór
Obciążenie składa się z zadań wsadowych, zapytań dynamicznych dla transakcji online, zapytań analizy danych, które są wykorzystywane do generowania raportów. Obciążenie pracą może być różne w ciągu dnia, tygodnia lub miesiąca i zależy od aplikacji. Optymalizacja każdej bazy danych jest unikalna. Może to być konfiguracja na poziomie bazy danych lub optymalizacja na poziomie zapytania. Więcej o optymalizacji opowiemy w dalszej części wpisu. Rywalizacja to stan, w którym co najmniej dwa składniki obciążenia próbują użyć jednego zasobu w sposób sprzeczny. Wraz ze wzrostem rywalizacji spada przepustowość.
Co to są wskazówki i najlepsze praktyki
Oto kilka wskazówek i najlepszych praktyk, których możesz przestrzegać, aby uniknąć problemów z wydajnością:
- Możesz rozważyć uruchomienie działań konserwacyjnych, takich jak ODKURZACZ i ANALIZA po dużej modyfikacji w swojej bazie danych. Pomaga to planistom w opracowaniu najlepszego planu wykonywania zapytań.
- Zwróć uwagę na potrzebę indeksowania tabel. Sprawia, że zapytania działają znacznie szybciej, zamiast wykonywać pełne skanowanie tabel.
- Aby przemierzanie indeksu było znacznie szybsze, możesz użyć poleceń CREATE TABLE AS lub CLUSTER do grupowania wierszy o podobnych wartościach kluczy.
- Kiedy zauważysz problem z wydajnością, użyj polecenia EXPLAIN, aby przyjrzeć się planowi, w jaki optymalizator zdecydował się wykonać zapytanie.
- Możesz spróbować zmienić plany, wpływając na optymalizator, modyfikując operatory zapytań. Na przykład, jeśli widzisz skanowanie sekwencyjne dla zapytania, możesz wyłączyć skanowanie sekwencyjne za pomocą „USTAW ENABLE_SEQSCAN NA WYŁĄCZONE”. Nie ma gwarancji, że optymalizator nie wybierze tego operatora, jeśli go wyłączysz. Optymalizator po prostu uważa, że operator jest znacznie droższy. Więcej szczegółów znajdziesz tutaj:https://www.postgresql.org/docs/current/static/runtime-config-query.html
- Możesz również spróbować zmienić parametry kosztów, takie jak CPU_OPERATOR_COST, CPU_INDEX_TUPLE_COST, CPU_TUPLE_COST, RANDOM_PAGE_COST i EFFECTIVE_CACHE_SIZE, aby wpłynąć na optymalizator. Więcej szczegółów znajdziesz tutaj:https://www.postgresql.org/docs/current/static/runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS
- Zawsze filtruj dane na serwerze, a nie w aplikacji klienckiej. Zminimalizuje to ruch sieciowy i zapewni lepszą wydajność.
- Aby wykonywać typowe operacje, zawsze zaleca się stosowanie procedur po stronie serwera (wyzwalaczy i funkcji). Wyzwalacze lub funkcje po stronie serwera są analizowane, planowane i optymalizowane przy pierwszym użyciu, a nie za każdym razem.
Jakie błędy popełniają ludzie
Jednym z typowych błędów popełnianych przez ludzi jest uruchamianie serwera bazy danych i bazy danych z domyślnymi parametrami. Domyślna konfiguracja PostgreSQL jest testowana w kilku środowiskach, jednak nie każda aplikacja uznałaby te wartości za optymalne. Musisz więc zrozumieć zachowanie swojej aplikacji i na tej podstawie ustawić parametry konfiguracyjne. Możesz użyć narzędzia pgTune, aby uzyskać wartości parametrów na podstawie używanego sprzętu. Możesz zajrzeć na:http://pgtune.leopard.in.ua/. Pamiętaj jednak, że będziesz musiał przetestować swoją aplikację z wprowadzonymi zmianami, aby sprawdzić, czy zmiany nie powodują obniżenia wydajności.
Inną rzeczą do rozważenia byłoby indeksowanie bazy danych. Indeksy pomagają szybciej pobierać dane, jednak większa liczba indeksów powoduje problemy z ładowaniem danych. Dlatego zawsze sprawdzaj, czy w bazie danych znajdują się jakieś nieużywane indeksy i pozbądź się ich, aby ograniczyć konserwację tych indeksów i poprawić ładowanie danych.