sql >> Databasteknik >  >> NoSQL >> MongoDB

WiredTiger och uppdateringar på plats

Med MMAPv1-lagringsmotorn framhävs ofta uppdateringar på plats som en optimeringsstrategi eftersom index för ett dokument pekar direkt till filplatser och förskjutningar. Att flytta ett dokument till en ny lagringsplats (särskilt om det finns många indexposter att uppdatera) har mer omkostnader för MMAPv1 än en uppdatering på plats som bara behöver uppdatera de ändrade fälten. Se:Record Storage Characteristics i MMAPv1.

WiredTiger stöder inte uppdateringar på plats eftersom den internt använder MVCC (Multiversion concurrency control), som vanligtvis används av databashanteringssystem. Detta är en betydande teknisk förbättring jämfört med den förenklade vyn i MMAP, och gör det möjligt att bygga mer avancerade funktioner som isoleringsnivåer och transaktioner. WiredTigers index har en nivå av inriktning (refererar till ett internt RecordID istället för filens plats och offset), så dokumentflyttningar på lagringsnivå är inte en betydande smärtpunkt.

Men den här artikeln säger också att "Även om [WiredTiger] inte tillåter uppdateringar på plats, kan den fortfarande prestera bättre än MMAP för många arbetsbelastningar".

Det betyder att även om MMAPv1 kan ha en mer effektiv väg för uppdateringar på plats, har WiredTiger andra fördelar som komprimering och förbättrad samtidighetskontroll. Du kan kanske konstruera en arbetsbelastning som endast består av uppdateringar på plats av ett fåtal dokument som kan fungera bättre i MMAPv1, men faktiska arbetsbelastningar är vanligtvis mer varierande. Det enda sättet att bekräfta effekten för en given arbetsbelastning skulle vara att testa i en representativ miljö.

Det allmänna valet av MMAPv1 vs WiredTiger är dock omöjligt om du vill planera för framtiden:WiredTiger har varit standardlagringsmotorn sedan MongoDB 3.2 och vissa nyare produktfunktioner stöds inte av MMAPv1. Till exempel stöder MMAPv1 inte Majority Read Concern vilket i sin tur innebär att det inte kan användas för Replica Set Config Servers (krävs för sharding i MongoDB 3.4+) eller Change Streams (MongoDB 3.6+). MMAPv1 kommer att fasas ut i nästa stora version av MongoDB (4.0) och är för närvarande planerad att tas bort i MongoDB 4.2.

Vilka är de exakta konsekvenserna som jag måste vara medveten om när jag använder WiredTiger? Till exempel, utan uppdateringar på plats kommer databasens storlek att växa snabbt?

Lagringsresultat beror på flera faktorer inklusive din schemadesign, arbetsbelastning, konfiguration och version av MongoDB-servern. MMAPv1 och WiredTiger använder olika strategier för postallokering, men båda kommer att försöka använda förallokerat utrymme som är markerat som ledigt/återanvändbart. Generellt sett är WiredTiger mer effektiv med användning av lagringsutrymme, och den har också fördelen av komprimering för data och index. MMAPv1 allokerar ytterligare lagringsutrymme för att försöka optimera för uppdateringar på plats och undvika dokumentflyttningar, även om du kan välja en "ingen utfyllnad"-strategi för samlingar där arbetsbelastningen inte ändrar dokumentstorleken över tid.

Det har gjorts betydande investeringar i att förbättra och ställa in WiredTiger för olika arbetsbelastningar sedan den först introducerades i MongoDB 3.0, så jag skulle starkt uppmuntra testning med den senaste produktionsversionen för bästa resultat. Om du har en specifik fråga om schemadesign och lagringstillväxt, skulle jag föreslå att du lägger ut detaljer på DBA StackExchange för diskussion.

Jag fick också veta att WiredTiger i MongoDB 3.6 lade till möjligheten att lagra deltan istället för att skriva om hela dokumentet (https://jira.mongodb.org/browse/DOCS-11416). Vad betyder detta, exakt?

Detta är en implementeringsdetalj som förbättrar WiredTigers interna datastrukturer för vissa användningsfall. I synnerhet kan WiredTiger i MongoDB 3.6+ vara effektivare när det gäller att arbeta med små ändringar i stora dokument (jämfört med tidigare utgåvor). WiredTiger-cachen måste kunna returnera flera versioner av dokument så länge de används av öppna interna sessioner (MVCC, som nämnts tidigare), så för stora dokument med små uppdateringar kan det vara mer effektivt att lagra en lista med delta. Men om för många delta ackumuleras (eller deltan ändrar de flesta av fälten i ett dokument) kan detta tillvägagångssätt vara mindre effektivt än att behålla flera kopior av hela dokumentet.

När data överförs till disk via en kontrollpunkt, måste en fullständig version av dokumentet fortfarande skrivas. Om du vill lära dig mer om några av internerna finns det en MongoDB Path To Transactions-serie med videor som följer utvecklingen av funktioner för att stödja transaktioner med flera dokument i MongoDB 4.0.

Vad jag inte förstår är också att de flesta (om inte alla) hårddiskar numera har en sektorstorlek på 4096 byte, så du kan inte skriva till hårddisken bara 4 byte (till exempel) utan måste istället skriva hela blocket på 4096 byte (så läs den först, uppdatera de 4 byten i den och skriv den sedan). Eftersom de flesta dokument ofta är <4096 byte betyder detta att det är nödvändigt att skriva om hela dokumentet i alla fall (även med MMAP). Vad har jag missat?

Utan att gå för långt in i implementeringsdetaljer och försöka förklara alla rörliga delar som är involverade, överväg hur de olika tillvägagångssätten tillämpas på arbetsbelastningar där många dokument uppdateras (snarare än på enstaka dokumentnivå) samt påverkan på minnesanvändning (före dokument skrivs till disk). Beroende på faktorer som dokumentstorlek och komprimering kan ett enda I/O-block representera allt från en bråkdel av ett dokument (maxstorlek 16 MB) till flera dokument.

I MongoDB är det allmänna flödet att dokument uppdateras i en minnesvy (till exempel WiredTiger-cachen) med ändringar kvar på disken i ett snabbt append-only journalformat innan de regelbundet rensas till datafilerna. Om O/S bara behöver skriva datablock som har ändrats, kräver färre datablock mindre övergripande I/O.




  1. Hur man optimerar prestanda för ClusterControl och dess komponenter

  2. Hur man får en återuppringning på MongoDB collection.find()

  3. Hur kan jag säkert ansluta till Heroku-värd Redis från kommandoraden?

  4. Hur man testar selleri med django på en Windows-maskin