sql >> Databáze >  >> NoSQL >> MongoDB

Řešení pomalých dotazů v MongoDB

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.

  1. Použití Profileru
  2. 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:

  1. Nepoužíváte indexování s kolekcí
  2. 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í.


  1. Mongoose findOneAndUpdate a upsert nevrací žádné chyby, žádné ovlivněné dokumenty

  2. Jak streamovat výsledky dotazů MongoDB s nodejs?

  3. Kombinace operátorů $regex a $or v Mongo

  4. redis-cli přesměrován na 127.0.0.1