SQL or NoSQL?

0

Witam,
tak się zastanawiam nad wyborem bazy do jednego z projektów. Chodzi o to, że np. będzie podobny dokument co faktura i chyba mniej więcej każdy wie jak to wygląda w bazie sql. Teraz pytanie czy lepiej zrobić całą bazę sql czy całą bazę nosql czy zrobić rozwiązanie hybrydowe? Na początku raczej to nie będą duże ilości danych, ale później może się to rozrosnąć, a przepisywanie projektu na inną bazę albo części projektu to jest trochę roboty. Chodzi głównie o taki właśnie rzeczy jak te faktury.

Myślę o rozwiązaniu hybrydowym, czyli jak są relacje to robimy to bazie sql, a jak są takie rzeczy jak np. te faktury to robimy je w nosql i do bazy sql wsadzamy jakiś odnośnik do nosql.

Chciałbym dowiedzieć się co mają do powiedzenia bardziej doświadczeni użytkownicy.

0

A co chcesz z tymi fakturami robić? Chcesz korzystać z ich treści w jakiś sposób? Wtedy jakieś bazy dokumentowe by się mogły przydać. Napisz co chcesz z tym robić, inaczej nie da się odpowiedzieć.

0

Czytać dane w aplikacji jako lista i pojedynczy dokument, generowanie pdf, filtrowanie po danych/stanach np. rodzaj i stan (chociaż to może w sql siedzieć), może jakieś kwoty oraz pozycje z tej faktury wyciągać do jakichś statystyk np. kupiłem tyle sprzedałem za tyle. To tak co mi na szybko przyszło do głwy

2

Do takich zastosowań oczywiście SQL tylko i wyłącznie.

0

Co do rozrośnięcia - musiałbyś mieć naprawdę miliony rekordów na niezbyt mocnej maszynie, żeby używając dobrze zaprojektowanej bazy SQL mieć problem z wydajnością.

3

To zależy... Jeżeli system raportowy chcesz przetrzymywać poza główną strukturą bazy danych tzn. tworzysz małą hurtownię, do której dorzucasz dane np. raz na dzień, a raporty będą zwykłymi zapytaniami bez JOINów to NoSQL będzie dobrym rozwiązaniem (w praktyce przechowujesz tam zrzuty widoków, a operacje na nich są prostymi selectami). Podobnie ma się sprawa z drukowaniem. Warto rozważyć przechowywanie kopii danych po stronie serwisu wydruków jako np. obiekty JSON (w NoSQL) podstawiane bezpośrednio do szablonu z którego generujemy PDFy (funkcjonalność druku seryjnego z EXCELA).

Jeżeli jednak wszystkie dane chciałbyś albo musisz trzymać w ramach jednej bazy (schematu) to SQL będzie lepszym rozwiązaniem.

0

Widzę, że temat nie jest taki prosty jak mi się zdawało. Pomyślę nad tym wszystkim i w przyszłym tygodniu przedstawię co dokładnie będę robił/ jaki dane będą potrzebne i spróbuje oszacować liczbę takich dokumentów.

0

Dobra już wiem jak to mniej więcej ma wyglądać. Głównie to będą inserty, ale też zbieranie danych statystycznych tak jak już wcześnie wspomniałem, czyli faktury opłacone, nie opłacone itd... Dodatkowo będzie jakby przerzucanie faktury z bazy A do bazy B z selekcją pozycji. No i oczywiście możliwość drukowania zarówno pojedynczego dokumentu jak i całej serii.
Jeśli chodzi o ilość to w tej chwili będzie tworzony dość zaawansowany prototyp, w którym nie będzie dużo danych, ale jeśli wszystko wypali to prototyp będzie rozwijany i tam dane po pewnym czasie przekroczą milion rekordów. Chodzi też o to, żeby już zrobić dość dobrze prototyp aby przejście do ostatecznej wersji odbyło się jak najmniejszym kosztem.
Jeszcze tak mi przychodzi do głowy jedna kwestia. Czy bazy mają coś takiego jak samouzupełnianie? Dokładnie chodzi o to aby po jakichś danych sprawdzać dwie bazy (wybrane tabele) czy są zgodne jeśli w jednej bazie brakuje tych danych to się same uzupełniają i są zgodne. Coś jak replikacja np. w mongodb, tylko, że nie całej bazy. Czy raczej samemu będzie trzeba coś takiego napisać? Jeszcze tak się zastanawiam np. że dane dokumentów można trzymać w jednej bazie, a inne dane np. użytkowników na drugiej bazie.

0

NoSQL to nie jest tylko kwestia skalowania. Miejsce, gdzie IMHO NoSQLe rozkładają RDBMSy na łopatki całkowicie jest zapewnienie wysokiej dostępności. W RDBMSie padnie Ci dysk/pamięć/procesor/karta sieciowa i co? I masz downtime. Nawet jak masz slave'a z hot-standby lub jakąś inną replikację, zanim zdiagnozujesz i przełączysz [1], użytkownicy będą się wkurzać, że serwis nie działa.

Kolejna rzecz: czy fakt, że nie przewidujecie dużo danych, nie wynika przypadkiem z tego, że na starcie założyliście, że po prostu nie będziecie zbierać wielu danych, bo by było ich za dużo? Trend jest obecnie taki, żeby zbierać jak najwięcej surowych danych (bo w końcu można), a później je masowo analizować np. Hadoopem. I tu znowu NoSQLe są znacznie lepsze.

A brakiem transakcji bym się nie przejmował. Banki przedkładają dostępność nad spójność (transakcje)... Większość ludzi nie zdaje sobie sprawy, że nie potrzebuje transakcji, a przynajmniej nie w sensie ACID.

[1] Tak, wiem, że teoretycznie można to zautomatyzować. I nigdy w życiu nie widziałem, żeby takie coś poprawnie zadziałało. Fail-over ma taką wadę, że jest jak backup, którego się nie testuje. W krytycznej sytuacji zawodzi.

Edit:

Głównie to będą inserty, ale też zbieranie danych statystycznych tak jak już wcześnie wspomniałem, czyli faktury opłacone, nie opłacone itd...

Jeśli głównie inserty + zbieranie danych na potrzeby statystyczne, to chyba nie ma nic mocniejszego obecnie niż Apache Cassandra.
http://www.quora.com/Why-are-the-writes-of-Cassandra-executed-faster-than-MySQLs

Jeszcze tak mi przychodzi do głowy jedna kwestia. Czy bazy mają coś takiego jak samouzupełnianie? Dokładnie chodzi o to aby po jakichś danych sprawdzać dwie bazy (wybrane tabele) czy są zgodne jeśli w jednej bazie brakuje tych danych to się same uzupełniają i są zgodne.

Cassandra (OSS) i Amazon DynamoDB (komercyjne) mają replikację zapisów + read-repair + anti-entropy. W praktyce działa właśnie tak, że jak jakiś danych na jednym węźle nie ma, to się dociągną tylko brakujące, nie cała baza.

Coś jak replikacja np. w mongodb, tylko, że nie całej bazy.

Akurat wzorować się w kwestii replikacji na MongoDB to jest bardzo, bardzo zły pomysł. MongoDB jest cudowne na jednym serwerze i mieszczą się całe w RAM. Zaprojektowane przez projektantów ładnego API, speców od marketingu i pisania ładnych blogów. Jak masz więcej niż jeden serwer, zaczynają się schody. To jest chyba najbardziej poryta architektura replikacji jaką widziałem. No i jest oparta o fail-over. Nie idź tą drogą.

Z innych rzeczy, MongoDB nie jest w pełni OpenSource, przynajmniej nie w tym sensie co inne bazy otwartoźródłowe jak np. PostgreSQL, HBase czy Cassandra. Cały kod jest własnością 10gen i jest licencjonowany na AGPL, która jest dosyć restrykcyjną licencją (złośliwi twierdzą, że "The stated purpose of the original GPL was to protect users from vendors. The AGPL is designed to protect vendors from users").

0
Krolik napisał(a):

W RDBMSie padnie Ci dysk/pamięć/procesor/karta sieciowa i co? I masz downtime. Nawet jak masz slave'a z hot-standby lub jakąś inną replikację, zanim zdiagnozujesz i przełączysz [1], użytkownicy będą się wkurzać, że serwis nie działa.
[...]
[1] Tak, wiem, że teoretycznie można to zautomatyzować. I nigdy w życiu nie widziałem, żeby takie coś poprawnie zadziałało. Fail-over ma taką wadę, że jest jak backup, którego się nie testuje. W krytycznej sytuacji zawodzi.

@Krolik, ale to chyba na Linuksach. Windows Server Failover Clustering po prostu działa, i nie potrzebuje żadnego admina do przełączania. (Co to w ogóle za pomysł?!) A bazy i tak siedzą na dyskach w SANie, który niweluje problemy z dostępnością i padającymi dyskami.

Przetestowanie failoveru też jest banalne, a jeśli admin tego nie zrobił na etapie konfigurowania infrastruktury/wdrożenia systemu, to znak, że należy go zwolnić.

0

Serwery i tak pewnie gdzieś będą obsługiwane przez zewnętrzne firmy.

1

@somekind: Przetestujesz failover na etapie wdrożenia i wszystko fajnie. Serwer padnie po roku od wdrożenia - jaką masz gwarancję, że w ciągu tego roku ktoś czegoś nie schrzanił (albo nie schrzaniło się samo)? Jeżeli nie ma procedury regularnego testowania failoveru przy każdej zmianie na produkcji, należy założyć, że go nie ma.
Poza tym jak przetestujesz serwer backupowy (sam failover może zadziałać poprawnie, ale backup wcale nie musi działać poprawnie)? Oczywiście w pewnym stopniu zawsze przetestujesz, ale tak naprawdę jedyna w 100% dobrze testująca metoda, to celowo wyłożyć serwer główny na systemie produkcyjnym i zobaczyć czy backup zadziała. Już widzę jak ktoś w korporacji się zgodzi na takie testowanie.

Poza tym:

  1. jak rozróżnisz w pewny sposób pad serwera od padu infrastruktury sieciowej?
  2. jak rozróżnisz serwer tymczasowo przeciążony od serwera padniętego? Jeżeli zrobisz failover przy chwilowym przeciążeniu (bo poleci kilka timeoutów pod rząd, to się pakujesz w jeszcze większe kłopoty)
  3. jak zabezpieczysz się przed awarią samego systemu monitorującego serwery lub jego infrastruktury sieciowej? Sam failover też podlega awariom. Będziesz monitorował system monitorujący? A może monitorował system monitorujący system monitorują StackOverflowException
  4. bazy danych to nie serwery aplikacyjne - mają swój stan - jak zabezpieczysz się przed równoczesnym zapisem różnych informacji do serwera głównego i backupu? jeżeli system zakłada, że "split brain problem" nigdy nie nastąpi, bo failover nigdy do tego nie dopuści, to gdy to się w końcu stanie, masz problem ze spójnością danych

Wszystkie setupy, jakie widziałem, które brały pod uwagę powyższe sytuacje miały jedną wspólną cechę:
były mocno złożone, a liczba przypadków brzegowych, które musiały obsługiwać była horrendalnie duża. Poprawność takiego systemu jest praktycznie nie do udowodnienia. Do tego dochodzą zwyczajne błędy w kodowaniu (i nie wierzę, że implementacja MS jest od nich wolna - systemy rozproszone są jednymi z najtrudniejszych do testowania i weryfikacji).

Duża złożoność + trudne testowanie (w praktyce - jak napisałem wyżej brak realnych możliwości przetestowania) => wnioski wyciągnijcie sami.
Failover jest ok, ale nie jeśli masz SLA na uptime 99,9999%.

Jeśli chodzi o samo MongoDB i jego mechanizmy replikacji / failoveru, to tu jest napisane, "co może pójść nie tak". Zwłaszcza polecam uwadze punkt 6.
http://nosql.mypopescu.com/post/12466059249/anonymous-post-dont-use-mongodb

0
Krolik napisał(a):

Poza tym jak przetestujesz serwer backupowy (sam failover może zadziałać poprawnie, ale backup wcale nie musi działać poprawnie)? Oczywiście w pewnym stopniu zawsze przetestujesz, ale tak naprawdę jedyna w 100% dobrze testująca metoda, to celowo wyłożyć serwer główny na systemie produkcyjnym i zobaczyć czy backup zadziała. Już widzę jak ktoś w korporacji się zgodzi na takie testowanie.

Trochę trudno wyobrazić mi sobie, żeby lustrzane kopie zachowywały się różnie...
Tak czy siak, przepięcie usług z jednego serwera na drugi trwa minutę. Można to robić nawet codziennie w sposób niewidzialny dla użytkowników. Wtedy praktycznie zawsze wiemy, czy wszystkie serwery działają tak samo.

  1. jak rozróżnisz w pewny sposób pad serwera od padu infrastruktury sieciowej?

Od sprzętu są admini, za awarie sprzętu odpowiadają oni lub producent. Ja tworzę systemy informatyczne, jestem trzy warstwy nad sprzętem. I jakie to ma znaczenie z punktu widzenia dostępności bazy danych?

  1. jak rozróżnisz serwer tymczasowo przeciążony od serwera padniętego? Jeżeli zrobisz failover przy chwilowym przeciążeniu (bo poleci kilka timeoutów pod rząd, to się pakujesz w jeszcze większe kłopoty)

Serwer padnięty to ten, który padł fizycznie, albo padły na nim usługi RDBMS. Przeciążony jest w pozostałych przypadkach braku odpowiedzi.
I jakie kłopoty? Minuta niedostępności dla użytkownika? No przed tym, to się trzeba już po stronie aplikacji zabezpieczyć.

  1. jak zabezpieczysz się przed awarią samego systemu monitorującego serwery lub jego infrastruktury sieciowej? Sam failover też podlega awariom. Będziesz monitorował system monitorujący? A może monitorował system monitorujący system monitorują StackOverflowException

Jakiego systemu monitorującego serwery? Żeby przestał działać failover, muszą paść wszystkie jego węzły. A wtedy failovera i tak nie ma po co działać, bo na nic nie przełączy.

  1. bazy danych to nie serwery aplikacyjne - mają swój stan - jak zabezpieczysz się przed równoczesnym zapisem różnych informacji do serwera głównego i backupu?

Bo jest to fizycznie niemożliwe, skoro oba są widziane pod jednym connection stringiem?

Duża złożoność + trudne testowanie (w praktyce - jak napisałem wyżej brak realnych możliwości przetestowania) => wnioski wyciągnijcie sami.

Z tego co napisałeś, wychodzi wniosek wychodzi taki, że rozwiązania nie od MS to nie jest dobry pomysł, jeśli się chce mieć system always on. Ale na 99% nie jest to prawda.

0

Bo jest to fizycznie niemożliwe, skoro oba są widziane pod jednym connection stringiem?

Czyli masz SPOF (Single Point Of Failure). W tej sytuacji, faktycznie automatyczny failover nie jest żadną sztuką. Tyle, że nie chroni przed wieloma rodzajami awarii.

0

Dobra chłopaki, ale ciągle brakuje mi jakieś konkretnej odpowiedzi co lepiej będzie się nadawać - SQL czy NoSQL? Na budowę serwerowni i tak mnie nie stać, więc tym się będzie zajmować zewnętrzna firma. Mi zależy teraz tylko na tym co mam wybrać żeby zacząć coś tworzyć. Co będzie wydajne bardziej? Które rozwiązanie będzie lepsze do tego typu zastosowań?

3

U nas uzywamy i tego i tego, system oparty o architekture WOA + MOM (Web Oriented Application + Message Oriented Middleware), AMQP/Gearman, uzywamy transakcyjnego SQL (MySQL) i NoSQL (Cassandra) rownolegle i dodatkowo kilka rodzajow "cache", od poczatku projektowany aby nie bylo SPOF i wspieralo rozlozenie w kilku geolokacjach (stany/europa/azja), w przygotowaniu auto skalowanie:

  • interfejs aplikacji to tylko i wylacznie stateless http (restapi)
  • dzielimy zapytania na read (GET) i write (POST, PUT, DELETE)
  • request stuka do "endpoint/gateway api", zaleznie od tego co ma robic jest forwardowany/dispatchowany do kolejnego "api" ktore go obsluguje
  • jezeli wynik requestu jest gotowy to odpowiedz zostaje zwrocona Od razu
  • jezeli nie, to klient "wisi", a request zostaje dodany do kolejki (sync/async)
  • aktor/worker przetwarza request, jezeli to read to po prostu zwraca wynik z warstwy persitence (Slave SQL/NoSQL), jezeli to write to robi transkacje ktora leci do Master SQL i ewentualnie "czysci" powiazane dokumenty w NoSQL
  • wynik dzialania aktora jest wrzucany do klastra Cassandry jako dokument
  • wstrzymany klient dostaje wynik

SQL aktualnie mamy na Amazon RDS w kilku strefach dostepnosci, ale ogolnie przyjmujemy ze to jest "zwykly" Master Slave, nie robimy shardu
NoSQL to klaster cassandry, keyspace jest replikowany w pierscieniu na trzy wezly, mozna dodac wiecej
W przygotowaniu autoscaler, ktory wykrywa trend ruchu i doczepia kolejne instancje endpointow i workerow aby zwiekszych przepustowosc.
Load balancing jest zrobiony czesciowo na strefie DNS (Geo DNS roundrobin) oraz w bardziej standardowy sposob po http, endpointy lacza sie ze zduplikowanymi serwisami w architekturze.

Krotko: mozemy ujebac cala strefe dosptenosci i aplikacja nadal bedzie dzialac, po przywroceniu dane sa replikowane przez cassandre, w przypadku failu SQL, przepinamy Master na pierwszego Slave, mamy opcje zrobic rownolegle dwa klastry MySQL, ale to aktualnie robi za nas Amazon RDS, w kodzie po prostu taki ficzer siedzi...

Ogolnie dziala, co do samego SQL/NoSQL - jak trzymasz info o kasie itp to ja bym sie trzymal SQL, ale zeby go nie "zajebac" rozwazylbym kolejke transakcji zeby sobie powolutku je przetwarzac a jako persistence dla kolejki mozna uzyc NoSQL i tu polecam Cassandre bo dziala zajebiscie dobrze :)

0

jak trzymasz info o kasie itp to ja bym sie trzymal SQL

Ale właściwie dlaczego? Z przyzwyczajenia? ;)

0
Krolik napisał(a):

jak trzymasz info o kasie itp to ja bym sie trzymal SQL

Ale właściwie dlaczego? Z przyzwyczajenia? ;)

U nas akurat mamy troche kodu legacy ktory bazuje na SQL, ale apropos "kasy" przydaje nam sie transakcyjnosc, wrzucamy caly blok operacji na raz i mozemy je cofnac w przypadku problemu, dodatkowo transakcje sa synchroniczne wiec jak zmieniaja sie stany itp to mam pewnosc ze nie ma race condition i po zapisie informacja jest tam gdzie powinna byc a nie dopiero "krązy" lub czeka na zapis, ma to dla mnie dosc sporo znaczenie w przypadku awari systemu ktory operuje pieniedzmi.

Cassandra jest super, ale przykladowo zrob test z inkrementacja licznikow to stany odczytywane w danej chwili nie zawsze sie zgadzaja bo dane potrzebuja czasu na "rozlozenie" sie po klastrze.

0

Zgadzam się, że transakcje są wygodne dla programisty, ale jakoś nie zauważyłem, aby rozproszone systemy finansowe działały w sposób stricte transakcyjny tj. ACID.

  1. Jak zasilam konto, to kasa jest realnie dostępna dopiero po jakimś czasie, np. nie mogę sobie zasilić konta, a za minutę pójść do bankomatu i wypłacić.
  2. Jak obciążam konto, płacąc kartą, to saldo też jest zmieniane dopiero po jakimś czasie.
  3. Lepiej, mogę zapłacić kartą w trybie offline (np. w systemie Visa lub MasterCard) i bank w ogóle nie wie o transakcji dopóki nie nastąpi synchronizacja.
  4. Zdarzyło już mi się, że instytucja finansowa się kropnęła i przelała mi pieniądze dwukrotnie - był to błąd systemu informatycznego.
  5. Zdarzyło mi się nie dostać pieniędzy z bankomatu, a transakcja w banku została zatwierdzona. Nie tylko mnie. Oczywiście skorygowali po reklamacji.

Nie wiem jak w innych instytucjach, ale banki zdecydowanie nie są ACID, a właśnie BASE (czyli spójność ewentualna). Podstawowa reguła - zapisać wszystko co najmniej 2 razy i ewentualnie dokonać korekty / reklamacji. Natomiast zrobienie pełnego ACID w ramach systemu rozproszonego nie jest praktykowane (2-phase commit pomiędzy dwoma bankami? a może Paxos? to by była masakra).

BTW: Co do Cassandry, to jeśli zapisujesz z CL.QUORUM to masz spójność natychmiastową. A Cassandra 2.0 ma lekkie transakcje (CAS) zaimplementowane na bazie Paxosa. Właściwie jakby się uprzeć, jak masz CAS, to ACID taki jak w RDBMSie też zrobisz (tylko nie wiem po co).

dodatkowo transakcje sa synchroniczne wiec jak zmieniaja sie stany itp to mam pewnosc ze nie ma race condition i po zapisie informacja jest tam gdzie powinna byc a nie dopiero "krązy" lub czeka na zapis, ma to dla mnie dosc sporo znaczenie w przypadku awari systemu ktory operuje pieniedzmi

Transakcje synchroniczne w systemie rozproszonym mają jedną dużą wadę. Jak się wyłoży tylko część systemu, to cały system nie działa. I wtedy jest jak miałem kiedyś w ZUSie "no, nic nie poradzę, system coś dzisiaj nie działa, proszę przyjść jutro". Nie pamiętam gdzie, ale wyczytałem, że w przypadku bankomatów bankom opłaca się bardziej ponieść ryzyko operacji offline (asynchronicznej) w przypadku awarii komunikacji z bankiem niż odmówić wypłaty pieniędzy.

edit: o znalazłem http://highscalability.com/blog/2013/5/1/myth-eric-brewer-on-why-banks-are-base-not-acid-availability.html

wrzucamy caly blok operacji na raz i mozemy je cofnac w przypadku problemu

Ciekawe jak to robili przed epoką komputerową? Zauważ, że kiedyś nie było RDBMSów, a systemy finansowe działały sprawnie i nie było problemów ze spójnością. Reguły gry od tamtych czasów się nie zmieniły. Nadal np. księgowość jest oparta na przyrostowym zapisie informacji, który bez problemu można zrealizować w każdym systemie NoSQL. Nie ma miejsca na jakiekolwiek wycofywanie transakcji, zamiast tego dozwolone są tylko korekty.

0
Krolik napisał(a):

...

Najpewniej masz racje :)
Po prostu tak to zrobilismy, co do awari to kolejkujemy transakcje i mamy "mirror" w cassandrze wiec nawet jak SQL master zdechnie to nie tracimy danych, jedynie przetwarzanie sie opoznia o czas przelaczenia na nowy master.

Jest jeszcze inny aspekt SQL/NoSQL: nawet jezeli zespol programistow jest w stanie ogarnanc system tak aby byl w miare niezawodny to najczesciej nie programisci, a it ops zajmuja sie deploymentem, monitorowaniem i utrzymaniem aplikacji, a dodawanie kolejnych nowosci do stosu technologicznego idzie im topornie, po prostu SQL jest imho prostszy w utrzymaniu ;)

0

Ooo chyba trochę zamuliłem. Dzięki za wszystkie info. Na pewno spróbuje cassandry do części danych, nie wiem czy do wszystkiego, zobaczymy. Raczej będę się kierował ku rozwiązaniu hybrydowemu póki co, może jak cassandra będzie śmigać dobrze to w całości będzie w cassandrze.

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