14.MongoDB系列之配置分片
阅读原文时间:2023年07月10日阅读:1
1. 启动服务器
1.1 启动配置服务器

配置服务器是集群的大脑,保存着关于每个服务器包含哪些数据的所有元数据,因此,必须首先创建配置服务器。

由于资源限制,在同一机器上启动三个进程

# mkdir /home/mongo/cs1
# mkdir /home/mongo/cs2
# mkdir /home/mongo/cs3
# mongod --configsvr --replSet configRS --bind_ip localhost --port 27038 --dbpath /home/mongo/cs1
# mongod --configsvr --replSet configRS --bind_ip localhost --port 27039 --dbpath /home/mongo/cs2
# mongod --configsvr --replSet configRS --bind_ip localhost --port 27040 --dbpath /home/mongo/cs3


# mongo --host localhost --port 27038
> rs.initiate(
{
 _id: "configRS",
 configsvr: true,
 members: [
    {_id: 0, host: "localhost:27038"},
    {_id: 1, host: "localhost:27039"},
    {_id: 2, host: "localhost:27040"}
 ]
})

可以看到,配置服务器副本集至此启动成功

configRS:PRIMARY> rs.isMaster()
{
        "hosts" : [
                "localhost:27038",
                "localhost:27039",
                "localhost:27040"
        ],
        "setName" : "configRS",
        "setVersion" : 1,
        "ismaster" : true,
        "secondary" : false
        ......
}
1.2 启动mongos路由进程

在3个配置服务器都运行后,启动一个mongos进程以供应用程序进行连接。为了确保高可用性,至少应该创建两个mongos进程。

# mongos --configdb configRS/localhost:27038,localhost:27039,localhost:27040 --bind_ip_all --port 27029 --fork --logpath /home/mongo/log.log
1.3 将副本集转换为分片

假设你已经创建了副本集,或参考之前文章8.MongoDB系列之创建副本集(一)进行创建副本集

连接副本集成员,并查看主节点

# mongo localhost:27018
study:PRIMARY> rs.isMaster()
{
        "hosts" : [
                "localhost:27018",
                "localhost:27019",
                "localhost:27020"
        ],
        "setName" : "study",
        "setVersion" : 2,
        "ismaster" : true
        .....
}

依次关闭从节点,并如下方式重新启动

mongod --replSet study --shardsvr --port 27019 --bind_ip localhost --dbpath /home/data/rs2
mongod --replSet study --shardsvr --port 27020 --bind_ip localhost --dbpath /home/data/rs3

现在将mongo shell连接到主节点,然后让其退位:

# mongo localhost:27018
study:PRIMARY> rs.stepDown()
# mongod --replSet study --shardsvr --port 27018 --bind_ip localhost --dbpath /home/data/rs1

现在可以将副本集作为分片添加到集群中了。通过mongos连接到admin数据库

# mongo localhost:27029/admin
> sh.addShard("study/localhost:27018,localhost:27019,localhost:27020")
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("62db816632b8e5b7cc0a5018")
  }
  shards:
        {  "_id" : "study",  "host" : "study/localhost:27018,localhost:27019,localhost:27020",  "state" : 1 }
  active mongoses:
        "4.2.6" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours:
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
        {  "_id" : "study",  "primary" : "study",  "partitioned" : false,  "version" : {  "uuid" : UUID("edc96711-21fd-4199-b47a-45a3b89c2f1c"),  "lastMod" : 1 } }

至此分片配置完成!

2. MongoDB如何追踪集群数据

每个mongos都必须能够根据一个片键来查找一个文档。MongoDB会将文档已数据块的形式进行分组,这些数据块是片键指定范围内的文档。块总是存在于分片上,因此MongoDB可以用较小的表来维护数据块跟分片的映射。一个块总是属于且仅属于一个块,因此,不能使用数组字段来作为片键。

2.1 块范围

块在shell中显示范围为$minKey和$maxKey, 块存储在config.chunks集合中

2.2 拆分块

各个分片的主节点mongod进程会跟踪他们当前的块,一旦达到某个阈值,就会检查该块是否需要拆分。

mongodb尝试分裂某个块却无法成功的过程被称为拆分风暴。防止拆分风暴的唯一方法是确保配置服务器尽可能正常运行。

3. 均衡器

均衡器负责是数据的迁移。它会定期检查分片之间是否存在不平衡,如果存在,就会对块进行迁移。

4. 变更流

变更流允许应用程序耿总数据库中数据的实时变更。通过跟踪oplog实现。跨分片集群的变更使用全局逻辑时钟来保持有序性。

欢迎关注公众号算法小生沈健的技术博客