sql >> Database >  >> NoSQL >> MongoDB

Operationele factoren om te overwegen tijdens MongoDB-gegevensmodellering

In mijn vorige blog, MongoDB-gegevensmodellering gebruiken om doorvoerbewerkingen te verbeteren, hebben we de twee belangrijkste benaderingen van gegevensmodellering-relaties besproken, namelijk insluiten en verwijzen. De schaalbaarheid van MongoDB is nogal afhankelijk van de architectuur en, om specifiek te zijn, datamodellering. Bij het ontwerpen van een NoSQL DBM is het belangrijkste punt van overweging om te zorgen voor documenten zonder schema, naast een klein aantal collecties met het oog op eenvoudig onderhoud. Goede gegevensintegriteit, het toepassen van gegevensvalidatie door middel van een aantal gedefinieerde regels voordat opslag wordt aangemoedigd. Een database-architectuur en -ontwerp moeten worden genormaliseerd en ontleed in meerdere kleine verzamelingen om herhaling van gegevens te vermijden, de gegevensintegriteit te verbeteren en het gemakkelijk te maken met ophaalpatronen. Als dit op zijn plaats is, bent u in staat om de gegevensconsistentie, atomiciteit, duurzaamheid en integriteit van uw database te verbeteren.

Datamodellering is geen bijzaak in een applicatieontwikkelingsfase, maar een eerste overweging, aangezien veel applicatiefacetten daadwerkelijk worden gerealiseerd tijdens de datamodelleringsfase. In dit artikel gaan we bespreken met welke factoren rekening moet worden gehouden tijdens het modelleren van gegevens en hoe deze de prestaties van een database in het algemeen beïnvloeden.

Vaak moet u een cluster van uw database implementeren als een manier om de beschikbaarheid van gegevens te vergroten. Met een goed ontworpen gegevensmodel kunt u activiteiten effectiever naar een shard-cluster distribueren, waardoor de doorvoerbewerkingen die op één enkele mongod-instantie zijn gericht, worden verminderd. De belangrijkste factoren waarmee rekening moet worden gehouden bij gegevensmodellering zijn:

  1. Schaalbaarheid
  2. Atomiciteit
  3. Prestaties en datagebruik
  4. Sharden
  5. Indexeren
  6. Opslagoptimalisatie
  7. Documentstructuur en groei
  8. Gegevenslevenscyclus

1. Schaalbaarheid

Dit is een toename van de werklast van een applicatie die wordt aangedreven door meer verkeer. Veel applicaties hebben altijd een verwachting in de toename van het aantal gebruikers. Wanneer er zoveel gebruikers worden bediend door een enkele database-instantie, voldoen de prestaties niet altijd aan de verwachtingen. Als databasemanager heb je dus een mandaat om deze DBM zo te ontwerpen dat collecties en data-entiteiten worden gemodelleerd op basis van de huidige en toekomstige eisen van de applicatie. De databasestructuur moet over het algemeen presentabel zijn om het proces van replicatie en sharding te vergemakkelijken. Als u meer shards hebt, worden de schrijfbewerkingen over deze shards verdeeld, zodat voor elke gegevensupdate dit wordt gedaan binnen de shard die die gegevens bevat, in plaats van op te zoeken in een enkele grote set gegevens om een ​​update uit te voeren.

2. Atomiciteit

Dit verwijst naar het slagen of mislukken van een bewerking als een enkele eenheid. U kunt bijvoorbeeld een leesbewerking hebben waarbij een sorteerbewerking wordt uitgevoerd nadat het resultaat is opgehaald. Als de sorteerbewerking niet goed wordt afgehandeld, gaat de hele bewerking daarom niet door naar de volgende fase.

Atoomtransacties zijn reeksen operaties die niet deelbaar of herleidbaar zijn en daarom als afzonderlijke entiteiten voorkomen of als een enkele operatie mislukken. MongoDB-versies vóór 4.0 ondersteunen schrijfbewerkingen als atomaire processen op een enkel documentniveau. Met de versie 4.0 kan men nu transacties met meerdere documenten implementeren. Een datamodel dat atomaire operaties verbetert, heeft over het algemeen geweldige prestaties in termen van latentie. Latency is simpelweg de tijdsduur waarbinnen een bewerkingsverzoek wordt verzonden en wanneer een reactie wordt geretourneerd vanuit de database. Voor alle duidelijkheid:het is gemakkelijk om gegevens bij te werken die zijn ingesloten in een enkel document in plaats van in een document waarnaar wordt verwezen.

Laten we bijvoorbeeld de onderstaande dataset bekijken

{
    childId : "535523",
    studentName : "James Karanja",
    parentPhone : 704251068,
    age : 12,
    settings : {
        location : "Embassy",
        address : "420 01",
        bus : "KAZ 450G",
        distance : "4"
      }
}

Als we de leeftijd willen bijwerken door deze met 1 te verhogen en de locatie naar Londen willen wijzigen, kunnen we het volgende doen:

db.getCollection(‘students’).update({childId: 535523},{$set:{'settings.location':'London'}, $inc:{age:1}}).

Als bijvoorbeeld de $set-bewerking mislukt, wordt de $inc-bewerking automatisch niet geïmplementeerd en mislukt in het algemeen de hele bewerking.

Aan de andere kant, laten we eens kijken naar gegevens waarnaar wordt verwezen, zodat er 2 verzamelingen zijn, één voor studenten en de andere voor instellingen.

Studentencollectie

{
    childId : "535523",
    studentName : "James Karanja",
    parentPhone : 704251068,
    age : 12
}

Instellingen verzameling

{
  childId : "535523",  
  location : "Embassy",
  address : "420 01",
  bus : "KAZ 450G",
  distance : "4"
}

In dit geval kunt u de leeftijds- en locatiewaarden bijwerken met afzonderlijke schrijfbewerkingen, d.w.z.

db.getCollection(‘students’).update({childId: 535523},{$inc:{age:1}})
db.getCollection('settings’).update({childId: 535523 } , {$set: { 'settings.location':'London'}})

Als een van de bewerkingen mislukt, heeft dit niet noodzakelijk invloed op de andere, omdat ze als verschillende entiteiten worden uitgevoerd.

Transacties voor meerdere documenten

Met MongoDB versie 4.0 kunt u nu meerdere documenttransacties uitvoeren voor replicasets. Dit verbetert de prestaties omdat de bewerkingen worden uitgegeven aan een aantal collecties, databases en documenten voor snelle verwerking. Wanneer een transactie is uitgevoerd, worden de gegevens opgeslagen, terwijl als er iets misgaat en een transactie mislukt, de aangebrachte wijzigingen worden genegeerd en de transactie in het algemeen wordt afgebroken. Er vindt geen update van de replicasets plaats tijdens de transactie, aangezien de bewerking alleen buiten zichtbaar is wanneer de transactie volledig is vastgelegd.

Zoveel als u meerdere documenten in meerdere transacties kunt bijwerken, gaat het gepaard met een terugval van verminderde prestaties in vergelijking met het schrijven van één document. Bovendien wordt deze benadering alleen ondersteund voor de WiredTiger-opslagengine en is daarom een ​​nadeel voor de In-Memory- en MMAPv1-opslagengines.

3. Prestaties en gegevensgebruik

Applicaties zijn verschillend ontworpen om aan verschillende doeleinden te voldoen. Er zijn er enkele die alleen voor de huidige gegevens dienen, zoals toepassingen voor weernieuws. Afhankelijk van de structuur van een applicatie, zou men in staat moeten zijn om een ​​corresponderende optimale database te ontwerpen om de vereiste use case te dienen. Als men bijvoorbeeld een applicatie ontwikkelt die de meest recente gegevens uit de database haalt, is het gebruik van een gecapte collectie de beste optie. Een afgetopte verzameling verbetert de verwerking met hoge doorvoer, net als een buffer, zodat wanneer de toegewezen ruimte wordt benut, de oudste documenten worden overschreven en de documenten kunnen worden opgehaald in de volgorde waarin ze zijn ingevoegd. Gezien het ophalen van de invoegvolgorde, is het niet nodig om indexering te gebruiken en het ontbreken van een indexoverhead zal de schrijfdoorvoer eveneens verbeteren. Met een afgetopte verzameling zijn de bijbehorende gegevens vrij klein omdat ze enige tijd in het RAM kunnen worden bewaard. Tijdelijke gegevens worden in dit geval opgeslagen in de cache, die nogal wordt gelezen dan dat erin wordt geschreven, waardoor de leesbewerking vrij snel verloopt. De gecapte collectie heeft echter enkele nadelen, zoals:u kunt een document niet verwijderen tenzij de hele verzameling wordt verwijderd, elke wijziging in de grootte van een document zal de bewerking mislukken en ten slotte is het niet mogelijk om een ​​gecapte collectie te sharden.

Verschillende facetten zijn geïntegreerd in de datamodellering van een database, afhankelijk van de gebruiksbehoeften. Zoals gezien zullen rapportapplicaties de neiging hebben om meer leesintensief te zijn, daarom moet het ontwerp op een manier zijn om de leesdoorvoer te verbeteren.

4. Schuren

De prestaties door middel van horizontale schaling kunnen worden verbeterd door sharding, aangezien de lees- en schrijfworkloads worden verdeeld over de clusterleden. Het implementeren van een cluster van shards heeft de neiging de database te verdelen in meerdere kleine verzamelingen met gedistribueerde documenten, afhankelijk van een shardsleutel. U moet een geschikte Shard-sleutel selecteren die isolatie van query's kan voorkomen, naast het vergroten van de schrijfcapaciteit. Een betere selectie betreft doorgaans een veld dat aanwezig is in alle documenten binnen de beoogde collectie. Met sharding is er meer opslagruimte, omdat naarmate de gegevens groeien, er meer shards worden aangemaakt om een ​​subset van dit cluster te bevatten.

5. Indexeren

Indexering is een van de beste benaderingen voor het verbeteren van de schrijfwerkbelasting, vooral wanneer de velden in alle documenten voorkomen. Bij het indexeren moet men er rekening mee houden dat elke index 8 KB aan dataruimte nodig heeft. Verder, wanneer de index actief is, zal deze wat schijfruimte en geheugen in beslag nemen en moet daarom worden bijgehouden voor capaciteitsplanning.

Multiplenines Word een MongoDB DBA - MongoDB naar productie brengenLeer over wat u moet weten om MongoDB gratis te implementeren, bewaken, beheren en schalen

6. Opslagoptimalisatie

Veel kleine documenten binnen een verzameling nemen doorgaans meer ruimte in beslag dan wanneer u enkele documenten hebt met ingesloten documenten. Bij het modelleren moet men daarom de gerelateerde gegevens groeperen voordat ze worden opgeslagen. Met een paar documenten kan een databasebewerking worden uitgevoerd met weinig query's, waardoor willekeurige schijftoegang wordt verminderd en er minder bijbehorende sleutelitems in de bijbehorende index zullen zijn. Overwegingen in dit geval zijn daarom:gebruik embedding om minder documenten te hebben, wat op zijn beurt de overhead per document vermindert. Gebruik kortere veldnamen als er minder velden betrokken zijn bij een verzameling, om de documentoverhead niet significant te maken. Kortere veldnamen verminderen de expressiviteit .d.w.z.

{ Lname : "Briston", score : 5.9 }

bespaart 9 bytes per document in plaats van

{ last_name : "Briston", high_score: 5.9 }

Gebruik het veld _id expliciet. Standaard voegen MongoDB-clients een _id-veld toe aan elk document door een unieke 12-byte ObjectId aan dit veld toe te wijzen. Bovendien wordt het veld _id geïndexeerd. Als de documenten vrij klein zijn, neemt dit scenario een aanzienlijke hoeveelheid ruimte in beslag in het totale documentnummer. Voor opslagoptimalisatie mag u de waarde voor het veld _id expliciet specificeren bij het invoegen van documenten in een verzameling. Zorg er echter voor dat de waarde uniek wordt geïdentificeerd, omdat deze dient als primaire sleutel voor documenten in de collectie.

7. Documentstructuur en groei

Dit gebeurt als gevolg van de push-bewerking waarbij subdocumenten in een arrayveld worden geduwd of wanneer nieuwe velden aan een bestaand document worden toegevoegd. Documentgroei heeft enkele tegenslagen, d.w.z. voor een gelimiteerde verzameling, als de grootte wordt gewijzigd, zal de bewerking automatisch mislukken. Voor een MMAPv1-opslagengine zullen versies vóór 3.0 het document op schijf verplaatsen als de documentgrootte wordt overschreden. Bij latere versies vanaf 3.0 is er echter een concept van Power of 2 Sized Allocations dat de kans op dergelijke hertoewijzingen verkleint en een effectief hergebruik van de vrijgekomen recordruimte mogelijk maakt. Als u verwacht dat uw gegevens zullen groeien, kunt u uw gegevensmodel refactoren om verwijzingen tussen gegevens in afzonderlijke documenten te gebruiken in plaats van een gedenormaliseerd gegevensmodel te gebruiken. Om documentgroei te voorkomen, kunt u ook overwegen een pre-allocatiestrategie te gebruiken.

8. Gegevenslevenscyclus

Voor een toepassing die alleen de recent ingevoegde documenten gebruikt, kunt u overwegen een gecapte verzameling te gebruiken waarvan de functies hierboven zijn besproken.

U kunt ook de functie Time to Live instellen voor uw verzameling. Dit is heel toepasselijk voor toegangstokens in de functie voor het opnieuw instellen van wachtwoorden voor applicaties.

Tijd om te leven (TTL)

Dit is een verzamelingsinstelling die het voor mongod mogelijk maakt om automatisch gegevens te verwijderen na een bepaalde duur. Dit concept wordt standaard toegepast op door machines gegenereerde gebeurtenisgegevens, logs en sessie-informatie die gedurende een beperkte periode moeten worden bewaard.

Voorbeeld:

db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

We hebben een index createdAt gemaakt en een waarde van 3600 opgegeven expireAfterSeconds, wat 1 uur na het aanmaken is. Als we nu een document invoegen zoals:

db.log_events.insert( {
   "createdAt": new Date(),
   "logEvent": 2,
   "logMessage": "This message was recorded."
} )

Dit document wordt 1 uur na het invoegen verwijderd.

U kunt ook een klokspecifieke tijd instellen waarop u wilt dat het document wordt verwijderd. Om dit te doen, moet u eerst een index maken, d.w.z.:

db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

Nu kunnen we een document invoegen en het tijdstip specificeren waarop het moet worden verwijderd.

db.log_events.insert( {
   "expireAt": new Date(December 12, 2018 18:00:00'),
   "logEvent": 2,
   "logMessage": "Success!"
} )

Dit document wordt automatisch verwijderd wanneer de waarde expireAt ouder is dan het aantal seconden dat is opgegeven in de expireAfterSeconds, d.w.z. 0 in dit geval.

Conclusie

Gegevensmodellering is een omvangrijke onderneming voor elk toepassingsontwerp om de databaseprestaties te verbeteren. Overweeg voordat u gegevens aan uw database toevoegt, de toepassingsbehoeften en welke de beste gegevensmodelpatronen zijn die u moet implementeren. Bovendien kunnen belangrijke facetten van applicaties pas gerealiseerd worden na de implementatie van een goed datamodel.


  1. Vul ontbrekende datums in records in

  2. Hoe de Redis-prestaties te verhogen bij 100% CPU? Scheren? Snelste .Net-client?

  3. redis voor loggen

  4. Optimalisatie van MongoDB-query's