MongoDB Sharding: Steg-for-trinn praktisk veiledning

Sharding er en prosess for å dele opp den store skalaen av datasett i en del av mindre datasett på tvers av flere MongoDB-forekomster i et distribuert miljø.

Hva er Sharding?

MongoDB-sharding gir oss en skalerbar løsning for å lagre en stor mengde data blant antall servere i stedet for å lagre på en enkelt server.

Rent praktisk er det ikke mulig å lagre eksponentielt voksende data på en enkelt maskin. Å forespørre en enorm mengde data som er lagret på en enkelt server kan føre til høy ressursutnyttelse og kan ikke gi tilfredsstillende lese- og skrivegjennomstrømning.

I utgangspunktet er det to typer skaleringsmetoder som eksisterer for å gjennomføre voksende data med systemet:

Vertikal skalering fungerer med å forbedre ytelsen til én server ved å legge til kraftigere prosessorer, oppgradere RAM eller legge til mer diskplass til systemet. Men det er mulige implikasjoner av å bruke vertikal skalering i praktiske brukstilfeller med eksisterende teknologi og maskinvarekonfigurasjoner.

Horisontal skalering fungerer med å legge til flere servere og fordele belastningen på flere servere. Siden hver maskin vil håndtere undersettet av hele datasettet, gir den bedre effektivitet og kostnadseffektiv løsning i stedet for å distribuere avansert maskinvare. Men det krever ekstra vedlikehold av kompleks infrastruktur med et stort antall servere.

Mongo DB-skjæring fungerer på horisontal skaleringsteknikk.

Delingskomponenter

For å oppnå sharding i MongoDB, kreves følgende komponenter:

Shard er en Mongo-forekomst for å håndtere en delmengde av originaldata. Shards er nødvendig for å være utplassert i replikasettet.

Mongos er en Mongo-forekomst og fungerer som et grensesnitt mellom en klientapplikasjon og en sønderdelt klynge. Den fungerer som en spørringsruter til shards.

Config Server er en Mongo-instans som lagrer metadatainformasjon og konfigurasjonsdetaljer for klyngen. MongoDB krever at konfigurasjonsserveren distribueres som et replikasett.

Sharding arkitektur

MongoDB-klyngen består av en rekke replikasett.

Hvert replikasett består av minimum 3 eller flere mongoforekomster. En shard-klynge kan bestå av flere mongo shards-forekomster, og hver shard-forekomst fungerer innenfor et shard-replikasett. Applikasjonen samhandler med Mongos, som igjen kommuniserer med skår. Derfor samhandler aldri applikasjoner direkte med shardnoder i Sharding. Spørringsruteren distribuerer delsettene av data mellom shard-noder basert på shard-nøkkelen.

Sharding-implementering

Følg trinnene nedenfor for skjæring

Trinn 1

  • Start konfigurasjonsserveren i replikasettet og aktiver replikering mellom dem.

mongod –configsvr –port 27019 –replSet rs0 –dbpath C:datadata1 –bind_ip localhost

mongod –configsvr –port 27018 –replSet rs0 –dbpath C:datadata2 –bind_ip localhost

mongod –configsvr –port 27017 –replSet rs0 –dbpath C:datadata3 –bind_ip localhost

Steg 2

  • Initialiser replikasettet på en av konfigurasjonsserverne.

rs.initiate( { _id : «rs0», configsvr: true, medlemmer: [   { _id: 0, host: “IP:27017” },   { _id: 1, host: “IP:27018” },   { _id: 2, host: “IP:27019” }    ] })

rs.initiate( { _id : "rs0",  configsvr: true,  members: [   { _id: 0, host: "IP:27017" },   { _id: 1, host: "IP:27018" },   { _id: 2, host: "IP:27019" }    ] })
{
        "ok" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(1593569257, 1),
                "electionId" : ObjectId("000000000000000000000000")
        },
        "lastCommittedOpTime" : Timestamp(0, 0),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593569257, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1593569257, 1)
}

Trinn 3

  • Start deling av servere i replikasettet og aktiver replikering mellom dem.
  12 beste globale delte hosting for nybegynnere

mongod –shardsvr –port 27020 –replSet rs1 –dbpath C:datadata4 –bind_ip localhost

mongod –shardsvr –port 27021 –replSet rs1 –dbpath C:datadata5 –bind_ip localhost

mongod –shardsvr –port 27022 –replSet rs1 –dbpath C:datadata6 –bind_ip localhost

MongoDB initialiserer den første sharding-serveren som primær, for å flytte den primære sharding-serverbruken flyttePrimær metode.

Trinn 4

  • Initialiser replikasettet på en av de sønderdelte serverne.

rs.initiate( { _id : «rs0», medlemmer: [   { _id: 0, host: “IP:27020” },   { _id: 1, host: “IP:27021” },   { _id: 2, host: “IP:27022” }    ] })

rs.initiate( { _id : "rs0",  members: [   { _id: 0, host: "IP:27020" },   { _id: 1, host: "IP:27021" },   { _id: 2, host: "IP:27022" }    ] })
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593569748, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1593569748, 1)
}

Trinn 5

  • Start mangoene for den revne klyngen

mongos –port 40000 –configdb rs0/localhost:27019,localhost:27018, localhost:27017

Trinn 6

  • Koble til mongo-ruteserveren

mongo –port 40000

  • Legg nå til sharding-servere.

sh.addShard( “rs1/localhost:27020,localhost:27021,localhost:27022”)

sh.addShard( "rs1/localhost:27020,localhost:27021,localhost:27022")
{
        "shardAdded" : "rs1",
        "ok" : 1,
        "operationTime" : Timestamp(1593570212, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570212, 2),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

Trinn 7

  • På mongo shell muliggjør sharding på DB og samlinger.
  • Aktiver deling på DB

sh.enableSharding(“geekFlareDB”)

sh.enableSharding("geekFlareDB")
{
        "ok" : 1,
        "operationTime" : Timestamp(1591630612, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1591630612, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

Trinn 8

  • For å skjære er samlingsshard-nøkkelen (beskrevet senere i denne artikkelen) nødvendig.

Syntaks: sh.shardCollection(“dbName.collectionName”, { “key” : 1 } )

sh.shardCollection("geekFlareDB.geekFlareCollection", { "key" : 1 } )
{
        "collectionsharded" : "geekFlareDB.geekFlareCollection",
        "collectionUUID" : UUID("0d024925-e46c-472a-bf1a-13a8967e97c1"),
        "ok" : 1,
        "operationTime" : Timestamp(1593570389, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570389, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

Legg merke til hvis samlingen ikke eksisterer, opprett som følger.

db.createCollection("geekFlareCollection")
{
        "ok" : 1,
        "operationTime" : Timestamp(1593570344, 4),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570344, 5),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

Trinn 9

Sett inn data i samlingen. Mongo-logger vil begynne å vokse, og indikerer at en balanserer er i aksjon og prøver å balansere dataene mellom shards.

Trinn 10

Det siste trinnet er å sjekke statusen til skjæringen. Status kan sjekkes ved å kjøre under kommandoen på Mongos-rutenoden.

Delingsstatus

Sjekk sønderdelingsstatus ved å kjøre under kommandoen på mongo-rutenoden.

sh.status()

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5ede66c22c3262378c706d21")
  }
  shards:
        {  "_id" : "rs1",  "host" : "rs1/localhost:27020,localhost:27021,localhost:27022",  "state" : 1 }
  active mongoses:
        "4.2.7" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  5
        Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs1
        Time of Reported error:  Tue Jun 09 2020 15:25:03 GMT+0530 (India Standard Time)
        Migration Results for the last 24 hours:
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1024
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "geekFlareDB",  "primary" : "rs1",  "partitioned" : true,  "version" : {  "uuid" : UUID("a770da01-1900-401e-9f34-35ce595a5d54"),  "lastMod" : 1 } }
                geekFlareDB.geekFlareCol
                        shard key: { "key" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1
                        { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
                geekFlareDB.geekFlareCollection
                        shard key: { "product" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1
                        { "product" : { "$minKey" : 1 } } -->> { "product" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
        {  "_id" : "test",  "primary" : "rs1",  "partitioned" : false,  "version" : {  "uuid" : UUID("fbc00f03-b5b5-4d13-9d09-259d7fdb7289"),  "lastMod" : 1 } }

mongos>

Datadistribusjon

Mongos-ruteren fordeler belastningen mellom shards basert på shard-nøkkelen, og jevnt fordelt data; balanserer kommer i aksjon.

  Jeg brukte en Cortana Smart Speaker hele helgen. Her er hvorfor det mislyktes

Nøkkelkomponenten for å distribuere data mellom shards er

  • En balanserer spiller en rolle i å balansere delmengden av data blant de sønderdelte nodene. Balancer kjører når Mongos-serveren begynner å fordele belastninger mellom shards. Etter å ha startet, fordelte Balancer data jevnere. For å sjekke statusen til balancer, kjør sh.status() eller sh.getBalancerState() ellersh.isBalancerRunning().
mongos> sh.isBalancerRunning()
true
mongos>

ELLER

mongos> sh.getBalancerState()
true
mongos>

Etter å ha satt inn dataene, kunne vi legge merke til noe aktivitet i Mongos-demonen som sier at den flytter noen biter for de spesifikke shards og så videre, dvs. balansereren vil være i aksjon og prøve å balansere dataene på tvers av shards. Å kjøre balancer kan føre til ytelsesproblemer; derfor er det foreslått å kjøre balanseren innenfor en viss balanservindu.

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5efbeff98a8bbb2d27231674")
  }
  shards:
        {  "_id" : "rs1",  "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",  "state" : 1 }
        {  "_id" : "rs2",  "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",  "state" : 1 }
  active mongoses:
        "4.2.7" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  yes
        Failed balancer rounds in last 5 attempts:  5
        Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs2
        Time of Reported error:  Wed Jul 01 2020 14:39:59 GMT+0530 (India Standard Time)
        Migration Results for the last 24 hours:
                1024 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs2     1024
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "geekFlareDB",  "primary" : "rs2",  "partitioned" : true,  "version" : {  "uuid" : UUID("a8b8dc5c-85b0-4481-bda1-00e53f6f35cd"),  "lastMod" : 1 } }
                geekFlareDB.geekFlareCollection
                        shard key: { "key" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs2     1
                        { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs2 Timestamp(1, 0)
        {  "_id" : "test",  "primary" : "rs2",  "partitioned" : false,  "version" : {  "uuid" : UUID("a28d7504-1596-460e-9e09-0bdc6450028f"),  "lastMod" : 1 } }

mongos>
  • Shard Key bestemmer logikken for å distribuere dokumenter av sharded samling blant shards. Shard-nøkkel kan være et indeksert felt eller indeksert sammensatt felt som må være til stede i alle dokumenter i samlingen som skal settes inn. Data vil bli partisjonert i biter, og hver del vil bli assosiert med den rekkeviddebaserte shard-nøkkelen. På grunnlag av rekkeviddespørringen vil ruteren bestemme hvilken shard som skal lagre delen.

Shard Key kan velges ved å vurdere fem egenskaper:

  • Kardinalitet
  • Skriv distribusjon
  • Les distribusjon
  • Les målretting
  • Les lokalitet

En ideell shard-nøkkel gjør at MongoDB fordeler belastningen jevnt mellom alle shard. Å velge en god shardnøkkel er ekstremt viktig.

Bilde: MongoDB

Fjerning av shard-noden

Før du fjerner shards fra klyngen, må brukeren sørge for sikker migrering av data til gjenværende shards. MongoDB tar seg av sikker drenering av data til andre shard-noder før fjerning av den nødvendige shard-noden.

Kjør under kommandoen for å fjerne den nødvendige sharden.

Trinn 1

Først må vi bestemme vertsnavnet til sharden som skal fjernes. Kommandoen nedenfor vil liste alle shards som er tilstede i klyngen sammen med tilstanden til shard.

db.adminCommand( { listShards: 1 } )

mongos> db.adminCommand( { listShards: 1 } )
{
        "shards" : [
                {
                        "_id" : "rs1",
                        "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",
                        "state" : 1
                },
                {
                        "_id" : "rs2",
                        "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                        "state" : 1
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1593572866, 15),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593572866, 15),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

Steg 2

Utfør kommandoen nedenfor for å fjerne den nødvendige sharden fra klyngen. Når den er utstedt, tar balanseringsenheten seg av fjerning av biter fra drenerende shard-noden og balanserer deretter fordelingen av gjenværende shards blant resten shard-nodene.

db.adminCommand( { removeShard: “shardedReplicaNodes” } )

mongos> db.adminCommand( { removeShard: "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022" } )
{
        "msg" : "draining started successfully",
        "state" : "started",
        "shard" : "rs1",
        "note" : "you need to drop or movePrimary these databases",
        "dbsToMove" : [ ],
        "ok" : 1,
        "operationTime" : Timestamp(1593572385, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593572385, 2),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

Trinn 3

For å sjekke statusen til dreneringsskjæret, gi den samme kommandoen på nytt.

db.adminCommand( { removeShard: “rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022” } )

Vi må vente til tømmingen av dataene er fullført. meldings- og tilstandsfelt vil vise om tømming av data er fullført eller ikke, som følger

"msg" : "draining ongoing",
"state" : "ongoing",

Vi kan også sjekke statusen med kommandoen sh.status(). Når den er fjernet, gjenspeiles ikke shard node i utdataene. Men hvis drenering vil pågå, vil den sønderdelte noden komme med dreneringsstatus som sann.

Trinn 4

Fortsett å sjekke statusen for drenering med den samme kommandoen ovenfor, til den nødvendige skåren er fjernet helt.
Når den er fullført, vil utdataene fra kommandoen gjenspeile meldingen og tilstanden som fullført.

"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "rs1",
"ok" : 1,

Trinn 5

Til slutt må vi sjekke de gjenværende skårene i klyngen. For å sjekke statusen skriv inn sh.status() eller db.adminCommand( { listShards: 1 } )

mongos> db.adminCommand( { listShards: 1 } )
{
        "shards" : [
                {
                        "_id" : "rs2",
                        "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                        "state" : 1
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1593575215, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593575215, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

Her kan vi se at det fjernede skåret ikke lenger er til stede i listen over skår.

Fordeler med Sharding fremfor replikering

  • Ved replikering håndterer den primære noden alle skriveoperasjoner, mens sekundære servere er pålagt å vedlikeholde sikkerhetskopier eller betjene skrivebeskyttede operasjoner. Men ved skjæring sammen med replikasett blir belastningen fordelt på antall servere.
  • Et enkelt replikasett er begrenset til 12 noder, men det er ingen begrensning på antall shards.
  • Replikering krever avansert maskinvare eller vertikal skalering for å håndtere store datasett, noe som er for dyrt sammenlignet med å legge til flere servere i sharding.
  • I replikering kan leseytelsen forbedres ved å legge til flere slave-/sekundære servere, mens i sharding vil både lese- og skriveytelsen bli forbedret ved å legge til flere shards-noder.

Delingsbegrensning

  • Sharded-klyngen støtter ikke unik indeksering på tvers av shards før den unike indeksen er prefikset med full shard-nøkkel.
  • Alle oppdateringsoperasjoner for sharded samling enten på ett eller flere dokumenter må inneholde sharded key eller _id-feltet i spørringen.
  • Samlinger kan deles hvis størrelsen ikke overstiger den angitte terskelen. Denne terskelen kan estimeres på grunnlag av gjennomsnittlig størrelse på alle shard-nøkler og konfigurert størrelse på biter.
  • Sharding består av operasjonelle grenser for maks samlingsstørrelse eller antall deler.
  • Å velge feil shard-nøkler for å føre til ytelsesimplikasjoner.

Konklusjon

MongoDB tilbyr innebygd sharding for å implementere en stor database uten å kompromittere ytelsen. Jeg håper ovenstående hjelper deg med å sette opp MongoDB-sharding. Deretter vil du kanskje bli kjent med noen av de vanligste MongoDB-kommandoene.