@ avanti、@ MarkusWMalhbergに感謝します-コメントへの応答方法を熟考することで、私は正しい方向に進みました。これをまとめるのに少し時間がかかったので、構成について少し詳しく説明します。
概要
ユーザーエクスペリエンスに重点を置いて、読み取りと書き込みをユーザーの最も近くで実行できるようにするMongoデータベース構成を作成したいと考えています。
前提条件
- ユーザーはほとんどの場合、自分の地域でドキュメントを読み書きします。他の地域のデータへの読み取りの頻度が遅くてもかまいません。
- 各ドキュメントには、地域を示すキーが含まれています(わかりやすくするため)
シャーディングドキュメントの多くは、HA/DRに焦点を当てています。ユーザーエクスペリエンスと地域コンプライアンスにより、負荷分散ではなく地域性に重点が置かれています。
この例では、HA / DR、読み取り設定、および書き込みの懸念を完全に無視しますが、POCが成熟している場合は、これらに対処する必要があります。この例では、これらを無視して、目標であるローカルの読み取り/書き込みを明確に満たすようにしています。
参考資料
秘訣
私たちは知っています
- すべてのデータを利用できるように、1つのアプリケーションデータベースが必要です
- ユーザーがローカルで読み取り/書き込みできるようにするため、各ユーザーグループの近くにデータベースが必要です。レプリカセットが必要です
- 書き込みはプライマリレプリカセットノードに対してのみ行うことができるため、各ユーザーグループの隣にプライマリノードを取得するには、複数のレプリカが必要です。シャーディングされたクラスター
標準のReplicaSetとShardingの知識の範囲内で、この構成には2つの鍵があります。
- 地域的にローカルなReplicaSetノードに優先度を割り当てて、プライマリになるようにします。
- 場所を意識したシャードキーのタグ付けを使用して、データがローカルのシャードに書き込まれるようにします
シャードキーは何でもかまいません。効果的な負荷分散とは対照的に、ユーザーがローカルで読み取り/書き込みできることだけに関心があります。
各コレクションをシャーディングする必要があります。そうしないと、書き込みはシャードゼロになります。
必要な構成
構成
#!/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
テスト
sh.status()
を使用して、構成が正しいことを確認します 。シャードが正しく割り当てられ、タグが付けられ、地域のシャードキーが正しく割り当てられていることに注意してください。
[[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
}
正しいシャードとプライマリに書き込みが行われていることを確認します。各リージョンにレコードを作成します
db.users.insert({region:1, name:"us east user"})
db.users.insert({region:2, name:"us west user"})
各レプリカセットの各メンバーにログオンして、東のユーザーはUS-Eastシャードでのみ表示され、西のユーザーはUS-Westシャードでのみ表示されます。