"Drop database" a wiele instancji aplikacji

1

Nie brak opinii (#PDK) że w dzisiejszych czasach gdzie RAM jest tani traktować właśnie ten RAM jako pierwszorzędną bazę danych, a taką relacyjną bazę trzymac jako jakiś buckup, albo narzędzie do reportow.
No i nawet coś argumentacja wydaje się logiczna, tylko co w przypadku gdybyśmy mieli wiele instacji tej aplikacji? Można użyć jakiś kolejek, albo Kafki tylko co z konfliktami?
Załóżmy że mamy system typu Jira na dwóch instancjach, jest zadanie X. Jasiek na instancji 1 zamyka zadanie, a z kolei Krzysiek na instancji 2 w tym samym czasie przypisuje te zadanie na siebie. No i co wtedy?

5

Ło panie temat szeroki.

  1. Proste rozwiązanie, które praktykowałem to signgle master i repliki. Master (jeden wybrany node - lider) obrabia wszyskie POSTy, a repliki obrabiają GETy. Repliki przetwarzają też (z opóźnieniem) eventy z mastera. Proste, pasuje dobrze do architektury REST + Load balancer. A, że przeważnie mocno dominują GETy nad POSTami (innych w ogóle metod nie uznajemy - przy okazji) - to jest to nieźle skalowalne.

  2. Problem jest jak chcesz mieć multi master:
    a) możesz zaprojektowac eventy, aby były bezkonfliktowe (i przemienne) - w twoim przypadku zadanie zostanie zamknięte, ale krzysiek przypisze na siebie i trudno - będzie zamkniete i przypisane na krzyśka. Dwa węzły przetworzą te eventy w różnej kolejności, ale wynik będzie ten sam.
    b) możesz bawić się w rozwiązywanie konfliktów. Warto, aby event dotyczący obiektu miał wersje obiektu której dotyczył (jak w optimistic lock). Ale wtedy zaczyna się piekło, o którym zresztą nie mam pojęcia, bo nigdy produkcyjnie się w to nie bawiłem. Paradoksalnie miałem rozwiązywanie konfliktów na SQLowych !!! bazach master - master (oracle golden gate), ale się tym osobiście nie zajmowałem.
    Poczytaj, pooglądaj o rzeczach typu konsensus, split brain, vector clock itd. Przy małej liczbie nodów są jeszcze proste algorytmy - możesz zobaczyć jak działa cassandra, hazelcast itp.

3

No i nawet coś argumentacja wydaje się logiczna, tylko co w przypadku gdybyśmy mieli wiele instacji tej aplikacji? Można użyć jakiś kolejek, albo Kafki tylko co z konfliktami?

Możesz synchronizować commandy tak, żeby istniała globalna kolejność, albo pchając to przez jakąś jedną specjalną instancje, albo nadając jakiś numer sekwencyjny podbijając ostatni który znasz - to szczególnie kiedy przesyłasz w evencie aktualny stan a nie tylko akcje (tzn nie close issue tylko issue state które ma informacje czy jest open/close). Ta druga opcja pozwala ci zwyczajnie odrzucić "stare" eventy, bo skoro przetworzyłeś juz event 5 to nie ma znaczenia co jest w evencie 3, bo 5 i tak go już nadpisał.

0

Temat rzeka. Tak ram jest tani i dlatego wiele db serwerów trzyma w Ramie swoje dane a nie czyta za każdym razem z dysku. Dasz więcej ramu, sam go zeżre. Ty nic nie musisz kombinować. Masz jeden serwer db z którego korzysta wiele instancji aplikacji. Tyle, koniec tematu ;-)
Jak chcesz robić repliki danych, to wykracza poza trzymanie ich w ramie. Bo możesz mieć repliki które są trzymane na dysku.. więc trochę inny szerszy temat.

Pytanie z gatunku: Chce poczytać coś, polećcie coś.
I jeden CI poleci magazyn wędkarza, drugi playboya a trzeci książki... a z książek to też gatunek? Kryminał? A może techniczna?

Jak opisałbyś **konkretny **problem to znajdzie się kilka sensownych rozwiązań. Dokładnie musisz wiedzieć jaki jest ruch itd, wtedy można myśleć nad poszukaniem sensownego rozwiązania. Nie ma idealnego rozwiązania na wszystko. A dla pewnych zastosowań nawet... nie ma problemu.

0
Aleksander32 napisał(a):

Nie brak opinii (#PDK) że w dzisiejszych czasach gdzie RAM jest tani traktować właśnie ten RAM jako pierwszorzędną bazę danych, a taką relacyjną bazę trzymac jako jakiś buckup, albo narzędzie do reportow.

Pytanie czy możesz sobie pozwolić na utratę danych. Jeżeli nie, to RAM nie jest żadnym rozwiązaniem, bo jak dostaniesz żądanie zmiany, to musisz mieć zatwierdzoną transakcję w DB zanim odeślesz HTTP200. Przy odczycie możliwy jest np. cache, który jeżeli nie ma jakiejś wartości, to odczytuje ją z bazy, ale jednocześnie nasłuchuje eventów i aktualizuje sobie przechowywane wartości.

No i nawet coś argumentacja wydaje się logiczna, tylko co w przypadku gdybyśmy mieli wiele instacji tej aplikacji? Można użyć jakiś kolejek, albo Kafki tylko co z konfliktami?
Załóżmy że mamy system typu Jira na dwóch instancjach, jest zadanie X. Jasiek na instancji 1 zamyka zadanie, a z kolei Krzysiek na instancji 2 w tym samym czasie przypisuje te zadanie na siebie. No i co wtedy?

Problem pojawia się w momencie, kiedy Alicja przypisze zadanie do siebie na serwerze Alpha, a Bartosz so siebie na serwerze Bravo.
Możesz zastosować podwójne zatwierdzanie - czyli Alicja dostanie 200 dopiero jak Alpha i Bravo potwierdzą przetworzenie żądania, a Bartosz dostanie HTTP409, bo Alpha go nie puścił.
Możesz znaleźć sposób biznesowy na rozwiązywanie takich konfliktów typu "ostatni wygrywa", zapisywać sobie dane w postaci listy zmian (eventów) a nie pojedynczej krotki, a ustalać co jest istotne, a co nie podczas raportowania.
Możesz zestawić sobie serwery DB z jednokierunkową replikacją (active-passive), gdzie zapis jest obsługiwany zawsze wyłącznie przez serwer aktywny, a odczyt i raportowanie przez dowolną z replik.

Jak ci już napisano wyżej - nie istnieje uniwersalny sposób na rozwiązywanie takich konfliktów. Pytanie jaki problem chcesz rozwiązać, jakie są uwarunkowania biznesowe i czym dysponujesz w projekcie (czas, kasa, ludzie).

0
Aleksander32 napisał(a):

Nie brak opinii (#PDK) że w dzisiejszych czasach gdzie RAM jest tani traktować właśnie ten RAM jako pierwszorzędną bazę danych, a taką relacyjną bazę trzymac jako jakiś buckup, albo narzędzie do reportow.

A czemu relacyjną?

1

@piotrpo:

Pytanie czy możesz sobie pozwolić na utratę danych. Jeżeli nie, to RAM nie jest żadnym rozwiązaniem,

A czym się tu różni RAM od czegoś innego. Taki dysk SSD to też RAM w zasadzie - tylko z mało wydajnym protokołem dostępu.
RAM zupełnie dobrze trzyma dane, tylko trzeba stawiać serwery na laptopach - bo te mają baterie i hibernacje włączoną zwykle.

Tak na serio to rozwiązaniem na utratę danych jest redundancja - wiele serwerów trzymających te same dane w RAM może być bezpieczniejszo od jednego operatego na dysku czy taśmie :-)
Z drugiej strony jak już robimy synchronizację danych miedzy serwerami to zrzucenie eventów do loga jest prawie za darmo, więc można mieć backup na taśmie w razie czego.

0

@jarekr000000: Zwykła redundancja ci nie wystarczy, istotne jest wiedzieć, że dane są bezpieczne w momencie potwierdzenia ich odebrania. Pytanie co ma robić system - rejestrować zlecania kupna akcji w domu maklerskim, czy godziny wyjścia do kibelka w software house.
Co do różnicy pomiędzy RAM a SDD - masz trochę racji, ale fakt, że dane nie są w stanie przetrwać restartu serwera, trochę jednak robi, szczególnie w przypadku bawienia się w jakieś mikroserwisy, kubernetesy, autoskalowania i inne czary. Istnieje już gotowe rozwiązania typu replikacja baz danych w jakimś tam trybie. Robi generalnie to samo co pomysł z zapisem do event logu.

0

@piotrpo: no właśnie ja ciągle nie rozumiem, czemu dane w RAM nie są bezpieczne, a na dysku magidznie są. Tu i tu może być awaria. Tu jeszcze przypominam, często olewany fakt, że fIush i zamknięcie strumienia, nie oznacza, że dane są faktycznie na dysku... (zależy od file systemu i ustawień os). Oczywiście jest różne prawdopodobieństwo i różne rodzaje awarii, ale nadal jak chce się bezpiecznie to trzeba mieć kilka kopii. Różnica jest tylko w głowach.

0

@jarekr000000: wszystko fajnie, ale....

Co, jeśli wysiądzie naraz całe DC, gdy bardzo gruby technik potknie się o bardzo gruby kabel zasilający i wszystkie instancje w DC wysiądą?

Jeśli rozważamy takie scenariusze (OK, ryzyko jest bardzo małe, ale pamiętam, że w zeszłym roku AWS jednak miał jakieś problemy z minimum jednym DC, bo nam się odbijały czkawką) to nagle się okazuje, że redundancja owszem, zdaje egzamin - ale same fizyczne lokalizacje też powinny być redundantne. Co nie zawsze jest możliwe, bo niektórych danych możesz nie móc wynosić poza np. obszar EU czy USA. Choć akurat w przypadku tych dwóch regionów i AWSa istnieje po kilka DC, więc można by załatwić sobie redundancję na co najmniej 3 różnych. Inni cloud providerzy pewnie też mają po kilka, co do prywatnych... no, są prywatne, więc nie wiem.

Tylko wtedy robi się nieciekawie (albo wręcz ciekawie), bo na pełnej kurtyzanie wjeżdżają opóźnienia, które w jednym DC mogły sobie być na poziome 1ms, ale pomiędzy to już będzie kilkadziesiąt i więcej :( Czy to nie zabija trochę sensu używania RAM zamiast dysków?

3

Co, jeśli wysiądzie naraz całe DC, gdy bardzo gruby technik potknie się o bardzo gruby kabel zasilający i wszystkie instancje w DC wysiądą?

A co jak DC spłonie :-)

Tylko wtedy robi się nieciekawie (albo wręcz ciekawie), bo na pełnej kurtyzanie wjeżdżają opóźnienia, które w jednym DC mogły sobie być na poziome 1ms, ale pomiędzy to już będzie kilkadziesiąt i więcej :( Czy to nie zabija trochę sensu używania RAM zamiast dysków?

Bardzo sensowny punkt - mnóstwo ludzi chciałoby spójne, szybko dostępne dane w systemach odpornych na awarie sieci i węzłów it do tego tanio. Ale w praktyce trzeb coś wybrać.
RAM to kierunek szybko dostępne dane i zwykle tanie w wykonaniu - z gorszą odpornością na awarie (szczególnie na bomby atomowe - kiedy centra muszą być oddalone).

Tak czy siak, dyskusja jest trochę akademicka, bo większość systemów opartych jakoś o "RAM first" ma i replikacje i zapiswanie na dyski (hazelcast, redis, mój ukochany prevayler).
Jak mamy replikację to zapisywanie na dysk jest "proste".
Jak mamy event sourcing to zapisywanie na dysk i replikacja jest "prosta".

Tu proponuję zresztą eksperyment myślowy. Zamiast domu maklerskiego, sklepu czy innego badziewia zaprojektuj jakiś poważny system, gdzie dane naprawde mają znaczenie i muszą być dostępne od razu, a awarie są częste. Np. serwer starcrafta do grania peer-to-peer.

0

Na okoliczność spłonięcia DC masz (możesz mieć) georedundancję, czyli replikację danych do kolejnego DC.
Wydajność, bezpieczeństwo, koszty, czas developmentu to wymagania stojące ze sobą w sprzeczności. Dlatego ważne jest jaki jest cel biznesowy, jak szybka faktycznie potrzebuje być aplikacja, czy można się pogodzić ze stratą danych z ostatnich 5 minut, czy dane muszą być dostępne w 1ms, czy 100ms i czy masz budżet na infrastrukturę na poziomie $100 miesięcznie, czy może raczej $100000

Co do serwera SC, pewnie przychodzące dane, na wejściu do backendu, wrzuciłbym jako event (request log), do jakiejś kolejki, jednocześnie wysyłając je do instancji serwisu obsługującego konkretną rozgrywkę, który trzymałby te dane w pamięci i był odpowiedzialny za przesłanie ich do przeciwnika. Nie wiem czy akurat w tym przypadku nie lepiej użyć jakiegoś SIPa i nawiązać bezpośrednie połaczenie p2p.

1 użytkowników online, w tym zalogowanych: 0, gości: 1