阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MongoDB的集群模式–Sharding(分片)

387次阅读
没有评论

共计 42941 个字符,预计需要花费 108 分钟才能阅读完成。

分片是数据跨多台机器存储,MongoDB 使用分片来支持具有非常大的数据集和高吞吐量操作的部署。

具有大型数据集或高吞吐量应用程序的数据库系统可能会挑战单个服务器的容量。例如,高查询率会耗尽服务器的 CPU 容量。工作集大小大于系统的 RAM 会强调磁盘驱动器的 I / O 容量。

有两种解决系统增长的方法:垂直和水平缩放。

垂直扩展 涉及增加单个服务器的容量,例如使用更强大的 CPU,添加更多 RAM 或增加存储空间量。可用技术的局限性可能会限制单个机器对于给定工作负载而言足够强大。此外,基于云的提供商基于可用的硬件配置具有硬性上限。结果,垂直缩放有实际的最大值。

水平扩展 涉及划分系统数据集并加载多个服务器,添加其他服务器以根据需要增加容量。虽然单个机器的总体速度或容量可能不高,但每台机器处理整个工作负载的子集,可能提供比单个高速大容量服务器更高的效率。扩展部署容量只需要根据需要添加额外的服务器,这可能比单个机器的高端硬件的总体成本更低。权衡是基础架构和部署维护的复杂性增加。

MongoDB 支持 通过 分片进行 水平扩展

一、组件

MongoDB 的集群模式 --Sharding(分片)

  • shard:每个分片包含分片数据的子集。每个分片都可以部署为 副本集(replica set)。可以分片,不分片的数据存于主分片服务器上。部署为 3 成员副本集
  • mongos:mongos 充当查询路由器,提供客户端应用程序和分片集群之间的接口。可以部署多个 mongos 路由器。部署 1 个或者多个 mongos
  • config servers:配置服务器存储群集的元数据和配置设置。从 MongoDB 3.4 开始,必须将配置服务器 部署为 3 成员副本集

 注意:应用程序或者客户端必须要连接 mongos 才能与集群的数据进行交互,永远 不应 连接到单个分片以执行读取或写入操作

shard 的 replica set 的架构图:

MongoDB 的集群模式 --Sharding(分片)

config servers 的 replica set 的架构图:

MongoDB 的集群模式 --Sharding(分片)

 

 分片策略

1、散列分片

  • 使用散列索引在共享群集中分区数据。散列索引计算单个字段的哈希值作为索引值; 此值用作分片键。
  • 使用散列索引解析查询时,MongoDB 会自动计算哈希值。应用程序也不会需要计算哈希值。
  • 基于散列值的数据分布有助于更均匀的数据分布,尤其是在分片键单调变化的数据集中。

MongoDB 的集群模式 --Sharding(分片)

 

 2、范围分片

  • 基于分片键值将数据分成范围。然后根据分片键值为每个块分配一个范围。
  • mongos 可以将操作仅路由到包含所需数据的分片。
  • 分片键的规划很重要,可能导致数据不能均匀分布。

MongoDB 的集群模式 --Sharding(分片)

 二、部署

1、环境说明

服务器名称 IP 地址 操作系统版本 MongoDB 版本 配置服务器 (Config Server) 端口 分片服务器 1(Shard Server 1 分片服务器 2(Shard Server 2) 分片服务器 3(Shard Server 3) 功能
mongo1.example.net 10.10.18.10 CentOS7.5 4.0 27027(Primary 27017(Primary 27018(Arbiter 27019(Secondary 配置服务器和分片服务器
mongo2.example.net 10.10.18.11 Centos7.5 4.0 27027(Secondary 27017(Secondary
27018(Primary 27019(Arbiter 配置服务器和分片服务器
mongo3.example.net 10.10.18.12 Centos7.5 4.0 27027(Secondary 27017(Arbiter 27018(Secondary 27019(Primary 配置服务器和分片服务器
mongos.example.net 192.168.11.10 Centos7.5 4.0   mongos 的端口:27017     mongos

官方推荐配置中使用逻辑 DNS,所以该文档中,将服务器名称和 IP 地址的 DNS 映射关系写入到各服务器的 /etc/hosts 文件中

2、部署 MongoDB

环境中 4 台服务器的 MongoDB 的安装部署,详见:MongoDB 安装

创建环境需要的目录:

mkdir -p /data/mongodb/data/{configServer,shard1,shard2,shard3}
mkdir -p /data/mongodb/{log,pid}

3、创建配置服务器(Config Server)的 Replica Set(副本集)

3 台服务器上配置文件内容: /data/mongodb/configServer.conf

mongo1.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/configServer.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/configServer"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/configServer.pid"
net:
   bindIp: mongo1.example.net
   port: 27027
replication:
   replSetName: cs0
sharding:
  clusterRole: configsvr

mongo2.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/configServer.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/configServer"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/configServer.pid"
net:
   bindIp: mongo2.example.net
   port: 27027
replication:
   replSetName: cs0
sharding:
  clusterRole: configsvr

mongo3.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/configServer.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/configServer"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/configServer.pid"
net:
   bindIp: mongo3.example.net
   port: 27027
replication:
   replSetName: cs0
sharding:
  clusterRole: configsvr

启动三台服务器 Config Server

mongod -f /data/mongodb/configServer.conf

连接到其中一个 Config Server

mongo --host mongo1.example.net --port 27027

结果:

MongoDB 的集群模式 --Sharding(分片)MongoDB 的集群模式 --Sharding(分片)

 1 MongoDB shell version v4.0.10
 2 connecting to: mongodb://mongo1.example.net:27027/?gssapiServiceName=mongodb
 3 Implicit session: session {"id" : UUID("1a4d4252-11d0-40bb-90da-f144692be88d") }
 4 MongoDB server version: 4.0.10
 5 Server has startup warnings: 
 6 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] 
 7 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
 8 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
 9 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
10 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] 
11 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] 
12 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
13 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
14 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] 
15 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
16 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
17 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] 
18 >

View Code

配置 Replica Set

rs.initiate(
  {_id: "cs0",
    configsvr: true,
    members: [{ _id : 0, host : "mongo1.example.net:27027" },
      {_id : 1, host : "mongo2.example.net:27027" },
      {_id : 2, host : "mongo3.example.net:27027" }
    ]
  }
)

结果:

{
        “ok” : 1,
        “operationTime” : Timestamp(1560493908, 1),
        “$gleStats” : {
                “lastOpTime” : Timestamp(1560493908, 1),
                “electionId” : ObjectId(“000000000000000000000000”)
        },
        “lastCommittedOpTime” : Timestamp(0, 0),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1560493908, 1),
                “signature” : {
                        “hash” : BinData(0,”AAAAAAAAAAAAAAAAAAAAAAAAAAA=”),
                        “keyId” : NumberLong(0)
                }
        }
}

查看 Replica Set 的状态

cs0:PRIMARY> rs.status()

结果:  可以看出三个服务器: 1 个 Primary,2 个 Secondary

{
        “set” : “cs0”,
        “date” : ISODate(“2019-06-14T06:33:31.348Z”),
        “myState” : 1,
        “term” : NumberLong(1),
        “syncingTo” : “”,
        “syncSourceHost” : “”,
        “syncSourceId” : -1,
        “configsvr” : true,
        “heartbeatIntervalMillis” : NumberLong(2000),
        “optimes” : {
                “lastCommittedOpTime” : {
                        “ts” : Timestamp(1560494006, 1),
                        “t” : NumberLong(1)
                },
                “readConcernMajorityOpTime” : {
                        “ts” : Timestamp(1560494006, 1),
                        “t” : NumberLong(1)
                },
                “appliedOpTime” : {
                        “ts” : Timestamp(1560494006, 1),
                        “t” : NumberLong(1)
                },
                “durableOpTime” : {
                        “ts” : Timestamp(1560494006, 1),
                        “t” : NumberLong(1)
                }
        },
        “lastStableCheckpointTimestamp” : Timestamp(1560493976, 1),
        “members” : [
                {
                        “_id” : 0,
                        “name” : “mongo1.example.net:27027”,
                        “health” : 1,
                        “state” : 1,
                        “stateStr” : “PRIMARY”,
                        “uptime” : 277,
                        “optime” : {
                                “ts” : Timestamp(1560494006, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDate” : ISODate(“2019-06-14T06:33:26Z”),
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “could not find member to sync from”,
                        “electionTime” : Timestamp(1560493919, 1),
                        “electionDate” : ISODate(“2019-06-14T06:31:59Z”),
                        “configVersion” : 1,
                        “self” : true,
                        “lastHeartbeatMessage” : “”
                },
                {
                        “_id” : 1,
                        “name” : “mongo2.example.net:27027”,
                        “health” : 1,
                        “state” : 2,
                        “stateStr” : “SECONDARY”,
                        “uptime” : 102,
                        “optime” : {
                                “ts” : Timestamp(1560494006, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDurable” : {
                                “ts” : Timestamp(1560494006, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDate” : ISODate(“2019-06-14T06:33:26Z”),
                        “optimeDurableDate” : ISODate(“2019-06-14T06:33:26Z”),
                        “lastHeartbeat” : ISODate(“2019-06-14T06:33:29.385Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-14T06:33:29.988Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “mongo1.example.net:27027”,
                        “syncSourceHost” : “mongo1.example.net:27027”,
                        “syncSourceId” : 0,
                        “infoMessage” : “”,
                        “configVersion” : 1
                },
                {
                        “_id” : 2,
                        “name” : “mongo3.example.net:27027”,
                        “health” : 1,
                        “state” : 2,
                        “stateStr” : “SECONDARY”,
                        “uptime” : 102,
                        “optime” : {
                                “ts” : Timestamp(1560494006, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDurable” : {
                                “ts” : Timestamp(1560494006, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDate” : ISODate(“2019-06-14T06:33:26Z”),
                        “optimeDurableDate” : ISODate(“2019-06-14T06:33:26Z”),
                        “lastHeartbeat” : ISODate(“2019-06-14T06:33:29.384Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-14T06:33:29.868Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “mongo1.example.net:27027”,
                        “syncSourceHost” : “mongo1.example.net:27027”,
                        “syncSourceId” : 0,
                        “infoMessage” : “”,
                        “configVersion” : 1
                }
        ],
        “ok” : 1,
        “operationTime” : Timestamp(1560494006, 1),
        “$gleStats” : {
                “lastOpTime” : Timestamp(1560493908, 1),
                “electionId” : ObjectId(“7fffffff0000000000000001”)
        },
        “lastCommittedOpTime” : Timestamp(1560494006, 1),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1560494006, 1),
                “signature” : {
                        “hash” : BinData(0,”AAAAAAAAAAAAAAAAAAAAAAAAAAA=”),
                        “keyId” : NumberLong(0)
                }
        }
}

创建管理用户

use admin
db.createUser(
  {user: "myUserAdmin",
    pwd: "abc123",
    roles: [{role: "userAdminAnyDatabase", db: "admin" },"readWriteAnyDatabase"]
  }
)

开启 Config Server 的登录验证和内部验证

使用 Keyfiles 进行内部认证,在其中一台服务器上创建 Keyfiles

openssl rand -base64 756 > /data/mongodb/keyfile
chmod 400  /data/mongodb/keyfile

将这个 keyfile 文件分发到其它的三台服务器上,并保证权限 400

/data/mongodb/configServer.conf  配置文件中开启认证

security:
   keyFile: "/data/mongodb/keyfile"
   clusterAuthMode: "keyFile"
   authorization: "enabled"

然后 依次关闭 2 个 Secondary,在关闭 Primary

mongod -f /data/mongodb/configServer.conf --shutdown

依次 开启 Primary 和两个 Secondary

mongod -f /data/mongodb/configServer.conf 

使用用户密码登录 mongo

mongo --host mongo1.example.net --port 27027 -u myUserAdmin --authenticationDatabase "admin" -p 'abc123'

注意:由于刚创建用户的时候没有给该用户管理集群的权限,所有此时登录后,能查看所有数据库,但是不能查看集群的状态信息。

cs0:PRIMARY> rs.status()
{
        “operationTime” : Timestamp(1560495861, 1),
        “ok” : 0,
        “errmsg” : “not authorized on admin to execute command {replSetGetStatus: 1.0, lsid: { id: UUID(\”59dd4dc0-b34f-43b9-a341-a2f43ec1dcfa\”) }, $clusterTime: {clusterTime: Timestamp(1560495849, 1), signature: {hash: BinData(0, A51371EC5AA54BB1B05ED9342BFBF03CBD87F2D9), keyId: 6702270356301807629 } }, $db: \”admin\” }”,
        “code” : 13,
        “codeName” : “Unauthorized”,
        “$gleStats” : {
                “lastOpTime” : Timestamp(0, 0),
                “electionId” : ObjectId(“7fffffff0000000000000002”)
        },
        “lastCommittedOpTime” : Timestamp(1560495861, 1),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1560495861, 1),
                “signature” : {
                        “hash” : BinData(0,”3UkTpXxyU8WI1TyS+u5vgewueGA=”),
                        “keyId” : NumberLong(“6702270356301807629”)
                }
        }
}
cs0:PRIMARY> show dbs
admin  0.000GB
config  0.000GB
local  0.000GB

赋值该用户具有集群的管理权限

use admin
db.system.users.find() #查看当前的用户信息 db.grantRolesToUser(
"myUserAdmin", ["clusterAdmin"])

查看集群信息

cs0:PRIMARY> rs.status()
{
        “set” : “cs0”,
        “date” : ISODate(“2019-06-14T07:18:20.223Z”),
        “myState” : 1,
        “term” : NumberLong(2),
        “syncingTo” : “”,
        “syncSourceHost” : “”,
        “syncSourceId” : -1,
        “configsvr” : true,
        “heartbeatIntervalMillis” : NumberLong(2000),
        “optimes” : {
                “lastCommittedOpTime” : {
                        “ts” : Timestamp(1560496690, 1),
                        “t” : NumberLong(2)
                },
                “readConcernMajorityOpTime” : {
                        “ts” : Timestamp(1560496690, 1),
                        “t” : NumberLong(2)
                },
                “appliedOpTime” : {
                        “ts” : Timestamp(1560496690, 1),
                        “t” : NumberLong(2)
                },
                “durableOpTime” : {
                        “ts” : Timestamp(1560496690, 1),
                        “t” : NumberLong(2)
                }
        },
        “lastStableCheckpointTimestamp” : Timestamp(1560496652, 1),
        “members” : [
                {
                        “_id” : 0,
                        “name” : “mongo1.example.net:27027”,
                        “health” : 1,
                        “state” : 1,
                        “stateStr” : “PRIMARY”,
                        “uptime” : 1123,
                        “optime” : {
                                “ts” : Timestamp(1560496690, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDate” : ISODate(“2019-06-14T07:18:10Z”),
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “”,
                        “electionTime” : Timestamp(1560495590, 1),
                        “electionDate” : ISODate(“2019-06-14T06:59:50Z”),
                        “configVersion” : 1,
                        “self” : true,
                        “lastHeartbeatMessage” : “”
                },
                {
                        “_id” : 1,
                        “name” : “mongo2.example.net:27027”,
                        “health” : 1,
                        “state” : 2,
                        “stateStr” : “SECONDARY”,
                        “uptime” : 1113,
                        “optime” : {
                                “ts” : Timestamp(1560496690, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDurable” : {
                                “ts” : Timestamp(1560496690, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDate” : ISODate(“2019-06-14T07:18:10Z”),
                        “optimeDurableDate” : ISODate(“2019-06-14T07:18:10Z”),
                        “lastHeartbeat” : ISODate(“2019-06-14T07:18:18.974Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-14T07:18:19.142Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “mongo1.example.net:27027”,
                        “syncSourceHost” : “mongo1.example.net:27027”,
                        “syncSourceId” : 0,
                        “infoMessage” : “”,
                        “configVersion” : 1
                },
                {
                        “_id” : 2,
                        “name” : “mongo3.example.net:27027”,
                        “health” : 1,
                        “state” : 2,
                        “stateStr” : “SECONDARY”,
                        “uptime” : 1107,
                        “optime” : {
                                “ts” : Timestamp(1560496690, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDurable” : {
                                “ts” : Timestamp(1560496690, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDate” : ISODate(“2019-06-14T07:18:10Z”),
                        “optimeDurableDate” : ISODate(“2019-06-14T07:18:10Z”),
                        “lastHeartbeat” : ISODate(“2019-06-14T07:18:18.999Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-14T07:18:18.998Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “mongo2.example.net:27027”,
                        “syncSourceHost” : “mongo2.example.net:27027”,
                        “syncSourceId” : 1,
                        “infoMessage” : “”,
                        “configVersion” : 1
                }
        ],
        “ok” : 1,
        “operationTime” : Timestamp(1560496690, 1),
        “$gleStats” : {
                “lastOpTime” : {
                        “ts” : Timestamp(1560496631, 1),
                        “t” : NumberLong(2)
                },
                “electionId” : ObjectId(“7fffffff0000000000000002”)
        },
        “lastCommittedOpTime” : Timestamp(1560496690, 1),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1560496690, 1),
                “signature” : {
                        “hash” : BinData(0,”lHiVw7WeO81npTi2IMW16reAN84=”),
                        “keyId” : NumberLong(“6702270356301807629”)
                }
        }
}

4、部署分片服务器 1(Shard1)以及 Replica Set(副本集)

3 台服务器上配置文件内容: /data/mongodb/shard1.conf

mongo1.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard1.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard1"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard1.pid"
net:
   bindIp: mongo1.example.net
   port: 27017
replication:
   replSetName: "shard1"
sharding:
   clusterRole: shardsvr

mongo2.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard1.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard1"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard1.pid"
net:
   bindIp: mongo2.example.net
   port: 27017
replication:
   replSetName: "shard1"
sharding:
   clusterRole: shardsvr

mongo3.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard1.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard1"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard1.pid"
net:
   bindIp: mongo3.example.net
   port: 27017
replication:
   replSetName: "shard1"
sharding:
   clusterRole: shardsvr

开启三台服务器上 Shard

mongod -f /data/mongodb/shard1.conf

连接 Primary 服务器的 Shard 的副本集

mongo --host mongo1.example.net --port 27017

结果

MongoDB shell version v4.0.10
connecting to: mongodb://mongo1.example.net:27017/?gssapiServiceName=mongodb
Implicit session: session {“id” : UUID(“91e76384-cdae-411f-ab88-b7a8bd4555d1”) }
MongoDB server version: 4.0.10
Server has startup warnings:
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten]
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten]
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten]
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten]
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2019-06-14T15:32:39.243+0800 I CONTROL  [initandlisten]
>

配置 Replica Set

rs.initiate(
  {_id : "shard1",
    members: [{ _id : 0, host : "mongo1.example.net:27017",priority:2 },
      {_id : 1, host : "mongo2.example.net:27017",priority:1 },
      {_id : 2, host : "mongo3.example.net:27017",arbiterOnly:true }
    ]
  }
)

注意:优先级 priority 的值越大,越容易选举成为 Primary

查看 Replica Set 的状态:

shard1:PRIMARY> rs.status()
{
        “set” : “shard1”,
        “date” : ISODate(“2019-06-20T01:33:21.809Z”),
        “myState” : 1,
        “term” : NumberLong(2),
        “syncingTo” : “”,
        “syncSourceHost” : “”,
        “syncSourceId” : -1,
        “heartbeatIntervalMillis” : NumberLong(2000),
        “optimes” : {
                “lastCommittedOpTime” : {
                        “ts” : Timestamp(1560994393, 1),
                        “t” : NumberLong(2)
                },
                “readConcernMajorityOpTime” : {
                        “ts” : Timestamp(1560994393, 1),
                        “t” : NumberLong(2)
                },
                “appliedOpTime” : {
                        “ts” : Timestamp(1560994393, 1),
                        “t” : NumberLong(2)
                },
                “durableOpTime” : {
                        “ts” : Timestamp(1560994393, 1),
                        “t” : NumberLong(2)
                }
        },
        “lastStableCheckpointTimestamp” : Timestamp(1560994373, 1),
        “members” : [
                {
                        “_id” : 0,
                        “name” : “mongo1.example.net:27017”,
                        “health” : 1,
                        “state” : 1,
                        “stateStr” : “PRIMARY”,
                        “uptime” : 43,
                        “optime” : {
                                “ts” : Timestamp(1560994393, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDate” : ISODate(“2019-06-20T01:33:13Z”),
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “could not find member to sync from”,
                        “electionTime” : Timestamp(1560994371, 1),
                        “electionDate” : ISODate(“2019-06-20T01:32:51Z”),
                        “configVersion” : 1,
                        “self” : true,
                        “lastHeartbeatMessage” : “”
                },
                {
                        “_id” : 1,
                        “name” : “mongo2.example.net:27017”,
                        “health” : 1,
                        “state” : 2,
                        “stateStr” : “SECONDARY”,
                        “uptime” : 36,
                        “optime” : {
                                “ts” : Timestamp(1560994393, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDurable” : {
                                “ts” : Timestamp(1560994393, 1),
                                “t” : NumberLong(2)
                        },
                        “optimeDate” : ISODate(“2019-06-20T01:33:13Z”),
                        “optimeDurableDate” : ISODate(“2019-06-20T01:33:13Z”),
                        “lastHeartbeat” : ISODate(“2019-06-20T01:33:19.841Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-20T01:33:21.164Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “mongo1.example.net:27017”,
                        “syncSourceHost” : “mongo1.example.net:27017”,
                        “syncSourceId” : 0,
                        “infoMessage” : “”,
                        “configVersion” : 1
                },
                {
                        “_id” : 2,
                        “name” : “mongo3.example.net:27017”,
                        “health” : 1,
                        “state” : 7,
                        “stateStr” : “ARBITER”,
                        “uptime” : 32,
                        “lastHeartbeat” : ISODate(“2019-06-20T01:33:19.838Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-20T01:33:20.694Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “”,
                        “configVersion” : 1
                }
        ],
        “ok” : 1
}

结果:  可以看出三个服务器: 1 个 Primary,1 个 Secondary,1 一个 Arbiter

创建管理用户

use admin
db.createUser(
  {user: "myUserAdmin",
    pwd: "abc123",
    roles: [{role: "userAdminAnyDatabase", db: "admin" },"readWriteAnyDatabase","clusterAdmin"]
  }
)

开启 Shard1 的登录验证和内部验证

security:
   keyFile: "/data/mongodb/keyfile"
   clusterAuthMode: "keyFile"
   authorization: "enabled"

然后 依次关闭 Arbiter、Secondary、Primary

mongod -f /data/mongodb/shard1.conf --shutdown

依次 开启 Primary 和两个 Secondary

mongod -f /data/mongodb/shard1.conf 

使用用户密码登录 mongo

mongo --host mongo1.example.net --port 27017 -u myUserAdmin --authenticationDatabase "admin" -p 'abc123'

5、部署分片服务器 2(Shard2)以及 Replica Set(副本集)

3 台服务器上配置文件内容: /data/mongodb/shard2.conf

mongo1.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard2.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard2"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard2.pid"
net:
   bindIp: mongo1.example.net
   port: 27018
replication:
   replSetName: "shard2"
sharding:
   clusterRole: shardsvr

mongo2.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard2.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard2"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard2.pid"
net:
   bindIp: mongo2.example.net
   port: 27018
replication:
   replSetName: "shard2"
sharding:
   clusterRole: shardsvr

mongo3.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard2.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard2"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard2.pid"
net:
   bindIp: mongo3.example.net
   port: 27018
replication:
   replSetName: "shard2"
sharding:
   clusterRole: shardsvr

 

开启三台服务器上 Shard

mongod -f /data/mongodb/shard2.conf

连接 Primary 服务器的 Shard 的副本集

mongo --host mongo2.example.net --port 27018

配置 Replica Set(注意:三个服务器的角色发生了改变)

rs.initiate(
  {_id : "shard2",
    members: [{ _id : 0, host : "mongo1.example.net:27018",arbiterOnly:true },
      {_id : 1, host : "mongo2.example.net:27018",priority:2 },
      {_id : 2, host : "mongo3.example.net:27018",priority:1 }
    ]
  }
)

查看 Replica Set 的状态:

shard2:PRIMARY> rs.status()
{
        “set” : “shard2”,
        “date” : ISODate(“2019-06-20T01:59:08.996Z”),
        “myState” : 1,
        “term” : NumberLong(1),
        “syncingTo” : “”,
        “syncSourceHost” : “”,
        “syncSourceId” : -1,
        “heartbeatIntervalMillis” : NumberLong(2000),
        “optimes” : {
                “lastCommittedOpTime” : {
                        “ts” : Timestamp(1560995943, 1),
                        “t” : NumberLong(1)
                },
                “readConcernMajorityOpTime” : {
                        “ts” : Timestamp(1560995943, 1),
                        “t” : NumberLong(1)
                },
                “appliedOpTime” : {
                        “ts” : Timestamp(1560995943, 1),
                        “t” : NumberLong(1)
                },
                “durableOpTime” : {
                        “ts” : Timestamp(1560995943, 1),
                        “t” : NumberLong(1)
                }
        },
        “lastStableCheckpointTimestamp” : Timestamp(1560995913, 1),
        “members” : [
                {
                        “_id” : 0,
                        “name” : “mongo1.example.net:27018”,
                        “health” : 1,
                        “state” : 7,
                        “stateStr” : “ARBITER”,
                        “uptime” : 107,
                        “lastHeartbeat” : ISODate(“2019-06-20T01:59:08.221Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-20T01:59:07.496Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “”,
                        “configVersion” : 1
                },
                {
                        “_id” : 1,
                        “name” : “mongo2.example.net:27018”,
                        “health” : 1,
                        “state” : 1,
                        “stateStr” : “PRIMARY”,
                        “uptime” : 412,
                        “optime” : {
                                “ts” : Timestamp(1560995943, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDate” : ISODate(“2019-06-20T01:59:03Z”),
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “could not find member to sync from”,
                        “electionTime” : Timestamp(1560995852, 1),
                        “electionDate” : ISODate(“2019-06-20T01:57:32Z”),
                        “configVersion” : 1,
                        “self” : true,
                        “lastHeartbeatMessage” : “”
                },
                {
                        “_id” : 2,
                        “name” : “mongo3.example.net:27018”,
                        “health” : 1,
                        “state” : 2,
                        “stateStr” : “SECONDARY”,
                        “uptime” : 107,
                        “optime” : {
                                “ts” : Timestamp(1560995943, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDurable” : {
                                “ts” : Timestamp(1560995943, 1),
                                “t” : NumberLong(1)
                        },
                        “optimeDate” : ISODate(“2019-06-20T01:59:03Z”),
                        “optimeDurableDate” : ISODate(“2019-06-20T01:59:03Z”),
                        “lastHeartbeat” : ISODate(“2019-06-20T01:59:08.220Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-20T01:59:08.716Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “mongo2.example.net:27018”,
                        “syncSourceHost” : “mongo2.example.net:27018”,
                        “syncSourceId” : 1,
                        “infoMessage” : “”,
                        “configVersion” : 1
                }
        ],
        “ok” : 1,
        “operationTime” : Timestamp(1560995943, 1),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1560995943, 1),
                “signature” : {
                        “hash” : BinData(0,”AAAAAAAAAAAAAAAAAAAAAAAAAAA=”),
                        “keyId” : NumberLong(0)
                }
        }
}

结果:  可以看出三个服务器: 1 个 Primary,1 个 Secondary,1 一个 Arbiter

配置登录认证的用户请按照 Shard1 的步骤

 

6、部署分片服务器 3(Shard3)以及 Replica Set(副本集)

3 台服务器上配置文件内容: /data/mongodb/shard3.conf

mongo1.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard3.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard3"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard3.pid"
net:
   bindIp: mongo1.example.net
   port: 27019
replication:
   replSetName: "shard3"
sharding:
   clusterRole: shardsvr

mongo2.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard3.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard3"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard3.pid"
net:
   bindIp: mongo2.example.net
   port: 27019
replication:
   replSetName: "shard3"
sharding:
   clusterRole: shardsvr

mongo3.example.net 服务器上

systemLog:
   destination: file
   path: "/data/mongodb/log/shard3.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/shard3"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/shard3.pid"
net:
   bindIp: mongo3.example.net
   port: 27019
replication:
   replSetName: "shard3"
sharding:
   clusterRole: shardsvr

开启三台服务器上 Shard

mongod -f /data/mongodb/shard3.conf

连接 Primary 服务器的 Shard 的副本集

mongo --host mongo3.example.net --port 27019

配置 Replica Set(注意:三个服务器的角色发生了改变)

rs.initiate(
  {_id : "shard3",
    members: [{ _id : 0, host : "mongo1.example.net:27019",priority:1 },
      {_id : 1, host : "mongo2.example.net:27019",arbiterOnly:true },
      {_id : 2, host : "mongo3.example.net:27019",priority:2 }
    ]
  }
)

查看 Replica Set 的状态:

shard3:PRIMARY> rs.status()
{
        “set” : “shard3”,
        “date” : ISODate(“2019-06-20T02:21:56.990Z”),
        “myState” : 1,
        “term” : NumberLong(1),
        “syncingTo” : “”,
        “syncSourceHost” : “”,
        “syncSourceId” : -1,
        “heartbeatIntervalMillis” : NumberLong(2000),
        “optimes” : {
                “lastCommittedOpTime” : {
                        “ts” : Timestamp(1560997312, 2),
                        “t” : NumberLong(1)
                },
                “readConcernMajorityOpTime” : {
                        “ts” : Timestamp(1560997312, 2),
                        “t” : NumberLong(1)
                },
                “appliedOpTime” : {
                        “ts” : Timestamp(1560997312, 2),
                        “t” : NumberLong(1)
                },
                “durableOpTime” : {
                        “ts” : Timestamp(1560997312, 2),
                        “t” : NumberLong(1)
                }
        },
        “lastStableCheckpointTimestamp” : Timestamp(1560997312, 1),
        “members” : [
                {
                        “_id” : 0,
                        “name” : “mongo1.example.net:27019”,
                        “health” : 1,
                        “state” : 2,
                        “stateStr” : “SECONDARY”,
                        “uptime” : 17,
                        “optime” : {
                                “ts” : Timestamp(1560997312, 2),
                                “t” : NumberLong(1)
                        },
                        “optimeDurable” : {
                                “ts” : Timestamp(1560997312, 2),
                                “t” : NumberLong(1)
                        },
                        “optimeDate” : ISODate(“2019-06-20T02:21:52Z”),
                        “optimeDurableDate” : ISODate(“2019-06-20T02:21:52Z”),
                        “lastHeartbeat” : ISODate(“2019-06-20T02:21:56.160Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-20T02:21:55.155Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “mongo3.example.net:27019”,
                        “syncSourceHost” : “mongo3.example.net:27019”,
                        “syncSourceId” : 2,
                        “infoMessage” : “”,
                        “configVersion” : 1
                },
                {
                        “_id” : 1,
                        “name” : “mongo2.example.net:27019”,
                        “health” : 1,
                        “state” : 7,
                        “stateStr” : “ARBITER”,
                        “uptime” : 17,
                        “lastHeartbeat” : ISODate(“2019-06-20T02:21:56.159Z”),
                        “lastHeartbeatRecv” : ISODate(“2019-06-20T02:21:55.021Z”),
                        “pingMs” : NumberLong(0),
                        “lastHeartbeatMessage” : “”,
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “”,
                        “configVersion” : 1
                },
                {
                        “_id” : 2,
                        “name” : “mongo3.example.net:27019”,
                        “health” : 1,
                        “state” : 1,
                        “stateStr” : “PRIMARY”,
                        “uptime” : 45,
                        “optime” : {
                                “ts” : Timestamp(1560997312, 2),
                                “t” : NumberLong(1)
                        },
                        “optimeDate” : ISODate(“2019-06-20T02:21:52Z”),
                        “syncingTo” : “”,
                        “syncSourceHost” : “”,
                        “syncSourceId” : -1,
                        “infoMessage” : “could not find member to sync from”,
                        “electionTime” : Timestamp(1560997310, 1),
                        “electionDate” : ISODate(“2019-06-20T02:21:50Z”),
                        “configVersion” : 1,
                        “self” : true,
                        “lastHeartbeatMessage” : “”
                }
        ],
        “ok” : 1,
        “operationTime” : Timestamp(1560997312, 2),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1560997312, 2),
                “signature” : {
                        “hash” : BinData(0,”AAAAAAAAAAAAAAAAAAAAAAAAAAA=”),
                        “keyId” : NumberLong(0)
                }
        }
}

结果:  可以看出三个服务器: 1 个 Primary,1 个 Secondary,1 一个 Arbiter

配置登录认证的用户请按照 Shard1 的步骤

 

7、配置 mongos 服务器去连接分片集群

mongos.example.net 服务器上 mongos 的配置文件 /data/mongodb/mongos.conf

systemLog:
  destination: file
  path: "/data/mongodb/log/mongos.log"
  logAppend: true
processManagement:
  fork: true
net:
  port: 27017
  bindIp: mongos.example.net
sharding:
  configDB: "cs0/mongo1.example.net:27027,mongo2.example.net:27027,mongo3.example.net:27027"
security:
   keyFile: "/data/mongodb/keyfile"
   clusterAuthMode: "keyFile"

启动 mongos 服务

mongos -f /data/mongodb/mongos.conf

连接 mongos

mongo --host mongos.example.net --port 27017 -u myUserAdmin --authenticationDatabase "admin" -p 'abc123'

查看当前集群结果:

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {"_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5d0af6ed4fa51757cd032108")
  }
  shards:
  active mongoses:
  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 }

在集群中先加入 Shard1、Shard2,剩余 Shard3 我们在插入数据有在进行加入(模拟实现扩容)。

sh.addShard("shard1/mongo1.example.net:27017,mongo2.example.net:27017,mongo3.example.net:27017")
sh.addShard("shard2/mongo1.example.net:27018,mongo2.example.net:27018,mongo3.example.net:27018")

结果:

mongos> sh.addShard(“shard1/mongo1.example.net:27017,mongo2.example.net:27017,mongo3.example.net:27017”)
{
        “shardAdded” : “shard1”,
        “ok” : 1,
        “operationTime” : Timestamp(1561009140, 7),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1561009140, 7),
                “signature” : {
                        “hash” : BinData(0,”2je9FsNfMfBMHp+X/6d98B5tLH8=”),
                        “keyId” : NumberLong(“6704442493062086684”)
                }
        }
}
mongos> sh.addShard(“shard2/mongo1.example.net:27018,mongo2.example.net:27018,mongo3.example.net:27018”)
{
        “shardAdded” : “shard2”,
        “ok” : 1,
        “operationTime” : Timestamp(1561009148, 5),
        “$clusterTime” : {
                “clusterTime” : Timestamp(1561009148, 6),
                “signature” : {
                        “hash” : BinData(0,”8FvJuCy8kCrMu5nB9PYILj0bzLk=”),
                        “keyId” : NumberLong(“6704442493062086684”)
                }
        }
}

查看集群的状态

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {"_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5d0af6ed4fa51757cd032108")
  }
  shards:
        {"_id" : "shard1",  "host" : "shard1/mongo1.example.net:27017,mongo2.example.net:27017",  "state" : 1 }
        {"_id" : "shard2",  "host" : "shard2/mongo2.example.net:27018,mongo3.example.net:27018",  "state" : 1 }
  active mongoses:
        "4.0.10" : 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 }

 

8、测试

为了便于测试,设置分片 chunk 的大小为 1M

use config
db.settings.save({"_id":"chunksize","value":1})

在连接 mongos 后,执行创建数据库,并启用分片存储

sh.enableSharding("user_center")

创建 “user_center” 数据库,并启用分片,查看结果:

mongos> sh.status()
— Sharding Status —
  sharding version: {
        “_id” : 1,
        “minCompatibleVersion” : 5,
        “currentVersion” : 6,
        “clusterId” : ObjectId(“5d0af6ed4fa51757cd032108”)
  }
  shards:
        {“_id” : “shard1”,  “host” : “shard1/mongo1.example.net:27017,mongo2.example.net:27017”,  “state” : 1}
        {“_id” : “shard2”,  “host” : “shard2/mongo2.example.net:27018,mongo3.example.net:27018”,  “state” : 1}
  active mongoses:
        “4.0.10” : 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}
                config.system.sessions
                        shard key: {“_id” : 1}
                        unique: false
                        balancing: true
                        chunks:
                                shard1  1
                        {“_id” : { “$minKey” : 1} } –>> {“_id” : { “$maxKey” : 1} } on : shard1 Timestamp(1, 0)
        {“_id” : “user_center”,  “primary” : “shard1”,  “partitioned” : true,  “version” : {  “uuid” : UUID(“3b05ccb5-796a-4e9e-a36e-99b860b6bee0”),  “lastMod” : 1 } }

创建 “users” 集合

sh.shardCollection("user_center.users",{"name":1})   # 数据库 user_center 中 users 集合使用了片键{"name":1},这个片键通过字段 name 的值进行数据分配

现在查看集群状态

mongos> sh.status()
— Sharding Status —
  sharding version: {
        “_id” : 1,
        “minCompatibleVersion” : 5,
        “currentVersion” : 6,
        “clusterId” : ObjectId(“5d0af6ed4fa51757cd032108”)
  }
  shards:
        {“_id” : “shard1”,  “host” : “shard1/mongo1.example.net:27017,mongo2.example.net:27017”,  “state” : 1}
        {“_id” : “shard2”,  “host” : “shard2/mongo2.example.net:27018,mongo3.example.net:27018”,  “state” : 1}
  active mongoses:
        “4.0.10” : 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}
                config.system.sessions
                        shard key: {“_id” : 1}
                        unique: false
                        balancing: true
                        chunks:
                                shard1  1
                        {“_id” : { “$minKey” : 1} } –>> {“_id” : { “$maxKey” : 1} } on : shard1 Timestamp(1, 0)
        {“_id” : “user_center”,  “primary” : “shard2”,  “partitioned” : true,  “version” : {  “uuid” : UUID(“33c79b3f-aa18-4755-a5e8-b8f7f3d05893”),  “lastMod” : 1 } }
                user_center.users
                        shard key: {“name” : 1}
                        unique: false
                        balancing: true
                        chunks:
                                shard2  1
                        {“name” : { “$minKey” : 1} } –>> {“name” : { “$maxKey” : 1} } on : shard2 Timestamp(1, 0)

写 pyhton 脚本插入数据

#enconding:utf8
import pymongo,string,random

def random_name():
    str_args = string.ascii_letters
    name_list = random.sample(str_args,5)
    random.shuffle(name_list)
    return ''.join(name_list)

def random_age():
    age_args = string.digits
    age_list = random.sample(age_args,2)
    random.shuffle(age_list)
    return int(''.join(age_list))
def insert_data_to_mongo(url,dbname,collections_name):
    print(url)
    client = pymongo.MongoClient(url)
    db = client[dbname]
    collections = db[collections_name]
    for i in range(1,100000):
        name = random_name()
        collections.insert({"name" : name , "age" : random_age(), "status" : "pending"})
        print("insert ",name)

if __name__ == "__main__":
    mongo_url="mongodb://myUserAdmin:abc123@192.168.11.10:27017/?maxPoolSize=100&minPoolSize=10&maxIdleTimeMS=600000"
    mongo_db="user_center"
    mongo_collections="users"
    insert_data_to_mongo(mongo_url,mongo_db,mongo_collections)

插入数据后查看此时集群的状态:

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {"_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5d0af6ed4fa51757cd032108")
  }
  shards:
        {"_id" : "shard1",  "host" : "shard1/mongo1.example.net:27017,mongo2.example.net:27017",  "state" : 1 }
        {"_id" : "shard2",  "host" : "shard2/mongo2.example.net:27018,mongo3.example.net:27018",  "state" : 1 }
  active mongoses:
        "4.0.10" : 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: 
                3 : Success
  databases:
        {"_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: {"_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  1
                        {"_id" : {"$minKey" : 1 } } -->> {"_id" : {"$maxKey" : 1 } } on : shard1 Timestamp(1, 0) 
        {"_id" : "user_center",  "primary" : "shard2",  "partitioned" : true,  "version" : {"uuid" : UUID("33c79b3f-aa18-4755-a5e8-b8f7f3d05893"),  "lastMod" : 1 } }
                user_center.users
                        shard key: {"name" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  9
                                shard2  8
                        {"name" : {"$minKey" : 1 } } -->> {"name" : "ABXEw" } on : shard1 Timestamp(2, 0) 
                        {"name" : "ABXEw" } -->> {"name" : "EKdCt" } on : shard1 Timestamp(3, 11) 
                        {"name" : "EKdCt" } -->> {"name" : "ITgcx" } on : shard1 Timestamp(3, 12) 
                        {"name" : "ITgcx" } -->> {"name" : "JKoOz" } on : shard1 Timestamp(3, 13) 
                        {"name" : "JKoOz" } -->> {"name" : "NSlcY" } on : shard1 Timestamp(4, 2) 
                        {"name" : "NSlcY" } -->> {"name" : "RbrAy" } on : shard1 Timestamp(4, 3) 
                        {"name" : "RbrAy" } -->> {"name" : "SQvZq" } on : shard1 Timestamp(4, 4) 
                        {"name" : "SQvZq" } -->> {"name" : "TxpPM" } on : shard1 Timestamp(3, 4) 
                        {"name" : "TxpPM" } -->> {"name" : "YEujn" } on : shard1 Timestamp(4, 0) 
                        {"name" : "YEujn" } -->> {"name" : "cOlra" } on : shard2 Timestamp(3, 9) 
                        {"name" : "cOlra" } -->> {"name" : "dFTNS" } on : shard2 Timestamp(3, 10) 
                        {"name" : "dFTNS" } -->> {"name" : "hLwFZ" } on : shard2 Timestamp(3, 14) 
                        {"name" : "hLwFZ" } -->> {"name" : "lVQzu" } on : shard2 Timestamp(3, 15) 
                        {"name" : "lVQzu" } -->> {"name" : "mNLGP" } on : shard2 Timestamp(3, 16) 
                        {"name" : "mNLGP" } -->> {"name" : "oILav" } on : shard2 Timestamp(3, 7) 
                        {"name" : "oILav" } -->> {"name" : "wJWQI" } on : shard2 Timestamp(4, 1) 
                        {"name" : "wJWQI" } -->> {"name" : {"$maxKey" : 1 } } on : shard2 Timestamp(3, 1)

可以看出,数据分别再 Shard1、Shard2 分片上。

将 Shard3 分片也加入到集群中来

mongos> sh.addShard("shard3/mongo1.example.net:27019,mongo2.example.net:27019,mongo3.example.net:27019")

在查看集群的状态:

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {"_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5d0af6ed4fa51757cd032108")
  }
  shards:
        {"_id" : "shard1",  "host" : "shard1/mongo1.example.net:27017,mongo2.example.net:27017",  "state" : 1 }
        {"_id" : "shard2",  "host" : "shard2/mongo2.example.net:27018,mongo3.example.net:27018",  "state" : 1 }
        {"_id" : "shard3",  "host" : "shard3/mongo1.example.net:27019,mongo3.example.net:27019",  "state" : 1 }
  active mongoses:
        "4.0.10" : 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: 
                8 : Success
  databases:
        {"_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: {"_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  1
                        {"_id" : {"$minKey" : 1 } } -->> {"_id" : {"$maxKey" : 1 } } on : shard1 Timestamp(1, 0) 
        {"_id" : "user_center",  "primary" : "shard2",  "partitioned" : true,  "version" : {"uuid" : UUID("33c79b3f-aa18-4755-a5e8-b8f7f3d05893"),  "lastMod" : 1 } }
                user_center.users
                        shard key: {"name" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  6
                                shard2  6
                                shard3  5
                        {"name" : {"$minKey" : 1 } } -->> {"name" : "ABXEw" } on : shard3 Timestamp(5, 0) 
                        {"name" : "ABXEw" } -->> {"name" : "EKdCt" } on : shard3 Timestamp(7, 0) 
                        {"name" : "EKdCt" } -->> {"name" : "ITgcx" } on : shard3 Timestamp(9, 0) 
                        {"name" : "ITgcx" } -->> {"name" : "JKoOz" } on : shard1 Timestamp(9, 1) 
                        {"name" : "JKoOz" } -->> {"name" : "NSlcY" } on : shard1 Timestamp(4, 2) 
                        {"name" : "NSlcY" } -->> {"name" : "RbrAy" } on : shard1 Timestamp(4, 3) 
                        {"name" : "RbrAy" } -->> {"name" : "SQvZq" } on : shard1 Timestamp(4, 4) 
                        {"name" : "SQvZq" } -->> {"name" : "TxpPM" } on : shard1 Timestamp(5, 1) 
                        {"name" : "TxpPM" } -->> {"name" : "YEujn" } on : shard1 Timestamp(4, 0) 
                        {"name" : "YEujn" } -->> {"name" : "cOlra" } on : shard3 Timestamp(6, 0) 
                        {"name" : "cOlra" } -->> {"name" : "dFTNS" } on : shard3 Timestamp(8, 0) 
                        {"name" : "dFTNS" } -->> {"name" : "hLwFZ" } on : shard2 Timestamp(3, 14) 
                        {"name" : "hLwFZ" } -->> {"name" : "lVQzu" } on : shard2 Timestamp(3, 15) 
                        {"name" : "lVQzu" } -->> {"name" : "mNLGP" } on : shard2 Timestamp(3, 16) 
                        {"name" : "mNLGP" } -->> {"name" : "oILav" } on : shard2 Timestamp(8, 1) 
                        {"name" : "oILav" } -->> {"name" : "wJWQI" } on : shard2 Timestamp(4, 1) 
                        {"name" : "wJWQI" } -->> {"name" : {"$maxKey" : 1 } } on : shard2 Timestamp(6, 1)

加入后,集群的分片数据重新平衡调整,有一部分数据分布到 Shard3 上。

 9、备份和恢复

 备份

备份的时候需要锁定配置服务器(ConfigServer)和分片服务器(Shard)

在备份前查看当前数据库中数据总条数

mongos> db.users.find().count()
99999

然后启动前面的 Python 脚本,可以在脚本中添加 time.sleep 来控制插入的频率。

在 mongos 服务器上停止平衡器。

mongos> sh.stopBalancer()

锁定配置服务器和各分片服务器,登录配置服务器和各分片服务器的 Secondary 执行命令

db.fsyncLock()

开始备份数据库

mongodump  -h mongo2.example.net --port 27027 --authenticationDatabase admin -u myUserAdmin -p abc123 -o /data/backup/config
mongodump  -h mongo2.example.net --port 27017 --authenticationDatabase admin -u myUserAdmin -p abc123 -o /data/backup/shard1
mongodump  -h mongo3.example.net --port 27018 --authenticationDatabase admin -u myUserAdmin -p abc123 -o /data/backup/shard2
mongodump  -h mongo1.example.net --port 27019 --authenticationDatabase admin -u myUserAdmin -p abc123 -o /data/backup/shard3

锁定配置服务器和各分片服务器

db.fsyncUnlock()

在 mongos 中开启平衡器

sh.setBalancerState(true);

在备份的过程中不会影响到数据的写入,备份后查看此时的数据

mongos> db.users.find().count()
107874

 

恢复

将 Shard1 分片服务器 1 中的数据库删除

shard1:PRIMARY> use user_center
switched to db user_center
shard1:PRIMARY>  db.dropDatabase()
{"dropped" : "user_center",
        "ok" : 1,
        "operationTime" : Timestamp(1561022404, 2),
        "$gleStats" : {"lastOpTime" : {"ts" : Timestamp(1561022404, 2),
                        "t" : NumberLong(2)
                },
                "electionId" : ObjectId("7fffffff0000000000000002")
        },
        "lastCommittedOpTime" : Timestamp(1561022404, 1),
        "$configServerState" : {"opTime" : {"ts" : Timestamp(1561022395, 1),
                        "t" : NumberLong(2)
                }
        },
        "$clusterTime" : {"clusterTime" : Timestamp(1561022404, 2),
                "signature" : {"hash" : BinData(0,"GO1yQDvdZ6oJBXdvM94noPNnJTM="),
                        "keyId" : NumberLong("6704442493062086684")
                }
        }
}

然后使用刚备份的数据库进行恢复

mongorestore  -h mongo1.example.net --port 27017 --authenticationDatabase admin -u myUserAdmin -p abc123 -d user_center /data/backup/shard1/user_center

2019-06-20T17:20:34.325+0800 the –db and –collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use –nsInclude instead
2019-06-20T17:20:34.326+0800 building a list of collections to restore from /data/backup/shard1/user_center dir
2019-06-20T17:20:34.356+0800 reading metadata for user_center.users from /data/backup/shard1/user_center/users.metadata.json
2019-06-20T17:20:34.410+0800 restoring user_center.users from /data/backup/shard1/user_center/users.bson
2019-06-20T17:20:36.836+0800 restoring indexes for collection user_center.users from metadata
2019-06-20T17:20:37.093+0800 finished restoring user_center.users (30273 documents)
2019-06-20T17:20:37.093+0800 done

根据上述步骤恢复 Shard2、Shard3 的数据

最后恢复的结果:

mongos> db.users.find().count()
100013

这个应该是我在锁的时候插入的数据。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计42941字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19348
评论数
4
阅读量
7804776
文章搜索
热门文章
开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南 大家好,我是星哥。之前介绍了腾讯云的 Code...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板 1Panel:小白轻松构建 Web 服务与面板加固指南 哈喽,我是星哥,经常有人问我不...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

  颠覆 AI 开发效率!开源工具一站式管控 30+ 大模型 ApiKey,秘钥付费 + 负载均衡全...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
告别Notion焦虑!这款全平台开源加密笔记神器,让你的隐私真正“上锁”

告别Notion焦虑!这款全平台开源加密笔记神器,让你的隐私真正“上锁”

  告别 Notion 焦虑!这款全平台开源加密笔记神器,让你的隐私真正“上锁” 引言 在数字笔记工...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...
我用AI做了一个1978年至2019年中国大陆企业注册的查询网站

我用AI做了一个1978年至2019年中国大陆企业注册的查询网站

我用 AI 做了一个 1978 年至 2019 年中国大陆企业注册的查询网站 最近星哥在 GitHub 上偶然...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号 AI 知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率 大家好,我是星哥,...
星哥带你玩飞牛NAS-8:有了NAS你可以干什么?软件汇总篇

星哥带你玩飞牛NAS-8:有了NAS你可以干什么?软件汇总篇

星哥带你玩飞牛 NAS-8:有了 NAS 你可以干什么?软件汇总篇 前言 哈喽各位玩友!我是是星哥,不少朋友私...
星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛 NAS-11:咪咕视频订阅部署全攻略 前言 在家庭影音系统里,NAS 不仅是存储中心,更是内容...
零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台

零成本上线!用 Hugging Face 免费服务器 +Docker 快速部署 HertzBeat 监控平台 ...
开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

  开源 MoneyPrinterTurbo 利用 AI 大模型,一键生成高清短视频! 在短视频内容...