gpt4 book ai didi

MongoDb区域副本集 - 每个区域的主节点?

转载 作者:IT老高 更新时间:2023-10-28 13:25:49 25 4
gpt4 key购买 nike

给定一个具有区域用户(区域为北美、欧洲、亚洲)的应用程序,您如何创建允许 HK 用户写入最近节点的副本集?

目标是香港的用户可以读写他们的本地节点,而不会遭受写入美国的延迟。我的假设是我可以在每个区域设置一个应用程序堆栈,通过副本集在所有区域之间共享数据,并且用户可以连接到他们最近的提供商(全局负载平衡)。

问题是副本集只有一个主节点,所有写入都必须到该节点。通过辅助和 NEAREST 提示可以直接读取数据,但我无法找到写入的解决方案。

这似乎是一个非常可靠的用例,应该处理它,但不能取得任何进展。解决方案、想法、指向某些来源的指针?

最佳答案

感谢@avanti,@MarkusWMalhberg - 思考如何回应评论将我推向了正确的方向。这需要一点时间来整理,所以我会有点冗长地解释配置。

概述

关注用户体验,我们希望创建一个 Mongo 数据库配置,允许在离用户最近的地方进行读写。

假设

  • 用户几乎总是在他们所在地区读写文档,并且不介意不频繁地读取其他地区数据的速度较慢。
  • 每个文档都包含一个指示其区域的键(为了简单/清晰)

大部分分片文档都侧重于 HA/DR。考虑到用户体验和区域合规性,重点是位置而不是负载分布。

此示例将完全忽略 HA/DR、读取首选项和写入问题,但如果 POC 成熟,则需要解决这些问题。该示例忽略了这些,以便清楚地满足目标:本地读/写。

引用文献

技巧

我们知道

  • 我们想要一个应用程序数据库,以便所有数据都可用
  • 我们希望用户在本地读/写,所以我们需要在每个用户组附近都有一个数据库;我们需要一个副本集
  • 只能对主副本集节点进行写入,因此,要获取每个用户组旁边的主节点,我们需要多个副本;分片集群

在标准的 ReplicaSet 和 Sharding 知识中,此配置有 2 个关键:

  • 为区域性本地 ReplicaSet 节点分配优先级以确保其成为主要节点。
  • 使用位置感知分片键标记确保数据写入本地分片

分片键可以是任何东西:与有效的负载共享相比,我们只关心用户能够在本地读/写。

每个集合都必须进行分片,否则写入将转到零分片。

所需配置

enter image description here

配置

#!/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() 验证我们的配置是否正确。注意分片分配正确,标签正确分配,区域分片键分配正确。

[starver@rakshasa 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 分片上查看西部用户。

关于MongoDb区域副本集 - 每个区域的主节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32555958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com