MongoDB Sharding: Lépésről lépésre gyakorlati útmutató

A megosztás egy olyan folyamat, amely során az adatkészletek nagy skáláját kisebb adatkészletekre osztják fel több MongoDB-példány között elosztott környezetben.

Mi az a Sharding?

A MongoDB sharding skálázható megoldást kínál számunkra, hogy nagy mennyiségű adatot tároljunk több szerver között, ahelyett, hogy egyetlen szerveren tárolnánk.

Gyakorlatilag nem kivitelezhető az exponenciálisan növekvő adatok egyetlen gépen történő tárolása. Az egyetlen szerveren tárolt hatalmas mennyiségű adat lekérdezése magas erőforrás-kihasználáshoz vezethet, és előfordulhat, hogy nem biztosít kielégítő olvasási és írási teljesítményt.

Alapvetően kétféle skálázási módszer létezik az adatok növelésére a rendszerrel:

A Vertical Scaling javítja az egyetlen kiszolgáló teljesítményét erősebb processzorok hozzáadásával, RAM bővítésével vagy több lemezterület hozzáadásával. De megvannak a lehetséges következményei a függőleges skálázásnak a gyakorlati felhasználási esetekben a meglévő technológiai és hardverkonfigurációk mellett.

A vízszintes méretezés több kiszolgáló hozzáadásával és a terhelés több kiszolgálón való elosztásával működik. Mivel minden gép a teljes adatkészlet részhalmazát fogja kezelni, jobb hatékonyságot és költséghatékonyabb megoldást kínál a csúcskategóriás hardver telepítése helyett. De ehhez a nagyszámú szerverrel rendelkező összetett infrastruktúra további karbantartása szükséges.

A Mongo DB sharding a vízszintes skálázási technikán működik.

Az alkatrészek megosztása

A MongoDB felosztásához a következő összetevőkre van szükség:

A Shard egy Mongo példány az eredeti adatok egy részhalmazának kezelésére. A szilánkokat a replikakészletben kell telepíteni.

A Mongos egy Mongo példány, és interfészként működik az ügyfélalkalmazás és a szilánkos fürt között. Lekérdezési útválasztóként működik a szilánkok felé.

A Config Server egy Mongo példány, amely metaadat-információkat és a fürt konfigurációs részleteit tárolja. A MongoDB megköveteli, hogy a konfigurációs kiszolgálót replikakészletként kell üzembe helyezni.

Sharding Architecture

A MongoDB-fürt számos replikakészletből áll.

Minden replikakészlet legalább 3 mongo példányból áll. Egy szilánkos fürt több mongo szilánkpéldányból állhat, és mindegyik szilánkpéldány egy shard-replikakészleten belül működik. Az alkalmazás kölcsönhatásba lép a Mongos-szal, amely viszont szilánkokkal kommunikál. Ezért a Shardingban az alkalmazások soha nem lépnek kapcsolatba közvetlenül a szilánkos csomópontokkal. A lekérdezési útválasztó a shard kulcs alapján osztja el az adatok részhalmazait a szilánkok csomópontjai között.

Megosztás megvalósítása

A felosztáshoz kövesse az alábbi lépéseket

1. lépés

  • Indítsa el a konfigurációs kiszolgálót a replikakészletben, és engedélyezze közöttük a replikációt.

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

2. lépés

  • Inicializálja a replikakészletet az egyik konfigurációs kiszolgálón.

rs.initiate( { _id : “rs0”, configsvr: igaz, tagok: [   { _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)
}

3. lépés

  • Indítsa el a kiszolgálók felosztását a replikakészletben, és engedélyezze közöttük a replikációt.
  A játékmonitor mely jellemzői számítanak valójában?

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

A MongoDB az első megosztási kiszolgálót elsődlegesként inicializálja, hogy áthelyezze az elsődleges megosztási kiszolgáló használatát elsõdleges mozgás módszer.

4. lépés

  • Inicializálja a replikakészletet az egyik megosztott kiszolgálón.

rs.initiate( { _id : “rs0”, tagok: [   { _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)
}

5. lépés

  • Indítsa el a mangót a szilánkos fürthöz

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

6. lépés

  • Csatlakoztassa a mongo route szervert

mongo -port 40000

  • Most adjon hozzá felosztási kiszolgálókat.

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)
                }
        }
}

7. lépés

  • A mongo shell-en engedélyezze a DB és a gyűjtemények felosztását.
  • Felosztás engedélyezése a DB-n

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)
                }
        }
}

8. lépés

  • A gyűjtemény szilánkos kulcsa (amelynek leírása ebben a cikkben később lesz) szükséges.

Szintaxis: 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)
                }
        }
}

Megjegyzés: ha a gyűjtemény nem létezik, hozza létre az alábbiak szerint.

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

9. lépés

Adatok beillesztése a gyűjteménybe. A Mongo naplók növekedni kezdenek, és azt jelzik, hogy egy kiegyenlítő működik, és megpróbálja egyensúlyba hozni az adatokat a szilánkok között.

10. lépés

Az utolsó lépés a felosztás állapotának ellenőrzése. Az állapot ellenőrizhető az alábbi parancs futtatásával a Mongos útvonal csomópontján.

Megosztási állapot

Ellenőrizze a felosztási állapotot az alábbi parancs futtatásával a mongo útvonalcsomóponton.

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>

Adatelosztás

A Mongos útválasztó a shard kulcs alapján osztja el a terhelést a szilánkok között, és egyenletesen osztja el az adatokat; kiegyensúlyozó lép működésbe.

  Generatív ellenséges hálózatok (GAN): Bevezetés

Az adatok szilánkok közötti elosztásának kulcseleme

  • A kiegyensúlyozó szerepet játszik az adatok részhalmazának kiegyensúlyozásában a szilánkos csomópontok között. A Balancer akkor fut, amikor a Mongos szerver elkezdi a terhelések szétosztását a szilánkok között. Miután elindult, a Balancer egyenletesebben osztotta el az adatokat. A kiegyenlítő állapotának ellenőrzéséhez futtassa az sh.status() vagy az sh.getBalancerState() vagy ash.isBalancerRunning() parancsot.
mongos> sh.isBalancerRunning()
true
mongos>

VAGY

mongos> sh.getBalancerState()
true
mongos>

Az adatok beillesztése után a Mongos démonban valamilyen tevékenységet észleltünk, amely azt jelzi, hogy bizonyos darabokat mozgat az adott szilánkokhoz és így tovább, azaz a kiegyenlítő működésbe lép, és megpróbálja kiegyensúlyozni az adatokat a szilánkok között. A kiegyensúlyozó futtatása teljesítményproblémákat okozhat; ezért javasolt a kiegyenlítőt egy bizonyos határon belül futtatni kiegyensúlyozó ablak.

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>
  • A Shard Key meghatározza a szilánkok között a szilánkos gyűjtemény dokumentumainak elosztásának logikáját. A szilánkos kulcs lehet indexelt mező vagy indexelt összetett mező, amelynek jelen kell lennie a gyűjtemény összes beszúrandó dokumentumában. Az adatok darabokra lesznek felosztva, és minden egyes darab a tartomány alapú szilánkos kulcshoz lesz társítva. A tartomány lekérdezése alapján a router eldönti, hogy melyik szilánk tárolja a darabot.

A Shard Key öt tulajdonság figyelembevételével választható ki:

  • Cardinalitás
  • Írja meg az elosztást
  • Olvassa el a terjesztést
  • Olvassa el a célzást
  • Olvassa el a helységet

Az ideális szilánkos kulcsnak köszönhetően a MongoDB egyenletesen osztja el a terhelést az összes szilánk között. A jó szilánkos kulcs kiválasztása rendkívül fontos.

Kép: MongoDB

A szilánkos csomópont eltávolítása

Mielőtt eltávolítaná a szilánkokat a fürtből, a felhasználónak biztosítania kell az adatok biztonságos áttelepítését a fennmaradó szilánkokba. A MongoDB gondoskodik az adatok biztonságos ürítéséről más szilánkok csomópontjaiba, mielőtt a szükséges szilánkos csomópontot eltávolítaná.

Futtassa az alábbi parancsot a szükséges szilánk eltávolításához.

1. lépés

Először is meg kell határoznunk az eltávolítandó szilánk gazdagépnevét. Az alábbi parancs felsorolja a fürtben található összes szilánkot, valamint a szilánk állapotát.

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)
                }
        }
}

2. lépés

Adja ki az alábbi parancsot a szükséges szilánk eltávolításához a fürtből. A kiadást követően a kiegyenlítő gondoskodik a darabok eltávolításáról a leürítő szilánkcsomópontról, majd kiegyenlíti a megmaradt darabok elosztását a többi szilánkcsomópont között.

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)
                }
        }
}

3. lépés

Az ürítő szilánk állapotának ellenőrzéséhez adja ki újra ugyanazt a parancsot.

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

Meg kell várnunk, amíg az adatok kiürítése befejeződik. msg és state mezők megmutatják, hogy az adatok kiürítése befejeződött-e vagy sem, az alábbiak szerint

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

Az állapotot az sh.status() paranccsal is ellenőrizhetjük. Az eltávolítás után a szilánkos csomópont nem fog megjelenni a kimenetben. De ha a leürítés folyamatban van, a szilánkos csomópont ürítési állapota igaz lesz.

4. lépés

Folytassa a leürítés állapotának ellenőrzését a fenti paranccsal, amíg a szükséges szilánkot teljesen el nem távolítja.
A befejezés után a parancs kimenete tükrözi az üzenetet és a befejezett állapotot.

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

5. lépés

Végül ellenőriznünk kell a fürtben lévő maradék szilánkokat. Az állapot ellenőrzéséhez írja be: sh.status() vagy 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)
                }
        }
}

Itt láthatjuk, hogy az eltávolított szilánk már nincs jelen a szilánkok listájában.

A megosztás előnyei a replikációval szemben

  • A replikáció során az elsődleges csomópont kezeli az összes írási műveletet, míg a másodlagos kiszolgálóknak biztonsági másolatok karbantartására vagy csak olvasható műveletek kiszolgálására van szükség. De a replikakészletekkel együtt történő felosztás során a terhelés a kiszolgálók között oszlik meg.
  • Egyetlen replikakészlet 12 csomópontra korlátozódik, de nincs korlátozás a szilánkok számára.
  • A replikáció csúcskategóriás hardvert vagy vertikális skálázást igényel a nagy adatkészletek kezeléséhez, ami túl drága ahhoz képest, hogy további kiszolgálókat adnak hozzá a felosztáshoz.
  • A replikáció során az olvasási teljesítmény fokozható több szolga/másodlagos kiszolgáló hozzáadásával, míg a felosztásnál az olvasási és írási teljesítmény is javulni fog több szilánkos csomópont hozzáadásával.

Megosztási korlátozás

  • Az Sharded fürt nem támogatja az egyedi indexelést a szilánkok között, amíg az egyedi index előtagjaként nem szerepel a teljes shard kulcs.
  • A szilánkos gyűjtemény minden frissítési műveletének egy vagy több dokumentumon tartalmaznia kell a lekérdezésben a szilánkos kulcsot vagy az _id mezőt.
  • A gyűjtemények feldarabolhatók, ha méretük nem haladja meg a megadott küszöbértéket. Ez a küszöbérték az összes szilánkos kulcs átlagos mérete és a darabok mérete alapján becsülhető meg.
  • A megosztás a maximális gyűjteményméretre vagy a felosztások számára vonatkozó működési korlátozásokból áll.
  • A nem megfelelő szilánkos kulcsok kiválasztása a teljesítmény következményeihez vezet.

Következtetés

A MongoDB beépített felosztást kínál nagy adatbázisok megvalósításához a teljesítmény veszélyeztetése nélkül. Remélem, a fentiek segítenek a MongoDB felosztásának beállításában. Ezután érdemes megismerkednie néhány gyakran használt MongoDB-parancsgal.