Kiedy osobna baza do odczytów i osobna do zapisów?

0

W CQRS często stosuje się osobne bazy do odczytu i do zapisu, choć nie jest to obowiązkowe. Ale na jakiej podstawie podjąć taką decyzję, że robimy dwie osobne bazy danych?

  • Czy jak przewidujemy znacznie więcej odczytów niż zapisów to wtedy bardziej dwie osobne bazy danych?
  • A jak przewidujemy podobną liczbę odczytów i zapisów to wtedy bardziej jedna baza danych?
0

Co znaczy wiecej i mniej? To jest bardziej zlożony temat i nie da sie tego określić tylko na podstawie takiego kryterium.

0

Przy projektowaniu aplikacji jedno z podstawowych pytań jakie należy zadać to "What is the expected read to write ratio?", ale nigdzie nie jest wyjaśnione co zrobić jak współczynnik odczytów jest większy niż zapisów a co w sytuacji jak jest zbliżony.

0

Ale ja nie rozumiem, procesor może nie domagać? Czy trzymasz bazę na SSD? Z czym tam jest problem? Jakie rozmiary są odczytywane? 1000 użytkowników potrzebuje w tej samej sekundzie 1GB danych?
.

Przy przepustowości pamięci RAM wynoszącej 25,6 GB/s, w ciągu jednej sekundy można odczytać 4 GB danych 6,4 razy, co odpowiada transferowi 25,6 GB danych.

Teraz czy wiesz ile zajmuje jeden bit?

Ludzki mózg nie przetworzy takiego rozmiaru informacji , jeśli to nie jest nagranie video.

Bo co potrzebujesz w jednej sekundzie bazę adresów zamieszkania każdego człowieka w galaktyce wraz z informacjami o stanie konta, historię zatrudnienia itp?

Dzielisz temat na mniejsze porcje. Jeśli optymalizujesz bazę danych to też dzielisz to na mniejsze części ale to się rzadko robi.

Pomijajć fakt, że te dane mogą być skompresowane.

0

Inaczej: "What is the expected read to write ratio?" - to jest jedno z pytań jakie powinien zadać architekt aplikacji przy tworzeniu nowej aplikacji na etapie projektowania jej architektury. Ja architektem nie jestem, ale chciałbym wiedzieć dlaczego to pytanie i odpowiedź na nie jest tak ważne.

0
aleksandercherpski2 napisał(a):

Inaczej: "What is the expected read to write ratio?" - to jest jedno z pytań jakie powinien zadać architekt aplikacji przy tworzeniu nowej aplikacji na etapie projektowania jej architektury. Ja architektem nie jestem, ale chciałbym wiedzieć dlaczego to pytanie i odpowiedź na nie jest tak ważne.

Ograniczenia fizyczne sprzętu, koszt jego zakupu modernizacji, wygoda korzystania. Koszt - chodzi o koszt używania.

0

Ograniczenia fizyczne sprzętu, koszt jego zakupu modernizacji, wygoda korzystania. Koszt - chodzi o koszt używania.

Hm......... jesteś pewien, że o to tu chodzi? W sensie jak liczba odczytów będzie większa niż zapisów to koszt infrastruktury będzie większy niż jak liczba odczytów i zapisów będzie taka sama? 🤔

0
aleksandercherpski2 napisał(a):

Ograniczenia fizyczne sprzętu, koszt jego zakupu modernizacji, wygoda korzystania. Koszt - chodzi o koszt używania.

Hm......... jesteś pewien, że o to tu chodzi? W sensie jak liczba odczytów będzie większa niż zapisów to koszt infrastruktury będzie większy niż jak liczba odczytów i zapisów będzie taka sama? 🤔

" to jest jedno z pytań jakie powinien zadać architekt aplikacji przy tworzeniu nowej aplikacji na etapie projektowania jej architektury. Ja architektem nie jestem, ale chciałbym wiedzieć dlaczego to pytanie i odpowiedź na nie jest tak ważne."

Dlatego to jest tak ważne.

5

@johnny_Be_good Nie wprowadzaj w błąd. CQRS nie rozwiązuje problemu zasobów sprzętowych.
Pracowałeś gdzieś przy systemie w takiej architekturze?

Ogólnie, choć nie jestem architektem. Jakie zasady ja znam. Kwestia balansu między rodzajem zapytań. Powiedzmy, że masz do generowania duże raporty, nawet raz dziennie. Do tego musisz rozpocząć transakcję, a odczyt danych z DB trwa 20 minut. Czy możesz sobie pozwolić na brak możliwości zapisu przez 20 minut?
I odwrotnie, np. zapisujesz dane z częstotliwością 100 razy na sekundę, co może spowodować problemy z odczytem.
W CQRS możesz nawet używać różnych baz, nie musi to być baza SQL w może być to kombinacja typu Redis + SQL.
Jeszcze innym aspektem jest skalowalność.
Nie znam żadnego złotego środka i chyba nikt go nie opisze. Ale jak widzisz gdzieś potencjalne wąskie gardło które może rozwiązać CQRS i rozdział baz, to możesz myśleć o takim wdrożeniu.

1

@johnny_Be_good cytat "Nie wiem co to jest CQRS" 😅 - no to wprowadziłeś mnie w błąd i udzieliłeś błędnych odpowiedzi, wypowiedziałeś się na temat o którym nie masz pojęcia...... ja szukam eksperckich odpowiedzi takich jak wypowiedź @jurek1980 . Nie rozumiem po co się więc wypowiedziałeś, czy moderator może usunąć odpowiedzi Johnney, które wprowadzają w błąd? @somekind @Riddle

0
aleksandercherpski2 napisał(a):

@johnny_Be_good cytat "Nie wiem co to jest CQRS" 😅 - no to wprowadziłeś mnie w błąd i udzieliłeś błędnych odpowiedzi, wypowiedziałeś się na temat o którym nie masz pojęcia...... ja szukam eksperckich odpowiedzi takich jak wypowiedź @jurek1980 . Nie rozumiem po co się więc wypowiedziałeś, czy moderator może usunąć odpowiedzi Johnney, które wprowadzają w błąd? @somekind

Pytasz się o temat nie nawiązując do sprzętu. Myślisz, że to w jakimś eterze pracuje? Najprostsza pętla może zamulić procesor i wtedy nie zrobisz nic a Ty jak mała dziewczynka "o tym nie chcę słyszeć". Zasłoń sobie uszy dłońmi i mów "ja nie słyszę! ja nie słyszę!".

Wszystko w IT się zaczyna od obsługi sprzętu.

Ale dlaczego ja nie mogę mieć wszystkiego w tym samym czasie? To jest pytanie dorosłego człowieka?

1

Chodzi o to, że jeśli system jest read-heavy to masz jedna bazę do zapisu i x kopii wykorzystywanych do odczytu.

Wszystkie te socjalmolochy są mocno read heavy, więc wyobraz sobie, co by było gdyby była jedna instancja.

https://nadtakan-futhoem.medium.com/what-is-read-replicas-d5f15e6c3b21

1
rjakubowski napisał(a):

Chodzi o to, że jeśli system jest read-heavy to masz jedna bazę do zapisu i x kopii wykorzystywanych do odczytu.

Wszystkie te socjalmolochy są mocno read heavy, więc wyobraz sobie, co by było gdyby była jedna instancja.

https://nadtakan-futhoem.medium.com/what-is-read-replicas-d5f15e6c3b21

Czyli generalnie można by wnioskować, że tam gdzie duża przewaga odczytów nad zapisami to dobrze jest stosować osobne bazy danych.

0

@aleksandercherpski2: za bardzo generalizujesz, bo nie da się o tak założyć - wydajność zależy od x czynników, ale jest to sposób na bottleneck po stronie bazy.

2

@johnny_Be_good pojedyncze bity czy bajty nie mają tu znaczenia. Wiem że tam robisz sobie te swoje niesamowite programy ale zapewnie wysokiej dostępności i skalowalności to całkiem inna rzecz niż jakiś prosty edytor HTML który piszesz. Tam się marnuje zasoby żeby zapewnić wysoka dostępność dlatego że firmę na to stać. Tak samo pisanie o tym że ile to danych potrzebujesz i wrzucanie jakiś losowych wartości odczytu z dysku xD no przecież nikt nie robi raportu który tylko pobiera dane z jednej tabeli i elo. Ja pracuje w systemie który ma 3 cyfrowa liczbę raportów i są to maluchy od kilkudziesięciu linijkę do kilku tysięcy. Tu nie chodzi o operacje In/out z dysku o której mógłbym pomyśleć taki początkujący jak ty tylko o przetworzenie dużej ilości danych.

Dwie bazy czy więcej powinny wynikać z potrzeb firmy. Na poczatku jedna wystarczy z nawiazka a potem gdyby sie pojawialy problem to trzeba to przeprojektować. Możesz od razu to robić z tą myślą jeśli robisz projekt do szuflady, musisz tam przemyśleć jak synchronizować te bazy, jak z nimi pracować żeby żadnej nie przytkać.
Nie ma jednej uniwersalnej odpowiedzi bo problem jest nietypowy.

6
aleksandercherpski2 napisał(a):

W CQRS często stosuje się osobne bazy do odczytu i do zapisu, choć nie jest to obowiązkowe. Ale na jakiej podstawie podjąć taką decyzję, że robimy dwie osobne bazy danych?

  • Czy jak przewidujemy znacznie więcej odczytów niż zapisów to wtedy bardziej dwie osobne bazy danych?
  • A jak przewidujemy podobną liczbę odczytów i zapisów to wtedy bardziej jedna baza danych?

Wydajność jest jednym z czynników jaki można wziąć pod uwagę, innym jest sposób odczytu danych. Czasami model relacyjny nie jest wydajny przy odczytach.

Wyobraź sobie, że masz skomplikowane odczyty, joiny w relacyjnej bazie danych przeszkadzają zamiast pomagać, bo jest tych danych i zapytań na minutę za dużo, więc rozsądnym rozwiązaniem jest zacząć tworzyć model odczytowy np w Cassandrze, gdzie mamy tabele per use case, duplikację danych i żadnych joinów. Potrzebuję pogrupowaną listę zamówień klienta z agregacjami, wyliczeniami i jakimiś danymi historycznymi, to zamiast skomplikowanego sql-a mam jedno zapytanie SELECT FROM TABELA i gotowe.

W kontrze do powyższego można zastosować rozwiązanie hybrydowe, gdzie dane aplikacji siedzą sobie normalnie w bazie relacyjnej, a dane do takich analiz/odczytów przepychamy do bazy analitycznej za pomocą narzędzi ETL aby odciążyć bazę transakcyjną.

Weź pod uwagę, że osobna baza transakcyjna i odczytowa/analityczna to potencjalny brak spójności danych i opóźnienia w świeżości danych. Bo np proces odpowiadający za umieszczenie informacji o statusie użytkownika w bazie odczytowej się wysypał i w bazie transakcyjnej użytkownik ma nowy status a w odczytowej stary.

Wracając do CQRS-a i dwóch baz danych, to nie bez powodu łączy się go z Event Sourcingiem, gdzie osobna baza danych do odczytu jest koniecznością, bo nie da się robić efektywnych zapytań na ciągach zdarzeń biznesowych.

3

@aleksandercherpski2
Zasadniczo są 2 pytania:

  1. Czy potrzebna jest wysoka dostępność?
  2. Czy klienta stać na takie rozwiązanie?

Nie ma jakiegoś ogólnego wzoru np jak na 10 odczytów masz jeden zapis to robisz osobno bazy.

Żeby zobrazować problem wyobraź sobie duże call center, w którym mają dziesiątki tysięcy pracowników, którzy dzwonią do ludzi z ankietami, ofertami i innym badziewiem oraz bazę danych, która trzyma informacje o tych pracownikach, ludziach do których dzwonią. Taka firma nie może pozwolić sobie na to by pracownik czekał minute na każdy zestaw danych. Bo traci pieniądze. Dlatego musi mieć wysoką dostępność odczytu. Z kolei wynik pracy musimy sobie utrwalić. I tak dochodzimy do wniosku że dzielimy sobie na 2 części i odczyt robimy z redisa a zapis do postgresa

Kolejny przykład wyobraź sobie laboratorium, coś jak cern i LHC przeprowadzasz bardzo kosztowny eksperyment i odczyty muszą zostać zapisane jak najszybciej, bo utrata choć ich części powoduje że badanie traci sens. W ten sposób dochodzimy do wniosku że musimy zrobić rozproszoną bazę danych.

@johnny_Be_good nie rozumiesz problemu bo operujesz na małych własnościach.

0

Czytam o CQRS, ale czy nie prościej od aktualizacji bazy danych służącej do odczytu byłoby zrobienie trzech kopii bazy danych (1., 3., 4.) w tej samej lokalizacji na różnych dyskach i przełączanie wskaźnika do bazy danych? Rodzaje baz danych:

  1. Do zapisu.
  2. Buforowa ostatnich zmian do zapisu.
  3. Czekająca na przełączenie na bazę danych do odczytu (przełączona z bazy danych do zapisu).
  4. Do odczytu.

Wtedy występowałyby zdarzenia takie jak:

  • Przełączono odczyt do bazy danych nr 3. Po zebraniu od wszystkich klientów baza danych nr 4 aktualizowana byłaby z bazy danych nr 2., której to bazy danych kopię można by zainicjować pustą dla zapisu i aktualizować później jeszcze raz.

Nie byłoby konieczne blokowanie bazy danych do odczytu oraz baza danych do zapisu byłaby tylko blokowana na krótki czas przełączenia towarzyszącej jej bazy buforowej (2.) do nowej pustej bazy.

0
overcq napisał(a):

Czytam o CQRS, ale czy nie prościej od aktualizacji bazy danych służącej do odczytu byłoby zrobienie trzech kopii bazy danych (1., 3., 4.) w tej samej lokalizacji na różnych dyskach i przełączanie wskaźnika do bazy danych? Rodzaje baz danych:

  1. Do zapisu.
  2. Buforowa ostatnich zmian do zapisu.
  3. Czekająca na przełączenie na bazę danych do odczytu (przełączona z bazy danych do zapisu).
  4. Do odczytu.

Wtedy występowałyby zdarzenia takie jak:

  • Przełączono odczyt do bazy danych nr 3. Po zebraniu od wszystkich klientów baza danych nr 4 aktualizowana byłaby z bazy danych nr 2., której to bazy danych kopię można by zainicjować pustą dla zapisu i aktualizować później jeszcze raz.

Nie byłoby konieczne blokowanie bazy danych do odczytu oraz baza danych do zapisu byłaby tylko blokowana na krótki czas przełączenia towarzyszącej jej bazy buforowej (2.) do nowej pustej bazy.

Ty to nazywasz prościej?

Poza tym CQRS stosuje się głównie w sytuacjach gdzie model relacyjny jest ograniczeniem i lepiej do odczytów używać innego typu bazy danych oraz w sytuacji gdy po stronie zapisowej mamy Event Sourcing i zapisujemy nie stan obiektu, tylko zdarzenia biznesowe, które pozwalają odtworzyć stan obiektu bo nie jesteśmy w stanie robić efektywnych zapytań na ciągu zdarzeń.

Posiadanie bazy relacyjnej po stronie zapisowej i odczytowej w CQRS to bezsens, więc nawet nie ma co rozważać takiego scenariusza. Lepiej dołożyć CPU i memory do istniejącej DB zamiast kombinować.

To tak jak z migracją do chmury. Można zrobić lift & shift na usługi IaaS i płakać że drogo i ch**owo. A można zastosować re-platform czy nawet re-architect do cloud-native i cieszyć się chmurą i możliwościami jakie daje.

3

Ale na jakiej podstawie podjąć taką decyzję, że robimy dwie osobne bazy danych?

Na podstawie konkretnego problemu, a nie wydumanego. Jak masz konkretny problem, to przeważnie różne warianty rozwiązań technicznych oraz ograniczenia (czas, pieniądz, regulacje prawne, dostępne zasoby). Rozważasz za/przeciw i wybierasz rozwiązanie, które da się zrobić.

Co brać pod uwagę:

  • wydajność read/write poszczególnych silników (bazy i infrastrukturę pod nie inaczej robi się dla optymalizacji zapisów, a inaczej dla odczytów)
  • czy chcesz niezależnie skalować workloady
  • czy chcesz niezależnie tunować odczyty i zapisy
  • czy chcesz mieć silną spójność czy wystarczy eventual consistency
  • czy dopuszczasz utratę danych / przestoje w odtwarzaniu z backupów (jak długie?)
  • czy masz wymagania dotyczące bezpieczeństwa dostępu do danych (i chcesz te dane fizycznie izolować )
  • itd.
0

Jeszcze kwestia taka, że jeśli chcesz mieć szybki odczyt to zazwyczaj nadajesz indeksy. Zabierają one dodatkowe miejsce na dysku. Dodatkowo indeksy powodują, że zapis może być wolniejszy, więc warto się rozeznać. W uproszczeniu z tym ratio pomyśl, że masz tabele i przybliż sobie ile dziennie użytkowników będzie ją odczytywać, a ile będzie zapisywać nowe dane lub aktualizować obecne. Większość dzisiejszych baz jest przygotowana na naprawdę spore liczby operacji.

0

Spróbuj sobie zaprojektować na kartce wystawianie i wyszukiwanie ofert w sklepie internetowym. Albo rachunek bankowy + przeszukiwanie historii przelewów. Skala - tysiące operacji na sekundę.

0

Z nieporuszonych kwestii to dwa serwisy utrzymywane przez różne zespoły. Jeden read drugi write = dwie bazy.

1
szmeterling napisał(a):

Z nieporuszonych kwestii to dwa serwisy utrzymywane przez różne zespoły. Jeden read drugi write = dwie bazy.

A niekoniecznie, w zależności od modelu biznesowego read i write może być rozwijany i utrzymywany przez ten sam zespół. Kwestia podziału odpowiedzialności. Jeżeli model bazy odczytowej wycieka poza domenę aplikacji, to prawdopodobnie jest to znak, żeby stworzyć osobny zespół od big data/analytics. Ale to już nie CQRS. CQRS to podział odpowiedzialności w ramach aplikacji, nie na poziomie przedsiębiorstwa.

1

Dwie bazy które muszą być ewentualnie spójne to zawsze wyzwianie dla programistów i Ops'ów. Nie podejmował bym tej decyzji od tak.
80% projektów nie powinno korzystać z tego rozwiązania, bo jest to po prostu trudniejsze w utrzymaniu (zazwyczaj gdy idziemy w CQRS na DB używamy SQL + nonSQLa; jeżeli ktoś chce mieć 2x SQL to powinien zrezygnować z kombinowania).

Sytuacje gdzie jest to uzasadnione:

  • Specyficzny usecase np. full text search (gdzie sam search wymaga stosowania odrębnej bazy danych typu ES lub Solr)
  • Dysproporcja ruchu odczyt:zapis, ruch odczytu jest na tyle duży że SQL będzie mieć trudności z jego obsługą
  • Agregacja danych z wielu źródeł (np. pod raporty, dashboardy) - wtedy warto zduplikować dane - to jest nowa odsłona starego data warehouse tylko z noSQL

Na pewno nie jest to uzasadnione gdy chcemy mieć 2x SQL które są sync'owane przez aplikację. To nie ma sensu lepiej trzymać wtedy wszystko w jednej DB która będzie objęta transakcjami. Jeżeli wydajność na to nie pozwala warto rozważyć dodanie 2 lub 3 replik read-only/fail-over i używać ich do odczytu.

Pamiętajcie KISS & YAGNII a nie to co mówią konsultanci!

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