De auteur heeft het Open Internet/Free Speech Fund geselecteerd om een donatie te ontvangen als onderdeel van het Write for DOnations-programma.
Introductie
Monitoring is een essentieel onderdeel van databasebeheer, omdat het u in staat stelt om de prestaties en algemene gezondheid van uw database te begrijpen. Door de prestaties van uw database te monitoren, kunt u een beter inzicht krijgen in de huidige capaciteit, observeren hoe de werkbelasting in de loop van de tijd verandert, en vooruit plannen om de database te schalen zodra deze zijn limieten nadert. Het kan ook helpen om onderliggende hardwareproblemen of abnormaal gedrag, zoals een onverwachte piek in het gebruik van de database, op te merken. Tot slot kan monitoring helpen bij het diagnosticeren van problemen met applicaties die de database gebruiken, zoals applicatiequery’s die bottlenecks veroorzaken.
MongoDB wordt geleverd met een verscheidenheid aan tools en hulpprogramma’s die u kunt gebruiken om de prestaties van uw database te observeren. In deze tutorial leert u hoe u database-metrics on-demand kunt monitoren met behulp van ingebouwde commando’s en tools. U zult ook vertrouwd raken met de database-profiler van MongoDB, die u kan helpen bij het detecteren van slecht geoptimaliseerde query’s.
Vereisten
Om deze tutorial te volgen, heb je het volgende nodig:
- A server with a regular, non-root user with
sudo
privileges and a firewall configured with UFW. This tutorial was validated using a server running Ubuntu 20.04, and you can prepare your server by following this initial server setup tutorial for Ubuntu 20.04. - MongoDB geïnstalleerd op je server. Volg onze tutorial over Hoe MongoDB te installeren op Ubuntu 20.04 om dit in te stellen.
- De MongoDB-instantie op je server beveiligd door verificatie in te schakelen en een beheerdersgebruiker aan te maken. Volg onze tutorial over Hoe MongoDB te beveiligen op Ubuntu 20.04 om MongoDB op deze manier te beveiligen.
- Bekendheid met het queryen van MongoDB-collecties en het filteren van resultaten. Om te leren hoe je MongoDB-query’s kunt gebruiken, volg onze gids over Hoe query’s te maken in MongoDB.
Opmerking: De gelinkte tutorials over het configureren van je server, het installeren van MongoDB en het beveiligen van de MongoDB-installatie verwijzen naar Ubuntu 20.04. Deze tutorial richt zich op MongoDB zelf, niet op het onderliggende besturingssysteem. Het zal over het algemeen werken met elke MongoDB-installatie, ongeacht het besturingssysteem, zolang verificatie is ingeschakeld.
Stap 1 — Voorbereiden van de testgegevens
Om uit te leggen hoe je MongoDB-prestaties kunt monitoren, beschrijft deze stap hoe je de MongoDB-shell opent om verbinding te maken met je lokaal geïnstalleerde MongoDB-instantie en een voorbeeldcollectie daarbinnen aanmaakt.
Om de voorbeeldcollectie te maken die in deze handleiding wordt gebruikt, verbindt u met de MongoDB-shell als uw beheerdersgebruiker. Deze tutorial volgt de conventies van de vereiste MongoDB-beveiligingstutorial en gaat ervan uit dat de naam van deze beheerdersgebruiker AdminSammy is en dat de authenticatiedatabase admin
is. Zorg ervoor dat u deze details in het volgende commando wijzigt om uw eigen configuratie weer te geven, indien anders:
Voer het wachtwoord in dat is ingesteld tijdens de installatie om toegang te krijgen tot de shell. Na het verstrekken van het wachtwoord, ziet u het >
promptteken.
Opmerking: Bij een verse verbinding zal de MongoDB-shell standaard verbinding maken met de database test
. U kunt deze database veilig gebruiken om te experimenteren met MongoDB en de MongoDB-shell.
Als alternatief kunt u overschakelen naar een andere database om alle voorbeeldopdrachten uit deze handleiding uit te voeren. Schakel over naar een andere database door het gebruik
commando uit te voeren, gevolgd door de naam van uw database:
Database monitoring is niet erg praktisch of nuttig bij het werken met een kleine dataset, aangezien het databasesysteem slechts een paar records hoeft te scannen voor een bepaalde query. Om de prestatiebewakingsfuncties van MongoDB te illustreren, heeft u een database nodig met voldoende gegevens zodat MongoDB een aanzienlijke tijd nodig heeft om query’s uit te voeren.
Om dit te bereiken, verwijzen de voorbeelden in deze handleiding naar een voorbeeldverzameling genaamd accounts
met een groot aantal documenten. Elk document vertegenwoordigt een individuele bankrekening met een willekeurig gegenereerd rekeningsaldo. Elk document in de verzameling heeft een structuur zoals deze:
Dit voorbeelddocument bevat de volgende informatie:
number
: Dit veld vertegenwoordigt het rekeningnummer voor de gegeven rekening. In deze verzameling heeft elk rekeningnummer een prefix van1000-
gevolgd door een toenemend numeriek identificatienummer.currency
: Dit veld geeft aan in welke valuta het saldo van elke rekening is opgeslagen. Decurrency
-waarde van elke rekening is ofwelUSD
ofEUR
.balance
: Hier wordt het saldo van elke gegeven bankrekening weergegeven. In deze voorbeelddatabase heeft hetbalance
-veld van elk document een willekeurig gegenereerde waarde.
In plaats van handmatig een groot aantal documenten in te voegen, kunt u de volgende JavaScript-code uitvoeren om tegelijkertijd een verzameling genaamd accounts
te maken en een miljoen van dergelijke documenten erin in te voegen:
Deze code voert een for
-lus uit die één miljoen keer achter elkaar wordt uitgevoerd. Elke keer dat de lus iterateert, wordt de insertOne()
-methode op de accountscollectie uitgevoerd om een nieuw document in te voegen. In elke iteratie geeft de methode een waarde aan het number
-veld dat bestaat uit het 1000-
voorvoegsel met de waarde die wordt vastgehouden in de i
-waarde voor die iteratie. Dit betekent dat de eerste keer dat deze lus iterateert, de waarde van het number
-veld wordt ingesteld op 1000-1
; de laatste keer dat het iterateert, wordt het ingesteld op 1000-1000000
.
De valuta wordt altijd weergegeven als USD
voor rekeningen met nummers hoger dan 500.000 en als EUR
voor rekeningen met lagere nummers dan dat. Het saldo-veld gebruikt de Math.random()
-functie om een willekeurig getal tussen 0 en 1 te genereren, en vermenigvuldigt vervolgens het willekeurige getal met 100.000 om grotere waarden te geven.
Opmerking: Het uitvoeren van deze lus kan lang duren, zelfs meer dan 10 minuten. Het is veilig om de bewerking te laten lopen totdat deze is voltooid.
De uitvoer zal u informeren over het succes en de ObjectId
teruggeven van het laatste ingevoegde document:
Output{
"acknowledged" : true,
"insertedId" : ObjectId("61a38a4beedf737ac8e54e82")
}
U kunt controleren of de documenten correct zijn ingevoegd door de count()
-methode zonder argumenten uit te voeren, die het aantal documenten in de collectie ophaalt:
Output1000000
In deze stap hebt u succesvol de lijst met voorbeelddocumenten gemaakt die als testgegevens zullen dienen in deze handleiding om de tools te verklaren die MongoDB biedt voor prestatiebewaking. In de volgende stap leert u hoe u de basisstatistieken van het servergebruik controleert.
Stap 2 — Controleren van Server Gebruiksstatistieken
MongoDB houdt automatisch een aantal nuttige prestatie statistieken bij, en deze regelmatig controleren is een fundamentele manier om uw database te monitoren. Wees ervan bewust dat deze statistieken geen realtime inzicht bieden in wat er met uw database gebeurt, maar ze kunnen wel nuttig zijn om te bepalen hoe de database presteert en of er eventuele problemen op komst zijn.
Waarschuwing: De MongoDB monitoring commando’s die in deze handleiding worden beschreven, geven potentieel gevoelige informatie over uw database en de prestaties ervan. Daarom vereisen sommige van deze commando’s geavanceerde toestemmingen.
Specifiek vereisen de serverStatus()
methode beschreven in deze stap, evenals de mongostat
en mongotop
commando’s die worden benadrukt in de volgende stap, allemaal dat gebruikers de clusterMonitor
rol hebben gekregen om ze uit te voeren. Op dezelfde manier vereist de setProfilingLevel()
methode beschreven in Stap 4 de dbAdmin
rol.
Als u de vereiste zelfstudie hebt gevolgd over Hoe MongoDB beveiligen op Ubuntu 20.04 en verbonden bent met uw MongoDB-instantie als de beheerder die u hebt aangemaakt in die handleiding, moet u deze aanvullende rollen toekennen om de voorbeelden in deze handleiding te kunnen volgen.
Eerst, schakel over naar de authenticatiedatabase van uw gebruiker. Dit is admin
in het volgende voorbeeld, maar maak verbinding met uw eigen gebruikersauthenticatiedatabase als deze anders is:
Outputswitched to db admin
Vervolgens voert u een grantRolesToUser()
-methode uit en kent u uw gebruiker de rol clusterMonitor
toe samen met de rol dbAdmin
over de database waarin u de collectie accounts
heeft aangemaakt. Het volgende voorbeeld gaat ervan uit dat de collectie accounts
zich in de database test
bevindt:
Houd er rekening mee dat het over het algemeen veiliger is om gebruikersprofielen toe te wijzen aan specifieke doeleinden. Op deze manier zal geen enkele gebruiker onnodig brede privileges hebben. Als u in een productieomgeving werkt, wilt u mogelijk een speciale gebruiker hebben wiens enige doel is om de database te monitoren.
Het volgende voorbeeld maakt een MongoDB-gebruiker met de naam MonitorSammy aan en kent hen de rollen toe die nodig zijn om de voorbeelden in deze tutorial te volgen. Merk op dat het ook de rol readWriteAnyDatabase
bevat, waarmee deze gebruiker gegevens kan lezen en schrijven naar elke database in de cluster:
Nadat u uw gebruiker de juiste rollen heeft toegekend, gaat u terug naar de database waar uw accounts
-collectie is opgeslagen:
Outputswitched to db test
Begin met het controleren van de algemene databasestatistieken door de methode stats()
uit te voeren:
Het argument van deze methode (1024*1024
) is de schaalfactor en vertelt MongoDB om opslaginformatie terug te geven in megabytes. Als u dit weglaat, worden de waarden allemaal gepresenteerd in bytes.
De stats()
methode geeft een beknopte output met enkele belangrijke statistieken met betrekking tot de huidige database:
Output{
"db" : "test",
"collections" : 3,
"views" : 0,
"objects" : 1000017,
"avgObjSize" : 80.8896048767171,
"dataSize" : 77.14365005493164,
"storageSize" : 24.109375,
"indexes" : 4,
"indexSize" : 9.9765625,
"totalSize" : 34.0859375,
"scaleFactor" : 1048576,
"fsUsedSize" : 4238.12109375,
"fsTotalSize" : 24635.703125,
"ok" : 1
}
Deze output biedt een overzicht van de gegevens die deze MongoDB-instantie opslaat. De volgende sleutels die in deze output worden geretourneerd, kunnen bijzonder nuttig zijn:
- De
objects
sleutel toont het totale aantal documenten in de database. U kunt dit gebruiken om de omvang van de database te beoordelen en, wanneer dit in de loop van de tijd wordt waargenomen, de groei ervan. avgObjectSize
toont de gemiddelde grootte van deze documenten, wat inzicht geeft in of de database werkt met grote en complexe documenten of kleine. Deze waarde wordt altijd weergegeven in bytes, ongeacht of u een schaalfactor opgeeft.- De sleutels
collections
enindexes
geven aan hoeveel collecties en indexes er momenteel zijn gedefinieerd in de database. - De sleutel
totalSize
geeft aan hoeveel opslagruimte de database inneemt op de schijf.
Deze informatie die wordt geretourneerd door de stats()
methode kan helpen om een idee te krijgen van hoeveel gegevens momenteel zijn opgeslagen in uw database, maar het geeft geen inzicht in de prestaties of bestaande problemen. Daarvoor is de veel uitgebreidere serverStatus()
methode handig:
De output van deze methode is lang en biedt veel informatie over het gebruik van de server:
Output{
"host" : "ubuntu-mongo-rs",
"version" : "4.4.6",
"process" : "mongod",
"pid" : NumberLong(658997),
"uptime" : 976,
. . .
"ok" : 1
}
Hoewel al deze informatie potentieel nuttig zou kunnen zijn, zal deze handleiding zich met name richten op drie secties. Ten eerste, zoek de connections
sectie van deze output:
Output . . .
"connections" : {
"current" : 4,
"available" : 51196,
"totalCreated" : 4,
"active" : 2,
"exhaustIsMaster" : 1,
"exhaustHello" : 0,
"awaitingTopologyChanges" : 1
},
. . .
Elke databaseserver kan slechts een beperkt aantal verbindingen tegelijk ondersteunen. De huidige
-sleutel toont het aantal momenteel verbonden cliënten met de database, terwijl beschikbaar
het aantal overgebleven ongebruikte verbindingen weergeeft die beschikbaar zijn op de database. De waarde totalCreated
bevat het aantal verbindingen dat vanaf het opstarten van de server is gebruikt.
De meeste toepassingen zijn ontworpen om bestaande verbindingen opnieuw te gebruiken en openen niet vaak meerdere verbindingen. Daarom kan een hoog aantal verbindingen, indien niet voorzien, een verontrustend teken zijn van een verkeerde configuratie van hoe cliënten toegang hebben tot de server.
Als het hoge aantal verbindingen wordt voorzien door het karakter van de uitgevoerde workloads, kunt u overwegen om een of meer shards toe te voegen aan een sharded cluster om het verkeer over meerdere MongoDB-instanties te verdelen.
Vervolgens zoekt u de globalLock
-sectie van de uitvoer. Deze sectie heeft betrekking op globale vergrendelingen over de hele databaseserver:
Output . . .
"globalLock" : {
"totalTime" : NumberLong(975312000),
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 0,
"readers" : 0,
"writers" : 0
}
},
MongoDB gebruikt vergrendelingen om gegevensconsistentie te waarborgen bij het uitvoeren van meerdere bewerkingen, waarbij wordt gegarandeerd dat geen twee query’s dezelfde gegevens tegelijkertijd wijzigen. Op drukbezochte servers bestaat de kans dat vergrendelingen leiden tot knelpunten, waarbij een of meer query’s wachten tot de vergrendelingen zijn vrijgegeven voordat ze kunnen worden uitgevoerd.
De waarde currentQueue.total
toont het aantal query’s dat wacht op het vrijgeven van de vergrendelingen, zodat ze kunnen worden uitgevoerd. Als deze waarde hoog is, betekent dit dat de prestaties van de database worden beïnvloed en dat query’s langer duren om te voltooien.
Dit komt vaak voort uit veel langlopende queries die de vergrendelingen vasthouden en kan een indicatie zijn van een ineffectief gebruik van indexen of slecht ontworpen queries, onder andere mogelijkheden.
Ten slotte, zoek de opcounters
-sectie:
Output "opcounters" : {
"insert" : NumberLong(10000007),
"query" : NumberLong(6),
"update" : NumberLong(6),
"delete" : NumberLong(0),
"getmore" : NumberLong(0),
"command" : NumberLong(1298)
},
Deze sectie van de uitvoer van serverStatus()
kan je een idee geven of de databaseserver voornamelijk wordt gebruikt voor lees- of schrijfoperaties, of dat het gebruik goed in balans is. In dit voorbeeld is na het invoegen van de testdocumenten de teller voor insert
-operaties veel hoger dan die voor query
-operaties. In een realistisch scenario zouden deze waarden waarschijnlijk verschillend zijn.
Databases met veel schrijfoperaties kunnen profiteren van horizontaal schalen via sharding. Op dezelfde manier zullen MongoDB-databases met veel leesbewerkingen meestal profiteren van replicatie.
Deze statistieken kunnen een algemeen idee geven van hoe de server wordt gebruikt en of er prestatieproblemen zijn zoals lange wachtrijen voor vergrendelingen op het moment van toegang. Ze geven echter geen realtime informatie over hoe de server wordt gebruikt. Voor dat doel zijn de opdrachten mongostat
en mongotop
nuttige tools.
Stap 3 — Het verkrijgen van real-time databasestatistieken met behulp van mongostat
en mongotop
Terwijl de commando’s die worden gebruikt om toegang te krijgen tot de serverstatistieken van MongoDB in retrospect inzicht kunnen bieden in hoe de server wordt gebruikt, kunnen ze geen realtime informatie verstrekken over welke collecties op dit moment het meest actief worden gebruikt of wat voor soort queries worden uitgevoerd.
MongoDB biedt twee handige systeemtools voor realtime monitoring die de databaseactiviteit analyseren en continu de informatie vernieuwen die ze verstrekken: mongostat
en mongotop
. mongostat
biedt een beknopt overzicht van de huidige status van de MongoDB-instantie, terwijl mongotop
bijhoudt hoeveel tijd de instantie besteedt aan lees- en schrijfbewerkingen. Beide van deze tools worden uitgevoerd vanaf de opdrachtregel, in plaats van de MongoDB-shell.
Om mongostat
te gebruiken, behoudt u uw huidige MongoDB shell-verbinding en opent u een ander terminalvenster om toegang te krijgen tot uw servershell. In de tweede servershell voert u het mongostat
-commando uit:
Zoals eerder vermeld, vereist mongostat
geavanceerde rechten. Als u authenticatie hebt ingeschakeld op uw MongoDB-instantie en een gebruiker hebt ingesteld met de juiste rollen, moet u zich als die gebruiker authenticeren door hun gebruikersnaam en authenticatiedatabase op te geven (zoals getoond in dit voorbeeld) en vervolgens hun wachtwoord in te voeren wanneer daarom wordt gevraagd.
In een standaardconfiguratie drukt mongostat
de tellers van momenteel uitgevoerde query’s af in intervallen van één seconde:
Outputinsert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn time
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.4k 7 Nov 28 15:40:40.621
*0 *0 *0 *0 0 2|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 224b 84.8k 7 Nov 28 15:40:41.619
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.5k 7 Nov 28 15:40:42.621
*0 *0 *0 *0 0 3|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 365b 85.0k 7 Nov 28 15:40:43.619
Als de uitvoer van mongostat
een waarde van 0
toont voor een bepaald querytype, geeft dit aan dat de database geen bewerkingen van dat type uitvoert. Deze voorbeelduitvoer toont 0
voor elk querytype, wat betekent dat er momenteel geen query’s actief worden uitgevoerd.
U moet nog steeds uw eerste terminalvenster open hebben en verbonden zijn met uw MongoDB-shell. Voeg wat meer testdocumenten toe aan de collectie accounts
en controleer of mongostat
de activiteit zal opmerken:
Dit is een for
-loop vergelijkbaar met degene die u hebt uitgevoerd in Stap 1. Deze keer voegt de lus slechts 10000 items toe. De rekeningnummers zijn voorafgegaan door 2000
, en de valuta is altijd USD.
Terwijl de nieuwe documenten worden ingevoegd, controleert u de uitvoer van mongostat
:
Output. . .
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 112b 42.5k 4 Nov 28 15:50:33.294
*0 *0 *0 *0 0 0|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:34.295
755 *0 *0 *0 0 1|0 0.1% 38.8% 0 1.54G 210M 0|0 1|0 154k 79.4k 4 Nov 28 15:50:35.294
2853 *0 *0 *0 0 0|0 0.4% 39.1% 0 1.54G 211M 0|0 1|0 585k 182k 4 Nov 28 15:50:36.295
2791 *0 *0 *0 0 1|0 0.7% 39.4% 0 1.54G 212M 0|0 1|0 572k 179k 4 Nov 28 15:50:37.293
2849 *0 *0 *0 0 0|0 1.0% 39.7% 0 1.54G 213M 0|0 1|0 584k 182k 4 Nov 28 15:50:38.296
745 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 153k 79.2k 4 Nov 28 15:50:39.294
*0 *0 *0 *0 0 0|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:40.295
*0 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 167b 42.7k 4 Nov 28 15:50:41.293
. . .
Terwijl de query wordt uitgevoerd, beginnen de nieuwe regels die worden geretourneerd door mongostat
waarden te tonen die verschillen van 0
. In de insert
-kolom, die het aantal queries toont dat nieuwe gegevens toevoegt aan de database, waren de waarden enkele seconden hoger. Aangezien mongostat
gegevens toont in intervallen van één seconde, kun je niet alleen de verhouding van inserts ten opzichte van andere soorten databasebewerkingen vinden, maar ook hoe snel de database de nieuwe gegevens invoegt. In dit voorbeeld bereikte de server bijna 3000 inserts per seconde.
Je kunt mongostat
gebruiken om de huidige werklast van de database server te controleren, gegroepeerd op querytypes. De tweede tool die MongoDB levert — mongotop
— toont de activiteit van de database server gegroepeerd per collecties.
Stop mongostat
van het uitvoeren in je tweede terminalvenster door op CTRL + C
te drukken. Voer vervolgens mongotop
uit in dezelfde terminal. Opnieuw, als je authenticatie hebt ingeschakeld, moet je jezelf authenticeren als een gebruiker met de juiste privileges:
mongotop
geeft een lijst van alle collecties in de database weer, vergezeld van de tijd besteed aan lezen, schrijven en in totaal binnen het tijdsvenster. Net als bij mongostat
wordt de output elke seconde ververst:
Output2021-11-28T15:54:42.290+0000 connected to: mongodb://localhost/
ns total read write 2021-11-28T15:54:43Z
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
test.accounts 0ms 0ms 0ms
. . .
Probeer wat meer documenten in de database in te voegen om te zien of de activiteit wordt geregistreerd in mongotop
. Voer in de MongoDB shell de volgende for
-loop uit; observeer daarna het terminalvenster met mongotop
dat wordt uitgevoerd:
Deze keer zal de activiteit zichtbaar zijn in de statistieken van mongotop
:
Output. . .
ns total read write 2021-11-28T15:57:27Z
test.accounts 127ms 0ms 127ms
admin.$cmd.aggregate 0ms 0ms 0ms
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
ns total read write 2021-11-28T15:57:28Z
test.accounts 130ms 0ms 130ms
admin.$cmd.aggregate 0ms 0ms 0ms
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
. . .
Hier laat mongotop
zien dat alle database-activiteit plaatsvond in de accounts
-collectie in de test
-database en dat alle bewerkingen in het tijdsvenster schrijfbewerkingen zijn geweest. Dit zou allemaal moeten overeenkomen met de for
-lusbewerking die je hebt uitgevoerd.
Net als bij mongostat
kun je mongotop
stoppen met uitvoeren door op CTRL + C
te drukken.
Wanneer geobserveerd tijdens piekbelasting, kun je mongotop
gebruiken om te controleren hoe de database-activiteit zich verspreidt over verschillende collecties om je een beter inzicht te geven in je schema en om te plannen voor schaalvergroting. Het biedt ook inzicht in of het gebruik van een collectie meer lees- of schrijfintensief is.
Stap 4 — Het gebruik van MongoDB’s Database Profiler om Trage Queries te Identificeren
Database-prestatieknelpunten kunnen uit verschillende bronnen komen. Hoewel het schalen van de database (horizontaal of verticaal) vaak de oplossing is voor prestatieknelpunten, kan de oorzaak ervan eigenlijk niet de grenzen van de database zijn, maar problemen met het schema of de query-ontwerp.
Als queries te lang duren, kan de oorzaak een ineffectief gebruik van indexen zijn of fouten in de query zelf. Langlopende queries vallen vaak buiten de radar tijdens de ontwikkeling van toepassingen, meestal omdat de testdatasets te klein zijn of de omstandigheden verschillen van die in productie.
Je zou potentieel de schuldige kunnen vinden door handmatig testqueries uit te voeren en te controleren welke onderpresteren, hoewel dit erg vervelend zou zijn. Gelukkig kan de database-profiler tool van MongoDB dat automatisch doen.
De database-profiler van MongoDB kan queries loggen en statistieken bijhouden over hun uitvoering wanneer ze aan bepaalde voorwaarden voldoen. De belangrijkste van deze voorwaarden is de uitvoeringstijd van de query: als een query langer duurt dan een bepaalde tijd om uit te voeren, zal de profiler die query automatisch markeren als problematisch. Met behulp van de profiler kunt u identificeren welke queries slecht presteren en u vervolgens richten op het oplossen van die specifieke problemen.
Voordat u de profiler gebruikt, voert u de volgende query uit. Deze query zal een van de accounts ophalen die u hebt ingevoegd, hoewel het niet zo eenvoudig is als het op het eerste gezicht lijkt:
De opdracht zal het exacte account ophalen dat u hebt opgevraagd:
Output{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }
U hebt misschien gemerkt dat de query niet onmiddellijk werd uitgevoerd en dat het MongoDB een moment of twee kostte om het account te vinden. In een real-world toepassing kunnen er veel soorten queries zijn die slecht presteren, en u zou hun onderprestaties mogelijk niet opmerken in de praktijk.
U kunt MongoDB configureren om u te helpen vaststellen welke queries langer duren dan verwacht. Om dit te doen, schakelt u eerst de profiler in door de volgende opdracht uit te voeren:
De methode setProfilingLevel()
neemt twee argumenten. Het eerste is het profilingniveau, dat kan zijn 0
, 1
of 2
:
0
schakelt de profiler uit1
schakelt de profiler in alleen voor langzame queries die aan de voorwaarde voldoen2
activeert de profiler voor alle queries
In dit voorbeeld zal de profiler queries analyseren die langer dan 100 milliseconden duren, zoals gedefinieerd door het tweede argument, { slowms: 100 }
.
Opmerking: Het gebruik van de profiler vermindert de prestaties, omdat MongoDB nu queries moet analyseren naast het uitvoeren ervan. Het moet spaarzaam worden gebruikt bij het monitoren van prestatieknelpunten.
Het is mogelijk om de subset van queries die de profiler zal loggen verder aan te passen door deze te configureren om slechts een bepaald percentage queries te profileren of te filteren op querytype. Voor meer informatie over hoe u meer controle kunt hebben over de profiler, raadpleegt u de officiële documentatie over het onderwerp.
Deze methode zal een succesbericht teruggeven:
Output{ "was" : 0, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }
Vanaf nu zal de database-profilering zijn ingeschakeld en zal MongoDB actief elke query monitoren die u uitvoert om te kijken of deze langer dan 100 milliseconden duurt om te voltooien.
Probeer dit uit door een paar verschillende queries uit te voeren. Gebruik eerst het count
-commando om het aantal documenten in de accounts
-collectie te vinden:
Dit commando zal snel het aantal documenten in de collectie retourneren:
Output1020000
Probeer vervolgens de eerste drie bankrekeningen in de collectie op te zoeken:
Opnieuw zal de database snel de resultaten retourneren:
Output{ "_id" : ObjectId("61ef40640f2ba52efc56ee17"), "number" : "1000-1", "currency" : "EUR", "balance" : 25393.132960293842 }
{ "_id" : ObjectId("61ef40640f2ba52efc56ee18"), "number" : "1000-2", "currency" : "EUR", "balance" : 63629.42056192393 }
{ "_id" : ObjectId("61ef40640f2ba52efc56ee19"), "number" : "1000-3", "currency" : "EUR", "balance" : 75602.12331602155 }
Voer tot slot de zoekopdracht voor de specifieke bankrekening opnieuw uit:
Deze query zal het resultaat opleveren, maar, zoals eerder, zal het een momentje langer duren dan de vorige bewerkingen:
Output{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }
De profiler produceert zelf geen output, ook al was de query zichtbaar langzamer. In plaats daarvan worden de details over langzame bewerkingen geregistreerd in een speciale collectie binnen de database genaamd system.profile
. Deze collectie is een capped collectie die nooit groter wordt dan 1 MB in omvang. Dat betekent dat het altijd een lijst zal bevatten van alleen de meest recente langzame queries.
Om informatie op te halen over queries die door de profiler zijn geïdentificeerd, moet je de system.profile
collectie opvragen op een manier als deze:
Deze query gebruikt de find()
methode, zoals gebruikelijk. Het bevat ook een sort
clausule die { "ts" : -1 }
als argument bevat. Hiermee wordt de resultaatset gesorteerd met de nieuwste queries eerst. Ten slotte zal de pretty()
methode aan het einde de output weergeven in een meer leesbaar formaat.
Elke langzame query wordt weergegeven als een gewoon document, en system.profile
is net als elke andere reguliere collectie. Dit betekent dat je de resultaten kunt filteren, sorteren en zelfs kunt gebruiken in aggregatiepijplijnen om de lijst met door de profiler geïdentificeerde queries verder te beperken of te analyseren.
Merk op dat het resultaat slechts uit één document bestaat. De andere twee queries werden snel genoeg uitgevoerd om de profiler niet te activeren:
Output{
"op" : "query",
"ns" : "test.accounts",
"command" : {
"find" : "accounts",
"filter" : {
"number" : "1000-20"
},
. . .
},
"nreturned" : 1,
"keysExamined" : 0,
"docsExamined" : 1030000,
. . .
"millis" : 434,
"planSummary" : "COLLSCAN",
. . .
}
Deze output biedt een aantal details over de uitvoering van de langzame query:
- De
op
-sleutel toont wat voor soort operatie deze informatie vertegenwoordigt. Hier is het eenquery
, aangezien het een operatie vertegenwoordigt waarbij je defind()
hebt gebruikt om gegevens uit de database op te halen. - De
ns
-sleutel geeft aan welke database en collectie betrokken waren bij de operatie. Zoals de uitvoer laat zien, heeft deze operatie deaccounts
-collectie in detest
-database bevraagd. - De
command
-sleutel geeft verdere informatie over de query zelf. In dit geval bevat defilter
-sub-sleutel het volledige filterdocument. Met de informatie uit deop
– encommand
-velden kunt u de betreffende query reconstrueren. - In het veld
millis
vindt u de exacte tijd die nodig was om de query uit te voeren. In dit voorbeeld bijna een halve seconde. - Het veld
docsExamined
geeft het aantal gescande documenten weer om de resultaatset te retourneren. nreturned
vertegenwoordigt het aantal documenten dat de query heeft geretourneerd. In dit voorbeeld werd slechts één document geretourneerd uit meer dan een miljoen gescande documenten.- De
planSummary
toont de methode die MongoDB heeft gebruikt om de query uit te voeren.COLLSCAN
komt overeen met een volledige collectiescan, wat betekent dat elk document in de collectie één voor één is doorzocht om de overeenkomende bankrekening te vinden.
Allemaal samen benadrukt deze informatie de noodzaak van een index die MongoDB zou kunnen helpen bij het sneller uitvoeren van deze query. De database moest de hele collectie doorzoeken om een enkel document te vinden, zoals aangegeven door het grote verschil tussen het aantal onderzochte en geretourneerde documenten, evenals de uitvoeringsstrategie.
In dit specifieke voorbeeld zou het maken van een index om queries te ondersteunen die gegevens filteren op basis van het nummer
-veld direct een boost geven aan de prestaties van dit soort queries. In echte scenario’s kunnen de oplossingen voor langzame queries verschillen en afhangen van de exacte query die problemen veroorzaakt.
Om de profileringssessie af te ronden, kunt u de profiler uitschakelen door het profielniveau op nul in te stellen:
De operatie zal slagen met een bevestigingsbericht:
Output{ "was" : 1, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }
Nu keert de database terug naar normale werking zonder dat er achter de schermen profilering plaatsvindt.
Telkens wanneer u vermoedt dat langzame queries een negatieve invloed kunnen hebben op de prestaties van uw database, kunt u de database-profiler gebruiken om ze te vinden en hun structuur en uitvoering beter te begrijpen. Met deze informatie bent u beter in staat om ze aan te passen en hun prestaties te verbeteren.
Conclusie
Door deze handleiding te volgen, heb je geleerd hoe je de serverstatistieken van MongoDB kunt vinden en hoe je diagnostische tools zoals mongotop
, mongostat
kunt gebruiken, evenals het mechanisme voor databaseprofilering van MongoDB. Je kunt deze gebruiken om een beter inzicht te krijgen in de werklast van je database, te bepalen welke collecties het meest actief zijn en of de server voornamelijk schrijf- of leesbewerkingen uitvoert. Je kunt ook langzame query’s identificeren die de prestaties van MongoDB beïnvloeden om ze te vervangen door efficiëntere query’s.
Dit zijn slechts een selectie van tools en technieken die je kunt gebruiken om de gezondheid en prestaties van je MongoDB-installatie te monitoren en erop te reageren. Elk van deze tools kan verder worden geconfigureerd en aangepast om je meer gerichte inzichten te bieden in de serverprestaties. We moedigen je aan om de officiële MongoDB-documentatie te bestuderen om meer te leren over technieken die je kunt gebruiken om serverprestaties te monitoren en erop te reageren.
Source:
https://www.digitalocean.com/community/tutorials/how-to-monitor-mongodb-s-performance