MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Ensemble de réplicas régionaux MongoDb - nœud principal dans chaque région ?

Merci @avanti, @MarkusWMalhberg - réfléchir à la façon de répondre aux commentaires m'a poussé dans la bonne direction. Cela a pris un peu de temps à assembler, donc je serai un peu verbeux en expliquant la configuration.

Aperçu

En nous concentrant sur l'expérience utilisateur, nous souhaitons créer une configuration de base de données Mongo qui permette aux lectures et aux écritures de se produire au plus près de l'utilisateur.

Hypothèses

  • Les utilisateurs lisent et écrivent presque toujours des documents dans leur région et cela ne les dérange pas si les lectures peu fréquentes des données d'une autre région sont plus lentes.
  • Chaque document contient une clé qui indique sa région (pour plus de simplicité/clarté)

Une grande partie de la documentation de partitionnement se concentre sur HA/DR. Avec l'expérience utilisateur et la conformité régionale, l'accent est mis sur la localité plutôt que sur la répartition de la charge.

Cet exemple ignorera complètement HA/DR, les préférences de lecture et les problèmes d'écriture, mais ceux-ci doivent être résolus si le POC est arrivé à maturité. L'exemple les ignore au profit de la clarté pour atteindre l'objectif :lectures/écritures locales.

Références

Astuces

Nous savons

  • Nous voulons une seule base de données d'applications pour que toutes les données soient disponibles
  • Nous voulons que les utilisateurs puissent lire/écrire localement, nous avons donc besoin d'une base de données à proximité de chaque groupe d'utilisateurs ; nous avons besoin d'un jeu de répliques
  • Les écritures ne peuvent être effectuées que sur les nœuds du jeu de réplicas principaux. Par conséquent, pour obtenir des nœuds principaux à côté de chaque groupe d'utilisateurs, nous avons besoin de plusieurs réplicas ; un cluster fragmenté

Dans les connaissances standard de ReplicaSet et Sharding, il existe 2 clés pour cette configuration :

  • Attribuez une priorité au nœud ReplicaSet régional pour vous assurer qu'il devienne principal.
  • Utilisez le balisage de clé de partition sensible à l'emplacement pour vous assurer que les données sont écrites sur des partitions locales

Les clés de partage peuvent être n'importe quoi :nous ne nous préoccupons que de la possibilité pour les utilisateurs de lire/écrire localement, contrairement à un partage de charge efficace.

Chaque collection devra être fragmentée, ou les écritures iront au fragment zéro.

Configuration souhaitée

Le paramétrage

#!/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

Test

Vérifiez que notre configuration est correcte avec sh.status() . Les partitions de note sont correctement attribuées et les balises, et les clés de partition régionales sont correctement attribuées.

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

Vérifiez que les écritures sont effectuées sur le bon fragment et le bon primaire.Créez un enregistrement dans chaque région

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

Vous pouvez vous connecter à chaque membre de chaque jeu de répliques et voir l'utilisateur est uniquement sur la partition US-East et l'utilisateur ouest uniquement sur la partition US-West.