sql >> Databáze >  >> NoSQL >> MongoDB

Sada regionálních replik MongoDb - primární uzel v každé oblasti?

Díky @avanti, @MarkusWMalhberg - přemýšlení o tom, jak reagovat na komentáře, mě posunulo správným směrem. Trvalo to trochu dát dohromady, takže budu trochu podrobně vysvětlovat konfiguraci.

Přehled

Se zaměřením na uživatelskou zkušenost chceme vytvořit konfiguraci databáze Mongo, která umožní čtení a zápis co nejblíže k uživateli.

Předpoklady

  • Uživatelé téměř vždy čtou a zapisují dokumenty ve své oblasti a nevadí jim, když jsou občasné čtení dat v jiné oblasti pomalejší.
  • Každý dokument obsahuje klíč, který označuje jeho oblast (pro jednoduchost/přehlednost)

Velká část shardingové dokumentace se zaměřuje na HA/DR. Díky uživatelské zkušenosti a regionální shodě se místo rozložení zátěže zaměřujeme na lokalitu.

Tento příklad bude zcela ignorovat HA/DR, předvolby čtení a zápisu, ale ty je třeba řešit, pokud je POC vyzrálý. Příklad je ignoruje ve prospěch jasnosti splnění cíle:místní čtení/zápis.

Odkazy

Triky

Víme

  • Chceme jednu aplikační databázi, aby byla k dispozici všechna data
  • Chceme, aby uživatelé mohli číst/zapisovat lokálně, takže potřebujeme databázi poblíž každé skupiny uživatelů; potřebujeme sadu replik
  • Zápisy lze provádět pouze do uzlů primární sady replik, takže abychom získali primární uzly vedle každé skupiny uživatelů, potřebujeme více replik; útržkovitý shluk

V rámci standardních znalostí ReplicaSet a Sharding existují 2 klíče k této konfiguraci:

  • Přiřaďte prioritu regionálně místnímu uzlu ReplicaSet, abyste zajistili, že se stane primárním.
  • Použijte značkování datového klíče s ohledem na polohu, abyste zajistili zápis dat do místních datových fragmentů

Sdílené klíče mohou být cokoli:zajímáme se pouze o to, aby uživatelé mohli číst/zapisovat lokálně na rozdíl od efektivního sdílení zátěže.

Každá sbírka bude muset být shardována, jinak budou zápisy nulové.

Požadovaná konfigurace

Konfigurace

#!/usr/bin/env bash

echo ">>> Clean up processes and files from previous runs"
echo ">>> killAll mongod mongos"
killall mongod mongos

echo ">>> Remove db files and logs"
rm -rf data
rm -rf log

# Create the common log directory
mkdir log

echo ">>> Start replica set for shard US-East"
mkdir -p data/shard-US-East/rsMemberEast data/shard-US-East/rsMemberWest
mongod --replSet shard-US-East --logpath "log/shard-US-East-rsMemberEast.log" --dbpath data/shard-US-East/rsMemberEast --port 37017 --fork --shardsvr --smallfiles
mongod --replSet shard-US-East --logpath "log/shard-US-East-rsMemberWest.log" --dbpath data/shard-US-East/rsMemberWest --port 37018 --fork --shardsvr --smallfiles

echo ">>> Sleep 15s to allow US-East replica set to start"
sleep 15

# The US-East replica set member is assigned priority 2 so that it becomes primary
echo ">>> Configure replica set for shard US-East"
mongo --port 37017 << 'EOF'
config = { _id: "shard-US-East", members:[
         { _id : 0, host : "localhost:37017", priority: 2 },
         { _id : 1, host : "localhost:37018" }]};
rs.initiate(config)
EOF

echo ">>> Start replica set for shard-US-West"
mkdir -p data/shard-US-West/rsMemberEast data/shard-US-West/rsMemberWest
mongod --replSet shard-US-West --logpath "log/shard-US-West-rsMemberEast.log" --dbpath data/shard-US-West/rsMemberEast --port 47017 --fork --shardsvr --smallfiles
mongod --replSet shard-US-West --logpath "log/shard-US-West-rsMemberWest.log" --dbpath data/shard-US-West/rsMemberWest --port 47018 --fork --shardsvr --smallfiles

echo ">>> Sleep 15s to allow US-West replica set to start"
sleep 15

# The US-West replica set member is assigned priority 2 so that it becomes primary
echo ">>> Configure replica set for shard-US-West"
mongo --port 47017 << 'EOF'
config = { _id: "shard-US-West", members:[
         { _id : 0, host : "localhost:47017" },
         { _id : 1, host : "localhost:47018", priority: 2 }]};
rs.initiate(config)
EOF

# Shard config servers: should be 3 and all must be up to deploy a shard cluster
# These are the mongos backing store for routing information
echo ">>> Start config servers"
mkdir -p data/config/config-us-east data/config/config-us-west data/config/config-redundant
mongod --logpath "log/cfg-us-east.log"   --dbpath data/config/config-us-east   --port 57040 --fork --configsvr --smallfiles
mongod --logpath "log/cfg-us-west.log"   --dbpath data/config/config-us-west   --port 57041 --fork --configsvr --smallfiles
mongod --logpath "log/cfg-redundant.log" --dbpath data/config/config-redundant --port 57042 --fork --configsvr --smallfiles

echo ">>> Sleep 5 to allow config servers to start and stabilize"
sleep 5

# All mongos's must point at the same config server, a coordinator dispatches writes to each
echo ">>> Start mongos"
mongos --logpath "log/mongos-us-east.log" --configdb localhost:57040,localhost:57041,localhost:57042 --port 27017 --fork
mongos --logpath "log/mongos-us-west.log" --configdb localhost:57040,localhost:57041,localhost:57042 --port 27018 --fork

echo ">>> Wait 60 seconds for the replica sets to stabilize"
sleep 60

# Enable sharding on the 'sales' database and 'sales.users' collection
# Every collection in 'sales' must be sharded or the writes will go to shard 0
# Add a shard tag so we can associate shard keys with the tag (region)
# Shard tag range main and max cannot be the same so we use a region id for US-East = 1
# and US-West = 2. sh.addTagRange() is inclusive of minKey and exclusive of maxKey.
# We only need to configure one mongos - config will be propogated to all mongos through
# the config server
echo ">>> Add shards to mongos"
mongo --port 27017 <<'EOF'
db.adminCommand( { addshard : "shard-US-East/"+"localhost:37017" } );
db.adminCommand( { addshard : "shard-US-West/"+"localhost:47017" } );

db.adminCommand({enableSharding: "sales"})
db.adminCommand({shardCollection: "sales.users", key: {region:1}});

sh.addShardTag("shard-US-East", "US-East")
sh.addShardTag("shard-US-West", "US-West")
sh.addTagRange("sales.users", { region: 1 }, { region: 2 }, "US-East")
sh.addTagRange("sales.users", { region: 2 }, { region: 3 }, "US-West")
EOF

Testování

Ověřte správnost naší konfigurace pomocí sh.status() . Úlomky poznámek jsou správně přiřazeny a značky a regionální zlomkové klíče jsou správně přiřazeny.

[[email protected] RegionalSharding 14:38:50]$ mongo --port 27017 sales
...
rakshasa(mongos-3.0.5)[mongos] sales> sh.status()
  sharding version: {
    "_id": 1,
    "minCompatibleVersion": 5,
    "currentVersion": 6,
    "clusterId": ObjectId("55fdddc5746e30dc3651cda4")
  }
  shards:
    {  "_id": "shard-US-East",  "host": "shard-US-East/localhost:37017,localhost:37018",  "tags": [   "US-East" ] }
    {  "_id": "shard-US-West",  "host": "shard-US-West/localhost:47017,localhost:47018",  "tags": [   "US-West" ] }
  balancer:
    Currently enabled:  yes
    Currently running:  no
    Failed balancer rounds in last 5 attempts:  0
    Migration Results for the last 24 hours: 
        1 : Success
  databases:
    {  "_id": "admin",  "partitioned": false,  "primary": "config" }
    {  "_id": "test",  "partitioned": false,  "primary": "shard-US-East" }
    {  "_id": "sales",  "partitioned": true,  "primary": "shard-US-East" }
    sales.users
      shard key: { "region": 1 }
      chunks:
        shard-US-East: 2
        shard-US-West: 1
        { "region": { "$minKey" : 1 } } -> { "region": 1 } on: shard-US-East Timestamp(2, 1) 
        { "region": 1 } -> { "region": 2 } on: shard-US-East Timestamp(1, 3) 
        { "region": 2 } -> { "region": { "$maxKey" : 1 } } on: shard-US-West Timestamp(2, 0) 
        tag: US-East  {
  "region": 1
} -> {
  "region": 2
}
        tag: US-West  {
  "region": 2
} -> {
  "region": 3
}

Ověřte, zda jsou zápisy provedeny na správný fragment a primární. Vytvořte záznam v každé oblasti

db.users.insert({region:1, name:"us east user"})
db.users.insert({region:2, name:"us west user"})

Můžete se přihlásit ke každému členovi každé sady replik a zobrazit východního uživatele pouze na datovém fragmentu US-East a západního uživatele pouze na datovém fragmentu US-West.



  1. MongoDB Projekce dílčího dokumentu

  2. Uvnitř architektury Santander's Near Real-Time Data Ingest Architecture (část 2)

  3. Jak ConnectionMultiplexer řeší odpojení?

  4. Může mongo vrátit dokumenty s prázdnými/chybějícími poli na konci ve vzestupném pořadí?