Database løsning til store mængder af data

Tags:    postgresql mysql mongodb

User
Malte @ 30.01.18 19:47
Hej Udviklere,

Jeg står overfor et IoT projekt hvor store mængder data skal opsamles og lageres på en fornuftig måde.
Der er tale om ca. 255 Float værdier og 512 Dint værdier en gang i sekundet, svarende til omkring ??86.400? nye ?rows om dagen.
Indtil nu har jeg benyttet MySQL da jeg har erfaring med denne database men må efterhånden erkende at det ikke holder i længden med den mængde data.

Pt. er dataen lageret på følgende måde i MySQL:
Fold kodeboks ind/udC kode 


Problemt opstår pt. hvis jeg fx skal lave en graf for 5 værdier for de seneste 7 dage skal 604.800 rows håndteres og dette kræver både mange ressourcer for serveren samt ventetid for clienten i browseren.

Mit spørgsmål er hvordan gør man dette smartest, findes der en bedre måde at gøre dette på?

Jeg har kigget lidt på noget NoSQL (mongdb) men også på PosgreSQL men er ikke sikker på hvilken løsning der er bedst egnet til mit formål.

I fremtiden ønsker jeg iøvrigt at samle data fra mange (flere hundrede steder) i en samlet cloud database.

På forhånd tak for hjælpen :)



Indlæg senest redigeret d. 31.01.2018 17:58 af Malte
8 svar postet i denne tråd vises herunder
3 indlæg har modtaget i alt 8 karma
Sorter efter stemmer Sorter efter dato
Umiddelbart ville jeg netop anbefale PostgreSQL eller MongoDB som du selv fremhæver. MySQL er ganske udemærket i situationer hvor store mængder af data skal læses, men når det kommer til både read/write så er PostgreSQL et bedre valg, hvilket lader til at være dit tilfælde. Og selvfølgelig er MongoDB også et godt valg i dette tilfælde, hvis du ikke har et reelt behov for at opbevare data relationelt.

Din hosting spiller også ind her. Hvad bruger du nu? Egen server eller cloud hosting? Jeg ville klart vælge en elastisk hosted cloud løsning i dit tilfælde, så du nemt kan skalere efter behov.



Måden at undgå ventetid på at behandle 604.800 rækker, hver med 255 floats og 512 Dint (hvad end det er), hvilket sammenlagt er mindst 1 GB af data - vel og mærke hver gang du henter den data - hvilket du er nød til ofte hvis du viser grafen flydende langs dagen - er simpelthen ikke at gøre det.

Du vil vise en graf over de sidste 7 dage over tid, hvilket er 604800 rækker og dermed "X-koordinater". Men har dine brugere en skærm med 604800 pixels i bredden? Og giver det overhovedet mening at vise et menneske så mange datapunkter. Nej vel.

Lad os for diskussionens skyld sige du kan nøjes med "X-punkt" hver 15min over 7 dage. Det giver stadig 672 X-punkter på din graf. Så det du kan gøre i stedet er at at med dit 'rådata', at bygge et andet mere groft datasæt som aggregerer dit rådata til større klodser. Lad os sige du også har et 1-dags graf du vil lave, så kan det være at 15 min intervaller er for store, så i stedet kan du bygge dit aggregat med 5 min intervaller i stedet. Den kan bruges til begge grafer, (du kan samle 3x5min til 15min for 7-dags grafen). Disse klodser skal kun laves (skrives engang) og der er 300 gange mindre data at behandle ved læsninger.



Indlæg senest redigeret d. 05.02.2018 17:33 af Søren Enevoldsen
User
Jacob bang @ 01.02.18 14:36
Synes det lyder meget underligt det du har gang i men det kan være det hjælper på forståelsen hvis du besvarer følgende spørgsmål:

Har du noget index på Timestamp kolonnen?

Hvorfor har du klumpet alle data sammen i en "Data" kolonnen frem for at splittet dine float og dint værdier op i kolonner således du kan select specifikt dem du har brug for?



User
Malte @ 05.02.18 16:52
Synes det lyder meget underligt det du har gang i men det kan være det hjælper på forståelsen hvis du besvarer følgende spørgsmål:

Har du noget index på Timestamp kolonnen?

Hvorfor har du klumpet alle data sammen i en "Data" kolonnen frem for at splittet dine float og dint værdier op i kolonner således du kan select specifikt dem du har brug for?


Ja der er naturligvis index på timestamp kolonnen.
Feltet data benyttes til at gemme i JSON format da antallet af float og dint værdier kan variere fra hhv. 0-512 DINT og 0-255 FLOAT på den måde kan jeg minimere mængden af plads hvert row optager hvis ikke benytter alle 512/255 værdier.


Umiddelbart ville jeg netop anbefale PostgreSQL eller MongoDB som du selv fremhæver. MySQL er ganske udemærket i situationer hvor store mængder af data skal læses, men når det kommer til både read/write så er PostgreSQL et bedre valg, hvilket lader til at være dit tilfælde. Og selvfølgelig er MongoDB også et godt valg i dette tilfælde, hvis du ikke har et reelt behov for at opbevare data relationelt.

Din hosting spiller også ind her. Hvad bruger du nu? Egen server eller cloud hosting? Jeg ville klart vælge en elastisk hosted cloud løsning i dit tilfælde, så du nemt kan skalere efter behov.


Hej Kristian, Tak for dit svar.
Jeg har forsøgt mig lidt med PostgreSQL men jeg er ikke helt tilfreds med læse hastigheden når jeg fx skal hente data for fx. 7 dags data og tenge en graf med canvasjs.com har du nogle bud på hvordan hastigheden eventuelt kan optimeres?



Indlæg senest redigeret d. 05.02.2018 16:56 af Malte
User
Malte @ 05.02.18 19:42
Måden at undgå ventetid på at behandle 604.800 rækker, hver med 255 floats og 512 Dint (hvad end det er), hvilket sammenlagt er mindst 1 GB af data - vel og mærke hver gang du henter den data - hvilket du er nød til ofte hvis du viser grafen flydende langs dagen - er simpelthen ikke at gøre det.

Du vil vise en graf over de sidste 7 dage over tid, hvilket er 604800 rækker og dermed "X-koordinater". Men har dine brugere en skærm med 604800 pixels i bredden? Og giver det overhovedet mening at vise et menneske så mange datapunkter. Nej vel.

Lad os for diskussionens skyld sige du kan nøjes med "X-punkt" hver 15min over 7 dage. Det giver stadig 672 X-punkter på din graf. Så det du kan gøre i stedet er at at med dit 'rådata', at bygge et andet mere groft datasæt som aggregerer dit rådata til større klodser. Lad os sige du også har et 1-dags graf du vil lave, så kan det være at 15 min intervaller er for store, så i stedet kan du bygge dit aggregat med 5 min intervaller i stedet. Den kan bruges til begge grafer, (du kan samle 3x5min til 15min for 7-dags grafen). Disse klodser skal kun laves (skrives engang) og der er 300 gange mindre data at behandle ved læsninger.


Hej Søren, tak for dit svar! Det giver tildels mening og er også noget ligenden den løsning jeg har tænkt på kan løse problemet da 1GB data i json format simpehen virker hovedløst at servere til en bruger. Kunne man eventuelt forstille sig at man havde en SQL query som hentet et row hvert 15min for en tidsperiode på 7 dage istedet for at kører to paralle dataset?
På forhånd tak for din hjælp :)!



Hvis jeg forstår dig ret så afhænger det af dit data. Hvis det ikke svinger meget mellem de 15 min så kan du nok godt. Hvis du kan lave en query der kun udtager punkter med 15 min intervaller reducerer du data og beregning med en stor faktor (vel en faktor 900).

Ser dog måske det problem at dataen ligger jo stadig på en HDD/SSD. Pga. du læser regulære intervaller kan det være I/O stadig tager tid fordi databasen skal læse så spredt på disken. Så her tror jeg stadig en anden mere "kompakt" tabel vil køre bedre. Men hvis du kan formulere en query der gør ovenstående er det jo hurtigt at teste.



Hmm, hvis du har et stort behov for hastighed ved læsning skal du måske kigge på noget dimensionelt database design, og bruge en tilhørende ETL process til at populere din database. Det kommer an på hvordan forholdet mellem dit skrive og læse behov er. Dit eksempel med at lave en graf over de sidste 7 dage ville virke fint i dette tilfælde, såfremt data fra idag ikke behøver være en del af det. Det ville tillade dig at køre en natlig ETL process der opdaterer dine data marts med ny data. PostgreSQL håndterer OLAP og OLTP bedre end MySQL, så måske dette kunne være vejen fremad_ Igen, det kommer an på om natlig opdatering af data der kan læses er frekvent nok.

Hvis ikke ville jeg anbefale at tænke mere over i NoSQL/MongoDB. Husk dog på at Mongo kun er ACID compliant indenfor de enkelte dokumenter, men ikke på tværs af flere dokumenter. Det kan have betydning for det design du vælger.



Havde lige lidt tid til at lege med det. Denne hurtige fiddle viser principielt hvordan den grove tabel kan blive lavet fra rådata.

http://sqlfiddle.com/#!17/5a5f0/10



t