W zeszłym tygodniu na CHAR(10) odbyły się warsztaty nt. „Bazy danych w chmurze”. Mówiąc prościej:co zrobić, gdy wymagania dotyczące przypadków użycia przekraczają zasoby dostępne na serwerze bazy danych.
To był główny temat całej konferencji, a kilka rozwiązań zostało zilustrowanych w ciągu dnia. Wspólnym tematem jest to, że żadne rozwiązanie nie pasuje do wszystkich przypadków użycia i że każde rozwiązanie ma swój koszt; dlatego musisz wybrać rozwiązanie, na które może sobie pozwolić Twój przypadek użycia.
Innym powszechnym (choć niejawnym) punktem było skupienie się na rozwiązaniach „wysokiego poziomu”, czyli:łączenie kilku serwerów baz danych na wyższym poziomie w celu emulowania jednego serwera z większymi zasobami.
Oczywista zaleta jest to, że nie musisz zmieniać dobrze przemyślanego kodu PostgreSQL; Wadą jest to, że używając wielu serwerów baz danych z ich niezależnymi osiami czasu, tracisz niektóre przydatne właściwości. Dwa przykłady:częściowa utrata semantyki transakcyjnej generuje konflikty; wstępne parsowanie każdego zapytania poza bazą danych wprowadza ograniczenia w akceptowanych zapytaniach.
Dyskusja była dość interesująca, a kiedy Dimitri Fontaine wspomniał o zdalnych przestrzeniach tabel, zacząłem się zastanawiać nad powiązanym, ale odrębnym pomysłem, a mianowicie:czy podejście niższego poziomu do problemu łączenia zasobów byłoby naprawdę niepraktyczne. Zanim zdążyłem rozwinąć szczegóły, warsztaty się zakończyły i mogłem jedynie naszkicować pomysł niektórym osobom, które były wokół tablicy (wśród nich Gabriele Bartolini, Nic Ferrier, Marko Kreen, Hannu Krosing, Greg Smith) wraz z podstawowymi pytania „czy to wygląda na wykonalne?” i „czy to przypomina coś, co już znasz?”.
Krótki szkic:w ten sposób można przedstawić stos aplikacji
(application) --> (connection) --> (db server) --> (resources)
gdzie zasoby wykorzystywane przez bazę danych obejmują pamięć masową, pamięć RAM i procesory. Celem jest umożliwienie aplikacji dowodzenia większą ilością zasobów w celu zwiększenia wydajności i szybkości. „Inteligentne” aplikacje, które zarządzają kilkoma bazami danych, mogą być reprezentowane jako
(application) --> (connection) --> (db server) --> (resources) | +---------> (connection) --> (db server) --> (resources)
natomiast rozwiązania „pulowania połączeń” można przedstawić jako
(application) --> (connection) --> (db server) --> (resources) | +---------> (db server) --> (resources)
przez rozwiązania „niższego poziomu” mam na myśli coś takiego
(application) --> (connection) --> (db server) --> (resources) | +---------> (resources)
co może przypominać coś znajomego, ale nie to tutaj proponuję. Aby wyjaśnić różnicę, mogę zwiększyć szczegóły i napisać
(resources) = (virtual resources) --> (physical resources)
reprezentować fakt, że na najniższym poziomie można mieć nietrywialne mapowanie między obiektami fizycznymi i wirtualnymi. Na przykład pamięć masowa SAN lub striping RAID może zapewnić większe dyski wirtualne, łącząc ze sobą mniejsze dyski fizyczne. Takie przypadki można przedstawić jako
(application) --> (connection) --> (db server) --> (virt.res.) --> (ph.res.) | +--------> (ph.res.)
Proponuję połączyć zasoby na serwerze bazy danych poziomie, dzięki czemu możemy mieć bardziej efektywną „wirtualizację” dzięki znajomości konkretnych przypadków użycia dla każdego zasobu (CPU, RAM, dysk), a jednocześnie uniknąć wielu trudności paradygmatu transakcyjnego. Obraz będzie wyglądał następująco:
(application) --> (connection) --> (db server) --> (virt.res.) --> (ph.res.) | +--------> (virt.res.) --> (ph.res.)
Zaletą jest to, że nie musimy zarządzać wszystkimi możliwymi przypadkami użycia dla każdego zasobu wirtualnego; musimy tylko zarządzać (i optymalizować) przypadki użycia, które są faktycznie potrzebne PostgreSQL. Na przykład:WAL nadal powinien być napisany w lokalnej „niewirtualizowanej” pamięci masowej, bgwriter będzie miał dostęp do lokalnych i zdalnych zasobów (RAM i dysk) itp.
Ostatnie słowa o niezawodności. Do prawidłowego działania cały system potrzebuje każdego podsystemu; częściowe awarie nie są zarządzane, ponieważ ta architektura nie jest nadmiarowa. Jest to system rozproszony, ale nie współdzielony. Jeśli ta architektura mogłaby zapewnić tanią i prostą skalowalność za pośrednictwem wirtualnego serwera bazy danych, który jest funkcjonalnie równoważny serwerowi fizycznemu o większych zasobach, wysoką dostępność można uzyskać w standardowy sposób, konfigurując dwa identyczne serwery wirtualne w konfiguracji Hot Standby.
Jakość sieci ma duży wpływ na ogólną wydajność; ten projekt może być użyteczny tylko wtedy, gdy masz szereg maszyn w tej samej sieci LAN, nie tylko ze względu na szybkość, ale także dlatego, że awaria sieci byłaby w rzeczywistości awarią systemu. Nawet przy tych ograniczeniach, moim zdaniem posiadanie tej opcji byłoby całkiem przydatne.
To wciąż szkic, który można wykorzystać jako odniesienie do dalszej dyskusji. Następne możliwe kroki:
- aby zrobić szczegółową listę przypadków użycia zasobów
- aby zdecydować, które technologie mogą najlepiej pomóc w każdym przypadku użycia
- oszacować rzeczywistą wydajność/koszty rozwoju