Baza danych Firebird o rozmiarze 1 Tb: raport wstępny
Dmitry Kuzmenko, ostatnia aktualizacja 31-03-2014
Tłumaczenia tego dokumentu: Portugalski Rosyjski Chiński
Przeczytaj nasz artykuł o jeszcze większej bazie danych (1,7 terabajta): Więcej szczegółów o bazie danych 1,7 terabajta.
Po co tworzyć terabajtową bazę danych Firebird?
Wiele firm pracuje z dużymi bazami danych Firebird i polega na nich w obsłudze ważnych operacji biznesowych. Niektóre bazy danych Firebird mają już setki gigabajtów rozmiaru i nadal rosną (zobacz sekcję „Kto jest duży?”), a moment, w którym staną się 2, 3 lub 5 razy większe, można łatwo przewidzieć. Dlatego administratorzy baz danych i dostawcy oprogramowania są zainteresowani zbadaniem zachowania Firebird z dużymi bazami danych i uzyskaniem rekomendacji, jak nimi zarządzać.
Kolejnym ważnym powodem, który mieliśmy na uwadze podczas tworzenia 1Tb bazy danych Firebird, było ostateczne wyeliminowanie powszechnego postrzegania Firebird jako silnika bazy danych do „małych baz danych”. Ten mit wydaje się już martwy, ale niektórzy analitycy i dziennikarze regularnie wyciągają go z grobu, i mamy nadzieję, że w końcu zakończymy z tym absurdalnym postrzeganiem.
| ## Sprzęt |
Firebird jest dobrze znany ze swojej niesamowitej skalowalności i to badanie potwierdziło to po raz kolejny. Początkowym celem tego eksperymentu było jedynie utworzenie bazy danych Firebird o rozmiarze 1Tb, więc użyliśmy zwykłego komputera stacjonarnego:
Tabela 1: Sprzęt
| Komponent | Parametry |
| CPU | AMDAthlon 64 x2 5200 |
| RAM | 4GB |
| Płyta główna | MSI K9N Platinum |
| HDD1 (system operacyjny i temp) | ST3160815AS, 160GB, SATA II |
| HDD2 (pomocniczy) | HDT721064SLA360, 640GB,SATAII |
| HDD2 (pomocniczy) | HDS728080PLA380, 80GB, SATA I |
| HDD3 (baza danych) | ST31500341AS, 1.5TB, SATA II (Firmware CC1H) |
W istocie włożyliśmy dysk HDD 1.5Tb do jednego z naszych biurowych komputerów stacjonarnych, bez żadnych innych modyfikacji. Ten dysk HDD został sformatowany z rozmiarem klastra 16Kb (takim samym jak rozmiar strony bazy danych, jak można zobaczyć poniżej).
Oprogramowanie
Ponieważ jest to komputer stacjonarny, systemem operacyjnym jest Windows XP Professional SP3, 32bit. Do faktycznego przeprowadzenia testu użyliśmy loadera z zestawu narzędzi opartego na TPC (pobierz go z http://ibdeveloper.com/tests/tpc-c/, dostępne są zarówno pliki binarne, jak i źródła).
Chcielibyśmy podkreślić, że loader wstawia dane tak, jak zostałyby wstawione w rzeczywistym scenariuszu: rekordy są wstawiane i umieszczane wewnątrz bazy danych (oraz na obszarach fizycznego dysku) do kilku tabel master-detail-subdetail, a nie tabela po tabeli.
Tabela 2: Oprogramowanie
| Oprogramowanie | Wersja |
| System operacyjny | Windows XP Professional SP3, 32bit |
| Firebird | 2.1.3 SuperServer (snapshot) |
| Loader | Niestandardowy loader z testu opartego na tpc |
Plan
Mieliśmy bardzo prosty plan dla tego eksperymentu:
- Utworzyć bazę danych i załadować ją 1Tb danych, bez indeksów
- Utworzyć klucze główne i odpowiednie indeksy (więc faktycznie rozmiar bazy danych jest większy niż 1Tb)
- Zebrać statystyki bazy danych
- Uruchomić kilka zapytań SQL i oszacować wydajność bazy danych
Konfiguracja bazy danych i serwera Firebird
Baza danych ma rozmiar strony 16384 bajtów, taki sam jak klaster dysku HDD, aby zmaksymalizować wydajność dysku (odczyt/zapis 1 strony w jednym cyklu I/O).
W konfiguracji Firebird skonfigurowaliśmy dodatkowy katalog dla przestrzeni tymczasowej i wskazaliśmy go na dysk 640Gb (gdzie ~300Gb było wolne).
Krok ładowania
Dane zostały załadowane do tej bazy danych w kilku krokach. Komputer był używany podczas operacji ładowania jak zwykły komputer stacjonarny (mamy MS Office, Firefox, IBAnalyst, itp. - około 8-12 programów działało jednocześnie). Gdybyśmy dedykowali sprzęt tylko do tego zadania, prawdopodobnie byłoby szybciej, więc proszę traktować te wartości tylko jako przykład niskiej klasy; z pewnością nie są to najlepsze wyniki.
Tabela 3: Operacje ładowania
| |
| Opis | Wartość |
| Czas ładowania | ~70 godzin |
| Łączna liczba wstawionych rekordów | 6.2 miliarda |
| Średnia prędkość wstawiania | 24500 rekordów/sekundę |
| Średni rozmiar rekordu | 146 bajtów (min 13 bajtów, max - 600 bajtów) |
| Transakcje | 646489 |
Spędziliśmy ~4 dni na ładowaniu, a po tym mieliśmy bazę danych Firebird o dokładnie 1Tb rozmiarze (tj. 1 099 900 125 184 bajtów).
Poniżej można zobaczyć dynamikę wzrostu bazy danych i transakcji w FBDataGuard Viewer:

Indeksy
Tworzyliśmy indeksy jeden po drugim i liczyliśmy czas ich tworzenia oraz odpowiedni rozmiar pliku tymczasowego użytego do sortowania.
Największy indeks został utworzony dla tabeli ORDER_LINE. Jego klucz główny zawiera cztery pola (Smallint, Smallint, Integer i Smallint). Plik tymczasowy dla tego indeksu sortowania miał 182Gb, a końcowy rozmiar indeksu w bazie danych to 29.3Gb.
Interesujące jest to, że nawet indeks dla tabeli z 3.8 miliarda rekordów ma głębokość = 3, ponieważ rozmiar strony wynosił 16384 bajtów, więc nie ma narzutu podczas wyszukiwania danych za pomocą klucza głównego dla tej tabeli.
Statystyki
Następnie zebraliśmy statystyki bazy danych. Zajęło to 7 godzin 32 minuty 45 sekund.
Umieściliśmy kluczowe informacje statystyczne w jednej tabeli i dołączyliśmy kilka zapytań i pomiarów czasu:
Tabela 4: Skonsolidowane statystyki dla bazy danych 1Tb
| Nazwa tabeli | Liczba rekordów | Rozmiar, gb | Czas wykonania select count(*) | Czas tworzenia indeksu | Rozmiar pliku tmp, Gb | Rozmiar indeksu, Gb |
| WAREHOUSE | 1240 | 0.002 | 0s | 0 | 0 | 0.0 |
| ITEM | 100000 | 0.012 | 0.7s | - | - | 0.0 |
| DISTRICT | 124000 | 0.017 | 0.7s | 6 | - | 0.0 |
| NEW_ORDER | 111600000 | 32 | 20m 00s | 23m 00s | 4.56 | 0.8 |
| CUSTOMER | 372000000 | 224 | - | 41m 00s | - | 2.6 |
| customer_last | 1h 52m 32s | 12.4 | 2.3 | |||
| fk_cust_ware | 2h 10m 51s | - | 2.3 | |||
| HISTORY | 372000000 | 32 | - | - | - | - |
| ORDERS | 372000000 | 25 | 32m 00s | 45m 41s | 15.2 | 2.5 |
| STOCK | 1240000000 | 404 | - | 3h 34m 44s | 41.5 | 9.2 |
| ORDER_LINE | 3720051796 | 359 | - | 12h 6m 18s | 182.0 | 29.3 |
Statystyki bazy danych można pobrać z tutaj.
Możesz użyć darmowego FBDataGuard Community Edition Viewer do interpretacji danych tekstowych i zobaczenia nie tylko metryk wydajności bazy danych, ale także zużycia CPU i pamięci.
Zapytania
Przede wszystkim uruchomiliśmy zapytania select count(*) na kilku tabelach (zobacz 4-tą kolumnę w Tabeli 4 powyżej). Jak wiadomo, ze względu na wielowersyjną naturę Firebird select count(*) dla całej tabeli jest kosztowną operacją dla serwera, ponieważ wymaga odwiedzenia każdej strony, i doświadczeni programiści Firebird nie używają select count(*), ale użyliśmy go, aby zademonstrować ogólny stosunek wydajności bazy danych i sprzętu.
Po zapytaniach select count uruchomiliśmy zapytania z rzeczywistego scenariusza i, szczerze mówiąc, byliśmy zdumieni tak dobrymi wynikami. Zobacz sam:
| Zapytanie | Statystyki | Opis |
| select w_id, w_name, c_id, c_last from WAREHOUSE, customer where c_w_id = w_id |
PLAN JOIN (WAREHOUSE NATURAL, CUSTOMER INDEX (FK_CUST_WARE)) ------ Performance info —— Prepare time = 15ms Execute time = 79ms Avg fetch time = 6.08 ms Current memory = 272 264 476 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 82 Writes from cache to disk = 0 Fetches from cache = 3 648 |
Proste złączenie tabel z 12400 i 372000000 rekordami, bez warunków WHERE. „Avg fetch time = 6.08 ms” dotyczy pobrania pierwszego wiersza. |
| select w_id, w_name, c_id, c_last from WAREHOUSE, customer where c_w_id = w_id and c_w_id = 10000 |
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ Performance info —— Prepare time = 16ms Execute time = 78ms Avg fetch time = 6.00 ms Current memory = 272 266 148 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 88 Writes from cache to disk = 0 Fetches from cache = 3 656 |
Złączenie tych samych tabel z warunkiem, który wymusza wybór najnowszych rekordów. „Avg fetch time = 6.00 ms” dotyczy pobrania pierwszego wiersza. |
| select count(*) from WAREHOUSE, customer where c_w_id = w_id and c_w_id = 10000 Result = 30000 |
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ Performance info —— Prepare time = 0ms Execute time = 453ms Avg fetch time = 453.00 ms Current memory = 272 263 844 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 1 048 Writes from cache to disk = 0 Fetches from cache = 60 024 |
Zliczanie rekordów dla poprzedniego zapytania |
| SELECT * FROM ORDER_LINE WHERE OL_W_ID = 500 |
Plan PLAN (ORDER_LINE INDEX (ORDER_LINE_PK)) ------ Performance info —— Prepare time = 0ms Execute time = 94ms Avg fetch time = 7.23 ms Current memory = 136 445 536 Max memory = 136 592 176 Memory buffers = 8 192 Reads from disk to cache = 150 Writes from cache to disk = 0 Fetches from cache = 2 402 |
Zapytanie do największej tabeli (3.8B rekordów). „Avg fetch time = 7.23 ms” dotyczy pobrania pierwszego wiersza. |
<br>Plan<br><br>PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))<br><br> <br><br>------ Performance info ------<br><br>Prepare time = 0ms<br><br>Execute time = 3s 438ms<br><br>Avg fetch time = 0.01 ms<br><br>Current memory = 136 445 496<br><br>Max memory = 136 592 176<br><br>Memory buffers = 8 192<br><br>Reads from disk to cache = 1 840<br><br>Writes from cache to disk = 0<br><br>Fetches from cache = 598 636<br> |
| SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500 | To samo zapytanie do największej tabeli (3,8 mld rekordów), ale tym razem pobraliśmy wszystkie rekordy (pobrano 299245 rekordów). |
| | |
| select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000) | Plan
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 125ms
Avg fetch time = 9.62 ms
Current memory = 272 270 824
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 91
Writes from cache to disk = 0
Fetches from cache = 3 659 | Złączenie tabel z 1240 rekordami i 372 mln rekordów. |
| select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000)
Result = 59 970 000 | Plan
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 13m 4s 718ms
Avg fetch time = 784 718.00 ms
Current memory = 272 268 532
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 2 332 583
Writes from cache to disk = 0
Fetches from cache = 119 977 902 | Zliczanie rekordów dla poprzedniego zapytania |
Podsumowanie
W tym eksperymencie Firebird osiąga następujące wyniki
-
Niewątpliwa zdolność do obsługi dużych baz danych. Jesteśmy pewni, że możliwe jest utworzenie i używanie bazy danych o rozmiarze 32 Tb na odpowiednim sprzęcie, a Firebird osiągnie taką samą wysoką wydajność, jak w przypadku mniejszych baz danych (tj. 1 Tb i mniejszych).
-
Dobra skalowalność i zadziwiająco mały rozmiar. Baza danych o rozmiarze 1 Tb została utworzona na zwykłym komputerze stacjonarnym i, co ważniejsze, można jej używać do wykonywania ogólnych zapytań: jeśli nie pobierasz milionów rekordów, szybkość zapytania jest taka sama jak w przypadku baz danych o umiarkowanym rozmiarze (10-15 Gb).
To nie koniec tego eksperymentu: zamierzamy uruchomić kilka zapytań, zebrać dodatkowe statystyki i wkrótce opublikować bardziej szczegółowy raport. Prosimy o śledzenie aktualności.
Kontakt
Wszystkie pytania i zapytania prosimy kierować na adres [email protected]