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:
sudo apt install postgresql -y
sudo -u postgres -i
psql
CREATE DATABASE paritions
exitNastępnie, po zainstalowaniu PostgreSQL i utworzeniu nowej bazy danych:
for i in `seq 1 10000`;
do
echo $i;
psql -c "create table demo_$i (id int, val int);" partitions;
doneW 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.
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/110Myś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….