V produkci by aplikace měla poskytnout uživateli včasnou odpověď za účelem zlepšení interakce uživatele s vaší aplikací. Občas se však databázové dotazy mohou začít zpožďovat, a proto trvá delší latence, než se odpověď dostane k uživateli, nebo spíše operace propustnosti ukončena kvůli překročení nastavené průměrné časové prodlevy.
V tomto blogu se dozvíme, jak můžete identifikovat tyto problémy v MongoDB, způsoby, jak je opravit, kdykoli nastanou, a jaké jsou možné strategie, které lze podniknout, aby se to již neopakovalo.
P>Častěji vede k pomalým odpovědím na dotazy snížená kapacita procesoru, která není schopna odolat základní pracovní sadě. Pracovní množina je v tomto případě množství dat a indexů, které budou podrobeny instanci propustnosti, tedy aktivní v daném okamžiku. To je zvláště zohledněno při plánování kapacity, když se očekává, že množství příslušných dat se v průběhu času zvýší a počet uživatelů zapojených do vaší platformy.
Identifikace problému s pomalým dotazem
Existují dva způsoby, jak identifikovat pomalé dotazy v MongoDB.
- Použití Profileru
- Použití pomocníka db.currentOp()
Použití MongoDB Profiler
Profiler databáze v MongoDB je mechanismus pro shromažďování podrobných informací o příkazech databáze prováděných proti běžící instanci mongoda, což jsou:operace propustnosti (Create, Read, Update a Delete) a příkazy pro konfiguraci a správu.
Profiler využívá omezenou kolekci s názvem system.profile, kam zapisuje všechna data. To znamená, že když je kolekce plná, pokud jde o velikost, jsou starší dokumenty smazány, aby se vytvořil prostor pro nová data.
Profiler je ve výchozím nastavení vypnutý, ale v závislosti na úrovni profilování jej lze povolit pro jednotlivé databáze nebo instance. Možné úrovně profilování jsou:
- 0 – profilovač je vypnutý, proto neshromažďuje žádná data.
- 1 – profiler shromažďuje data pro operace, které trvají déle, než je hodnota zpomalení
- 2- Profiler shromažďuje data pro všechny operace.
Povolení profilování však generuje dopad na výkon databáze a využití disku, zejména pokud je úroveň profilování nastavena na 2 . Než povolíte a nakonfigurujete profiler v produkčním nasazení, měli byste zvážit jakékoli dopady na výkon.
K nastavení profilování používáme pomocníka db.setProfilingLevel(), např.:
db.setProfilingLevel(2)
Ukázkový dokument, který bude uložen v kolekci system.profile, bude:
{ "was" : 0, "slowms" : 100, "sampleRate" : 1.0, "ok" : 1 }
Pár klíč–hodnota „ok“:1 označuje, že operace byla úspěšná, zatímco slowms je prahová doba v milisekundách, kterou by operace měla trvat, a ve výchozím nastavení je 100 ms.
Změnu této hodnoty
db.setProfilingLevel(1, { slowms: 50 })
Chcete-li se dotázat na data pro kolekci system.profile, spusťte:
db.system.profile.find().pretty()
Použití db.currentOp()helper
Tato funkce uvádí aktuálně spuštěné dotazy s velmi podrobnými informacemi, jako je doba, po kterou byly spuštěny. Na běžícím mongo shellu spustíte komentář například:
db.currentOp({“secs_running”:{$gte:5}})
Kde secs_running je strategie filtrování, takže budou vráceny pouze operace, jejichž provedení trvalo déle než 5 sekund, čímž se sníží výstup. To se často používá, když lze stav CPU ohodnotit na 100 % kvůli nepříznivému dopadu na výkon, který může mít na databázi. Změnou hodnot se tedy dozvíte, které dotazy se vykonávají dlouho.
Vrácené dokumenty mají jako klíčové klíče následující:
- dotaz :co dotaz obnáší
- aktivní : pokud dotaz stále probíhá.
- ns :název kolekce, proti které má být dotaz proveden
- secs_running : doba trvání dotazu v sekundách
Zvýrazněním toho, které dotazy trvají dlouho, jste identifikovali, co přetěžuje CPU.
Interpretace výsledků a řešení problémů
Jak jsme popsali výše, latence dotazu velmi závisí na množství příslušných dat, což jinak povede k neefektivním plánům provádění. To znamená, že pokud například ve své kolekci nepoužíváte indexy a chcete aktualizovat určité záznamy, operace musí projít všechny dokumenty a nefiltrovat pouze ty, které odpovídají specifikaci dotazu. Logicky to bude trvat déle, což povede k pomalému dotazu. Neefektivní plán provádění můžete prozkoumat spuštěním příkazu: plain(‘executionStats’), který poskytuje statistiky o výkonu dotazu. Od tohoto bodu se můžete naučit, jak dotaz využívá index, kromě toho, že poskytnete vodítko, zda je index optimální.
Pokud se pomocník pro vysvětlení vrátí
{
"queryPlanner" : {
"plannerVersion" : 1,
...
"winningPlan" : {
"stage" : "COLLSCAN",
...
}
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 3,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 10,
"executionStages" : {
"stage" : "COLLSCAN",
...
},
...
},
...
}
queryPlanner.winningPlan.stage:Hodnota klíče COLLSCAN označuje, že mongod musel naskenovat celý sbírkový dokument, aby identifikoval výsledky, a proto se to stává nákladnou operací, která vede k pomalým dotazům.
executionStats.totalKeysExamined:0 znamená, že kolekce nevyužívá strategii indexování
U daného dotazu by se měl počet zahrnutých dokumentů blížit nule. Pokud je počet dokumentů poměrně velký, existují dvě možnosti:
- Nepoužíváte indexování s kolekcí
- Použití indexu, který není optimální.
Chcete-li vytvořit index pro kolekci, spusťte příkaz:
db.collection.createIndex( { quantity: 1 } )
Kde množství je příklad pole, které jste vybrali jako optimální pro strategii indexování.
Pokud se chcete dozvědět více o indexování a jaké strategii indexování použít, podívejte se na tento blog
Závěr
Snížení výkonu databáze lze snadno vykreslit pomalými dotazy, což je to nejmenší, co bychom od uživatelů platformy očekávali. Pomalé dotazy v MongoDB lze identifikovat povolením profileru a jeho konfigurací podle jeho specifikací nebo spuštěním db.currentOp() na běžící instanci mongoda.
Podíváme-li se na časové parametry vráceného výsledku, můžeme určit, které dotazy se zpožďují. Po identifikaci těchto dotazů použijeme u těchto dotazů pomocníka pro vysvětlení, abychom získali další podrobnosti, například pokud dotaz používá jakýkoli index.
Bez indexování se operace prodraží, protože před aplikací změn je třeba naskenovat mnoho dokumentů. S tímto poklesem bude CPU přetížen, což bude mít za následek pomalé dotazování a rostoucí špičky CPU.
Hlavní chybou, která vede k pomalým dotazům, je neefektivní plánování provádění, které lze snadno vyřešit použitím indexu s příslušnou kolekcí.