sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB forudindlæs dokumenter i RAM for bedre ydeevne

Dit observerede ydeevneproblem ved en indledende forespørgsel er sandsynligvis et af følgende problemer (i nogenlunde sandsynlighedsrækkefølge):

1) Din applikation/webservice har nogle overhead, der skal initialiseres ved første anmodning (dvs. allokering af hukommelse, opsætning af forbindelsespuljer, løsning af DNS, ...).

2) Indekser eller data, du har anmodet om, er endnu ikke i hukommelsen, så de skal indlæses.

3) Query Optimizer kan tage lidt længere tid at køre på den første anmodning, da den sammenligner planudførelsen for dit forespørgselsmønster.

Det ville være meget nyttigt at teste forespørgslen via mongo shell, og isoler, om overheaden er relateret til MongoDB eller din webservice (i stedet for at time begge dele, som du har gjort).

Følgende er nogle bemærkninger relateret til MongoDB.

Caching

MongoDB har ikke en "caching"-tid for dokumenter i hukommelsen. Den bruger hukommelseskortede filer til disk I/O, og dokumenterne i hukommelsen er baseret på dine aktive forespørgsler (dokumenter/indekser, du for nylig har indlæst) samt den tilgængelige hukommelse. Operativsystemets virtuelle hukommelsesmanager er ansvarlig for caching , og vil typisk følge en LRU-algoritme (Last-Recently Used) for at bestemme, hvilke sider der skal skiftes ud af hukommelsen.

Hukommelsesbrug

Den forventede adfærd er, at MongoDB over tid vil vokse til at bruge al ledig hukommelse til at gemme dit aktive arbejdsdatasæt.

Ser på din angivne db.stats() tal (og forudsat at det er dit eneste). database), ser det ud til, at din databasestørrelse er aktuel omkring 1 Gb, så du burde være i stand til at holde alt inden for din 10 Gb samlede RAM, medmindre:

  • der er andre processer, der konkurrerer om hukommelsen
  • du har genstartet din mongod server, og disse dokumenter/indekser er ikke blevet anmodet om endnu

I MongoDB 2.2 er der en ny touch kommando, du kan bruge til at indlæse indekser eller dokumenter i hukommelsen efter en servergenstart. Dette bør kun bruges ved første opstart til at "varme" serveren op, da du ellers ubehjælpsomt kan tvinge faktiske "aktive" data ud af hukommelsen.

På et linux-system kan du for eksempel bruge top kommando og skulle se at:

  • virtuelle bytes/VSIZE vil have en tendens til at være på størrelse med hele databasen
  • hvis serveren ikke har andre processer kørende, vil residente bytes/RSIZE være maskinens samlede hukommelse (dette inkluderer filsystemets cacheindhold)
  • mongod bør ikke bruge swap (da filerne er hukommelseskortet)

Du kan bruge mongostat værktøj til at få et hurtigt overblik over din mongod aktivitet .. eller mere nyttigt, brug en tjeneste som MMS at overvåge metrics over tid.

Forespørgselsoptimering

MongoDB Query Optimizer sammenligner planudførelse for et forespørgselsmønster for hver ~1.000 skriveoperationer og cacher derefter den "vindende" forespørgselsplan, indtil næste gang optimeringsværktøjet kører .. eller du kalder eksplicit en explain() på den forespørgsel.

Dette burde være ligetil at teste:kør din forespørgsel i mongo skal med .explain() og se på ms-timingerne og også antallet af indeksposter og scannede dokumenter. Timingen for en explain() er ikke den faktiske tid, det vil tage forespørgslerne at køre, da det inkluderer omkostningerne ved at sammenligne planerne. Den typiske udførelse vil være meget hurtigere .. og du kan se efter langsomme forespørgsler i din mongod log.

Som standard vil MongoDB logge alle forespørgsler langsommere end 100ms, så dette giver et godt udgangspunkt for at lede efter forespørgsler, der skal optimeres. Du kan justere den langsomme ms-værdi med --slowms config-indstilling, eller brug Database Profiler kommandoer.

Yderligere læsning i MongoDB-dokumentationen:




  1. Sådan skubbes flere til indlejret array

  2. MongoDB Aggregation Framework Stadier og Pipelining

  3. hvordan man fjerner array med værdien null efter unset i mongodb

  4. Mongodb tæller adskilt med flere gruppefelter