S modulem úložiště MMAPv1 jsou aktualizace na místě často zdůrazňovány jako optimalizační strategie, protože indexy dokumentu ukazují přímo na umístění souborů a offsety. Přesunutí dokumentu do nového umístění úložiště (zejména pokud existuje mnoho položek indexu k aktualizaci) má pro MMAPv1 větší režii než aktualizace na místě, která musí aktualizovat pouze změněná pole. Viz:Charakteristiky ukládání záznamů v MMAPv1.
WiredTiger nepodporuje aktualizace na místě, protože interně používá MVCC (Multiversion concurrency control), který běžně používají systémy pro správu databází. Toto je významné technické vylepšení oproti zjednodušenému zobrazení v MMAP a umožňuje vytvářet pokročilejší funkce, jako jsou úrovně izolace a transakce. Indexy WiredTiger mají úroveň nepřímosti (odkazují na interní RecordID namísto umístění souboru a offsetu), takže přesuny dokumentů na úrovni úložiště nepředstavují významný problém.
Tento článek však také říká, že "I když [WiredTiger] neumožňuje aktualizace na místě, stále může fungovat lépe než MMAP pro mnoho pracovních zátěží."
Znamená to, že ačkoli MMAPv1 může mít efektivnější cestu pro aktualizace na místě, WiredTiger má další výhody, jako je komprese a vylepšené řízení souběžnosti. Možná byste mohli vytvořit pracovní zátěž sestávající pouze z místních aktualizací několika dokumentů, které by mohly fungovat lépe v MMAPv1, ale skutečné pracovní zátěže jsou obvykle rozmanitější. Jediným způsobem, jak potvrdit dopad pro danou pracovní zátěž, by bylo testování v reprezentativním prostředí.
Obecná volba MMAPv1 vs WiredTiger je však sporná, pokud chcete plánovat do budoucna:WiredTiger je výchozím úložištěm od MongoDB 3.2 a některé funkce novějších produktů nejsou podporovány MMAPv1. Například MMAPv1 nepodporuje Majority Read Concern, což zase znamená, že jej nelze použít pro servery Replica Set Config Server (vyžadované pro sharding v MongoDB 3.4+) nebo Change Streams (MongoDB 3.6+). MMAPv1 bude v příštím hlavním vydání MongoDB (4.0) zastaralý a v současné době je naplánováno jeho odstranění v MongoDB 4.2.
Jaké jsou přesné důsledky, kterých si musím být vědom, když používám WiredTiger? Například bez aktualizací na místě se velikost databáze rychle zvětší?
Výsledky úložiště závisí na několika faktorech, včetně návrhu schématu, zátěže, konfigurace a verze serveru MongoDB. MMAPv1 a WiredTiger používají různé strategie přidělování záznamů, ale oba se pokusí využít předem přidělený prostor, který je označen jako volný/opakovaně použitelný. Obecně je WiredTiger efektivnější s využitím úložného prostoru a má také výhodu komprese dat a indexů. MMAPv1 přiděluje další úložný prostor, aby se pokusil optimalizovat pro aktualizace na místě a vyhnul se přesouvání dokumentů, i když můžete zvolit strategii „bez odsazení“ pro kolekce, kde pracovní zátěž v průběhu času nemění velikost dokumentu.
Od doby, kdy byl poprvé představen v MongoDB 3.0, došlo k značným investicím do vylepšení a vyladění WiredTiger pro různé pracovní zátěže, takže bych důrazně doporučil testování s nejnovějšími produkčními řadami pro nejlepší výsledek. Pokud máte konkrétní otázku ohledně návrhu schématu a růstu úložiště, navrhuji zveřejnit podrobnosti na DBA StackExchange k diskusi.
Také jsem se dozvěděl, že WiredTiger v MongoDB 3.6 přidal možnost ukládat delty spíše než přepisovat celý dokument (https://jira.mongodb.org/browse/DOCS-11416). Co to přesně znamená?
Toto je detail implementace, který zlepšuje vnitřní datové struktury WiredTiger pro některé případy použití. Zejména WiredTiger v MongoDB 3.6+ může být efektivnější při práci s malými změnami ve velkých dokumentech (ve srovnání s předchozími verzemi). Mezipaměť WiredTiger musí být schopna vrátit více verzí dokumentů, pokud jsou používány otevřenými interními relacemi (MVCC, jak bylo zmíněno dříve), takže pro velké dokumenty s malými aktualizacemi by mohlo být efektivnější ukládat seznam rozdílů. Pokud se však nahromadí příliš mnoho delt (nebo delty mění většinu polí v dokumentu), může být tento přístup méně výkonný než udržování více kopií celého dokumentu.
Když jsou data odeslána na disk prostřednictvím kontrolního bodu, je stále třeba zapsat plnou verzi dokumentu. Pokud se chcete dozvědět více o některých interních funkcích, existuje série videí MongoDB Path To Transactions sledující vývoj funkcí pro podporu transakcí s více dokumenty v MongoDB 4.0.
Také nerozumím tomu, že v dnešní době má většina (pokud ne všechny) pevné disky velikost sektoru 4096 bajtů, takže na pevný disk nemůžete zapisovat pouze 4 bajty (například), ale místo toho musíte zapsat celý blok 4096 bajtů (takže si to nejdřív přečtěte, aktualizujte v něm 4 bajty a pak to zapište). Protože většina dokumentů má často <4096 bajtů, znamená to, že je v každém případě nutné přepsat celý dokument (i s MMAP). Co mi uniklo?
Aniž byste zacházeli příliš daleko do podrobností implementace a pokoušeli se vysvětlit všechny zahrnuté pohyblivé části, zvažte, jak se různé přístupy vztahují k pracovní zátěži, kde se aktualizuje mnoho dokumentů (spíše než na úrovni jednoho dokumentu), a také dopad na využití paměti (před dokumenty se zapisují na disk). V závislosti na faktorech, jako je velikost dokumentu a komprese, může jeden blok I/O představovat kdekoli od zlomku dokumentu (maximální velikost 16 MB) po více dokumentů.
V MongoDB je obecný postup takový, že dokumenty jsou aktualizovány v zobrazení v paměti (například mezipaměť WiredTiger) se změnami přetrvávajícími na disku ve formátu žurnálu s rychlým připojením, než jsou pravidelně vyprázdněny do datových souborů. Pokud O/S musí zapisovat pouze bloky dat, které se změnily, dotyk s menším počtem bloků dat vyžaduje méně celkových I/O.