NoSql baze i iskustva
U poslednje vreme (zadnje 2 godine) se sve vise prica o no-sql bazama. Iako izgledaju kao zgodan alat za neke stvari, sigurno da nisu zamena za RDBMS u svakoj situaciji.
Istrazivao sam malo na tu temu i cini mi se da su ove baze pogodne za neki tip web-based aplikacija, koje ne zahtevaju transakcije u isto vreme nad vise tabela (dokumenata), a npr. zahtevaju cesto radi prikaza ili izvestaja, agregaciju rezultata iz vise tabela (sto su tabele normalizovanije to je veca petljancija izvuci neke podatke). Kao primer, vrlo cesto zbog takve organizacije UI-a (sve na izvol'te) dolazi se u situaciju da treba da se radi JOIN nad 6-10 tabela, pa dodatno filtriranje, grupisanje, limiti itd... Nekada stvarno postaje PITA, a i sporo. Ok, tu su indexi i explain, ali voleo bih da bude nesto "lakse". Govoreci no-sql terminologijom, to bi se pamtilo na nivou jednog dokumenta, jedne kolekcije, dok npr. stvari koje se mnogo cesto updateuju, ili rezultati nekih pretraga se mogu pamtiti u Redisu. Siguran sam da ima i neki losih strana ovakve organizacije koje treba pokriti. Nisam testirao i radio u real-time uslovima sa ovakvim tipom baze, tako da sve sto bih izneo su manje-vise pretpostavke i razmisljanja. Evo jednog linka, gde se uporedjuju neki od popularnih no-sql enginea: http://kkovacs.eu/cassandra-vs-mongo...uchdb-vs-redis Gledao sam najvise MongoDB, posto je bas velika buka oko njega. Medjutim naleteo sam i na par clanaka na netu gde ljudi nisu najzadovoljniji istim (http://blog.engineering.kiip.me/post...r-with-mongodb, http://www.zopyx.de/blog/goodbye-mongodb - neki od argumenata su apsolutno validni). Dok, eto Trello ili stackexchange ga guraju uspesno. Glavni zahtevi koje bi trebalo da podrzi no-sql baza su relativno lako skaliranje (master-slave), lakse pisanje tipova upita ili ubrzanje koji su pandan pisanju JOIN-a ili subselecta nad vecim brojem tabela u RDBMS svetu i uopste stabilno okruzenje da tako kazem (gde nece tek tako da podaci nestanu od sebe). Sigurno cu se pozabaviti i sam vise ovim i istraziti i testirati neka resenja. Interesuje me da li je mozda neko imao iskustva sa ovim i naravno ako moze da to podeli :) ? |
Mislim da daleko više pljuvačine možeš pronaći o MySQL-u recimo pa opet rula mnogo velike projekte...
Boj ne bije svijetlo oružje.... |
Moje iskustvo sa mongom je odlicno, ali naravno ja nisam pravio Facebook (a ni Trello). Osnovna prednost u mom slucaju (tracking bannera) je sto su upisi stvarno brzi i sto ti NoSQL daje jednostavan nacin za organizaciju i kasnije dump podataka u komplexnu strukturu sa kojom je lako posle raditi.
Kod RDBMS moras da pravis komplikovane JOIN-e, pa da onda tako dobijene tabelarne podatke slazes u petlji u objekte koji ti trebaju, ovde je to vec tako kreirano u bazi i samo povuces ono sto ti treba. Em zahteva manje koda, em je dosta brze na vecoj kolicini podataka. |
Jedna stvar koju ti ne kazu kada pocnes da radis sa nosql-om - koju bi i sam provalio ali mozda suvise kasno: UVEK cuvaj strukturu dokumenta u kodu i UVEK koristi polje za verziju scheme (ovo vazi ako ti podaci za koje koristis nisu ultra kratkog veka)
Sta pod tim mislim - za razliku od RDBMS-a, Mongo nema strukturu dokumenta (dakle CREATE tabele) - sto znaci da mozes u istu kolekciju da upisujes sta ti je volja... ova sloboda ce te ujesti pre ili kasnije tako sto ces imati kod sa 400 if-ova koji proveravaju da li dokument ima ovo ili ono. Moj savet - definisi strukturu dokumenta u klasi (nesto kao jako tanki ORM), i ako mislis da ces menjati strukturu dokumenta - dodaj jedno polje koje oznacava trenutnu verziju (koje je recimo globalno i definise se na jednom mestu). Kako kod i schema evoluiraju - sve promene ce se svoditi na to da u read() metodi procitas dokument - proveris polje 'verzija' i kastujes ga u odgovarajucu nasledjenu klasu tvoje osnovne ORM klase. Ako nekoga zanima ili mu nije jasno na sta ciljam - mogu da bacim neki snippet da ilustrujem. |
^ dobar pristup, a jos jedan razlog za to da imas precizno definisan model, bar kod MongoDB-a, je sto on ne baca greske ako u upitu trazis polje koje ne postoji, tipa slucajno umesto counter otkucas coumter. A takve greske su uzasno teske za debug, narocito kod upita koji dohvataju podatke, jer je spelling otprilike poslednja stvar koju se setis da proveris (well, prvih 10 puta bar :) )
|
Koliko sam procitao i video, sa jedne strane no-sql daje fleksibilnost, dok sa druge strane (ako nisi disciplinovan i dosledan) mozes da upadnes u problem.
Dosta ljudi pominju da za razliku od mysql migracija, kod MongoDB-a koriste upravo verzije dokumenata, sto im omogucava laksi upgrade/izmene baze. Citat:
|
struktura dokumenta jednostavno mora da se cuva. ono sto je orm kod relacionih baza to je object/data mapping za nosql. sto se samog monga tice za asinhrono okruzenje postoji mongoosejs koji podrzava sheme, nestovanje istih, validaciju, itd. postoji nekoliko data mapping libova za rails i ostale jezike
|
ORM za no-sql baze mislim da se zove ODM (Object Document Mapper).
Potpuno mi je jasno da se trebaju u client kodu mapirati "definicije" baze (kolekcija i dokumenata). Kako radim sa custom napravljenim ORM alatom (koji je godinama peglan), upravo iz tih definicija se izvlace podaci za validaciju, za castovanje podataka na relaciji db-code, te za data migracije i za jos x stvari. Tako da mi je ideja kada i ako dodje do same implementacije, da se isti pristup primeni i za mongo ili neku drugu document bazu. Za PHP postoji Doctrine ODM. |
Citat:
|
Naravno da postoje razni gotovi mapperi ali svaka dodatna biblioteka u projektu zna da ima i svoju cenu. ODM-i nisu teski i mogu biti zabavni za pisanje, posebno ako ti za tvoje potrebe ne treba sva masinerija koju nude OSS resenja.
Posto sam obecao primer evo ga za python. Primer je vrlo jednostavan mada ovo sve moze mnogo vise da se zakomplikuje. Dakle osnovna klasa i globalno mesto gde se registruju modeli i verzije bi bili u modulu koji bi izgledao otprilike ovako: Kôd:
from pymongo import Connection Kôd:
class Calculation(MongoBaseModel) Kôd:
register_version_model(Calculation, 1) Kôd:
class NewCalculation(MongoBaseModel) Kao sto sam rekao moze ovo mnogo vise da se zakomplikuje i nabudzi (metaprogramiranjem i slicnim cakama), naravno fale provere gresaka itd. ali funkcionalni, mali i lagani ODM ne trazi mnogo vise od ovih 30ak linija u Pythonu, bez da se patis sa nekim bloat-om sa github-a. Ako nekome neka python-specific caka nije jasna (mada ih bas i nema u gornjem kodu) rado cu pojasniti. |
^ Hvala puno na trudu i primeru.
Primer je u sustini jasan, posto ima i inline komentara. Mada moze se kao sto kazes zakomplikovati, sto validacijom, sto meta definicijama, a sto jos nekim apstrakcijama. Sto vise automatizma i magicnih stvari to ce biti i kompleksnija implementacija. Imao bih samo jos 2 pitanja, posto vidim da imas iskustva sa MongoDB-om. Kako se sajt ili app (ne znam da li je jedna ili vise koje si radio) ponasaju ukoliko ima malo veceg opterecenja istih - npr. par stotina konkurentnih zahteva u sec? Najvise mislim na race-conditions posto koliko sam shvatio, MongoDB zakljucava celu bazu dok se za jednog korisnika obradjuju podaci? Da li si naisao na jos neke da kazem "klopke" kojih nema u RDBMS svetu. Jedan od primera je ovo verziranje polja. Drugi... video sam na par mesta kada se prave polja u bazi, da samo ime zauzima resurse baze. Ako imas 1000 korisnika u kolekciji users, "username" polje se 1000x pamti, da tako kazem. Pa onda radi optimizacije i performansi npr. mapiraju ga u "usn", pa ga onda "remairaju" u username u samom server/client kodu. Na ovaj nacin (procitah pre neki dan, ne secam se gde) neko je bazu sa 700MB, smanjio na 300MB, sto je vise nego pola. |
Nema na cemu :)
Sto se tice prostora - moj primer je tu uzasno neefikasan jer za SVAKI record cuva verziju. Ovo je nesto sto bi radio u pocetku razvoja, kada postoji velika mogucnost da ces imati izmena same scheme, ili ako ne maris previse za prostor (Mongo je inace vrlo "bahat" sto se prostora na disku tice, barem sa default parametrima, a i ne zaboravimo da po defaultu dodaje svoj _id na svaki record, tako da ako ti je prostor problem - sigurno moze bolje od onoga sto mongo radi po defaultu). Sto se lockovanja tice, mislim da to zavisi od tvog deployment-a. Mongo nije MySQL i sfere u kojima se oni koriste nisu skroz disjunktne, ali se i ne preklapaju u potpunosti. Opisacu ti ukratko kako ga mi koristimo, ali po meni svaki slucaj je drugaciji. Ako mene pitas nakon nekog vremena sam poceo da razmisljam da je Mongo u klasi sa Memecahced-om (samo nabudzen) bre nego sa raznim RDBMS-ovima. Dakle: mi koristimo ReplicaSet opciju gde imamo master u koji se pise (to ne rade web workeri, nego za to koristimo taskove - za queue inace isto koristimo mongo :) ali to je nevezano za celu pricu). Front end web serveri imaju svaki svoj mongo koji replicira mastera, i u te mongo-e se nikad ne pise (osim replikacije naravno ali je ona jako brza) vec samo cita iz njih. Dakle lag replikacije postoji (otud ona rec 'eventual' u frazi 'eventual consistency'), ali je nama nebitan, dakle kao sto rekoh zavisi od aplikacije (mi imamo peakove sa nekoliko stotina upisa, ali realnost je par desetina u sekundi). Sami upisi na mastera su uzasno brzi - ali kad kazem uzasno mislim jako uzasno, hiljade u sekundi, pre ce ti algoritam biti bottleneck nego Mongo. Ovo sve sto sam ti opisao sa ops strane nije trivijalno, ali nije ni nocna mora (Mongo ReplicaSet nije bas jednostavan za koriscenje, srusio nam je sajt 2 puta dok nismo provalili kako bezbolno da dodajemo servere, ali se sve zavrsilo na fabric skripti od par stotina linija koja to sada vrlo bezbolno radi). Sto kazu ono TL;DR: Mongo je okej sistem, ima svoje mracne strane, ali u definitivno vise nego pristojan. Sve zavisi od tvoje aplikacije, ali kad razmisljas o tome gde da ga koristis (a i vecinu nosql resenja), pre razmisljaj: memcached sa vise opcija a slabijim performansama (isto pogledaj i Redis), nego felksibilniji MySQL. PS. Nije bas tako strasno sto zakljucava celu bazu - pogledaj http://www.mongodb.org/display/DOCS/...ncurrency+work ali ako ti je to problem mozda ti treba redizajn :). |
Prostor na disku nije problem, mada bez obzira na to nismo za rasipanje resursima.
Inace Redis ce verovatno biti u stacku posto nam je potreban pub-sub za real-time. Pa su sada varijante, nosql ili Mysql, gde bi one stvari koje su usko grlo, ako je nosql isle manje u Redis (posto pomenuh da je vec skoro izvesno clan stacka i da moze da radi i kao Memcache), ili ako je Mysql onda bi vise stvari imalo neki vid predstavljanja u Redisu. Sustina je da posto ce biti dosta sadrzaja u vidu agregacije da tako kazem, da ubrzamo i sprecimo masivno pisanje JOIN-ova nad x tabela. Trenutno nemamo bazu, pa mi je jedan od ciljeva da sada ako moze identifikujemo stvari kojih se treba paziti ili obratiti vecu paznju ako radimo sa MongoDB-om (slicno sto si pomenuo da ti niko nije rekao da treba verzirati polja). U svakom slucaju, jos jednom ti hvala puno na trudu i vremenu. Imao bih jos par pitanja, ali neka budu ovo za sada. Dosta si mi pomogao i ovako :). |
Meni zvuci super zanimljivo to sto pokusavate (ako sam dobro razumeo). Moj savet - probajte prvo braindead pristup - memcached ispred mysql-a sa lukavo odabranim diskriminatorom... dobre su sanse da ce vas samo to daleko odvesti.
Ja sam uvek protiv komplikovanja ako nije bas nuzno :) |
Slazem se sa tobom. I mi smo za KISS :).
Odatle i npr. odluka da ne koristimo Memcache, kada vec imamo u stacku Redis koji moze da potpuno zameni Memcache funkcionalnost. Problem kesiranja, pub-sub resen - barem na papiru. Sada sama baza - persistence sloj. Nemamo iskustva za Mongom, ali imamo sa par RDBMS. Znamo sta nam je problem u RDBMS-u, ali ne znamo u Mongou. Jeste brzi za stvari koje nam treba (JOIN replacement), jeste donekle parsovanje rezultata na relaciji db-app lakse (strukture objekata vec cuvamo u MongoDB onakve kakve ih "skoro" i koristimo), ali opet nemamo nijedan nosql production projekat, pa imamo nepoznanice. Videcemo... |
Vreme je GMT +2. Trenutno vreme je 10:13. |
Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.