Ręczne partycjonowanie w PostgreSQL

Przetłumaczone automatycznie z angielskiego. Przeczytaj oryginał

Zastanawiałeś się kiedyś, ile tabel możemy utworzyć i używać w serwerze baz danych PostgreSQL? Czy nazywać je partycjami, czy shardami? Dlaczego nie użyć wbudowanego „automatycznego” partycjonowania?

Partycje czy shardy? #

Najpierw zdefiniujmy różnicę między partycjami a shardami. Partycje znajdują się na tym samym serwerze, natomiast shardy mogą być rozłożone na różne maszyny. Możemy użyć dziedziczenia lub nowszego, „automatycznego” partycjonowania. Oba te rozwiązania prowadzą jednak do ścisłego powiązania z RDBMS PostgreSQL, czego w niektórych sytuacjach chcielibyśmy uniknąć. Wyobraź sobie perspektywę migracji naszych schematów do innego RDBMS, takiego jak Microsoft SQL Server. Niekorzystanie z żadnej składni i konfiguracji specyficznej dla dostawcy byłoby wtedy korzystne.

Partycje niezależne od dostawcy #

Zamiast tego możemy więc po prostu spróbować ręcznie utworzyć tabele pełniące rolę partycji:

SQL
sudo apt install postgresql -y
sudo -u postgres -i
psql
CREATE DATABASE paritions
exit

Następnie, po zainstalowaniu PostgreSQL i utworzeniu nowej bazy danych:

Text
for i in `seq 1 10000`; 
do 
  echo $i;
  psql -c "create table demo_$i (id int, val int);" partitions; 
done

W ten sposób utworzyliśmy 10 000 tabel, używając wyłącznie ogólnej składni SQL, która jest w 100% kompatybilna ze wszystkimi innymi RDBMS. Co ważniejsze, nie zależymy od konfiguracji pamięci współdzielonej ani od ograniczeń wynikających z dołączenia zbyt wielu partycji do tabeli głównej.

Ile zwykłych partycji mogę mieć? #

W przypadku PostgreSQL (zwykłe partycje), jeśli dołączymy zbyt wiele tabel, łatwo możemy zacząć odczuwać to negatywnie pod względem wydajności i zużycia pamięci. Jeśli więc chcesz używać „automatycznego” partycjonowania PostgreSQL, pamiętaj, by nie dołączać zbyt wielu tabel. Ile to zbyt wiele? Zacząłem to zauważać już po dołączeniu 100 – 200 tabel, co w małych/średnich wdrożeniach powinno być naszą górną granicą.

Jak duże mogą być moje dane? #

Jeśli chodzi o to, jak duży może być pojedynczy węzeł PostgreSQL, powiedziałbym, że 5 – 10 TB danych z tabelami osiągającymi (wraz z toastami) 2 TB to dość normalna sytuacja i zwykły sprzęt sobie z tym poradzi. Jeśli masz na serwerze 512 GB RAM, bufor i cache wystarczą do pracy na tak ogromnych tabelach.

Ile tabel mogę utworzyć w pojedynczym węźle? #

Jak wspomniałem wcześniej, ogranicza cię przestrzeń dyskowa, pamięć i CPU – jak zawsze. Powinieneś jednak monitorować także liczbę i-węzłów (inodes) oraz liczbę deskryptorów plików w systemie, ponieważ te osobne tabele mogą trafiać do różnych plików, a ma to jeszcze większe znaczenie, jeśli w rekordach umieszczamy długie dane, które trafiają do toastów. Używanie zwykłych tabel jako partycji to jednak najbardziej zdenormalizowany sposób osiągnięcia celu, jakim jest fizyczny podział danych.

Mogę powiedzieć, że 50 000 tabel w pojedynczym węźle to nic złego, nawet w małym/średnim systemie.

Ale jaki jest faktyczny limit? Myślę, że jedyny praktyczny limit wynika z ograniczeń sprzętu i systemu operacyjnego. W kontenerze LXC z Ubuntu 22, z dyskiem 8GB, 1 vCPU i 512 MB pamięci mamy dostępnych 524 tys. i-węzłów. Po dodaniu 50 tys. tabel widzimy, że liczba i-węzłów wzrosła do 77126, co stanowi 15% całej dostępnej puli.

Text
postgres@z10-test:~$ df -i
Filesystem                        Inodes IUsed   IFree IUse% Mounted on
/dev/mapper/pve-vm--131--disk--0  524288 77126  447162   15% /
none                             4070043    25 4070018    1% /dev
tmpfs                            4070043     2 4070041    1% /dev/shm
tmpfs                             819200   149  819051    1% /run
tmpfs                            4070043     2 4070041    1% /run/lock
tmpfs                             814008    11  813997    1% /run/user/110

Myślę, że przynajmniej z perspektywy i-węzłów jesteśmy po bezpiecznej stronie, nawet przy 50 tys. tabel.

Jak zatem zaprojektować architekturę danych? #

Wyobraźmy sobie teraz rzeczywisty scenariusz systemu obsługującego milion klientów. Przy takiej liczbie zalecałbym posiadanie wielu węzłów w różnych lokalizacjach, aby zmniejszyć opóźnienia (w przypadku usług globalnych). Architektura aplikacji również musiałaby być rozproszona. Używalibyśmy więc zarówno partycjonowania w obrębie jednego węzła, jak i shardingu „per se”. Z drugiej strony możemy pozostać przy pojedynczym shardzie ze wszystkimi klientami w jednym węźle, a właściwą pracę wykonywać w węzłach Cassandry, a nie w RDBMS….

Wersja Markdown

Wszystkie treści na tej stronie są udostępniane na licencji Uznanie autorstwa – Użycie niekomercyjne – Bez utworów zależnych 4.0 Międzynarodowe (CC BY-NC-ND 4.0). Cytuj jako: Michał Sobczak, „Ręczne partycjonowanie w PostgreSQL”, 21 września 2024, https://michalasobczak.pl/pl/posts/postgresql-manual-partitioning.html