一、准备
linux 下指定配置文件安装mongodb
二、分片集群原理部分
什么是分片
分片(sharding)是MongoDB用来将大型集合水平分割到不同服务器(或者复制集)上所采用的方法。不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载。
为什么要分片
1.存储容量需求超出单机磁盘容量。2.活跃的数据集超出单机内存容量,导致很多请求都要从磁盘读取数据,影响性能。3.IOPS超出单个MongoDB节点的服务能力,随着数据的增长,单机实例的瓶颈会越来越明显。4.副本集具有节点数量限制。
垂直扩展:增加更多的CPU和存储资源来扩展容量。水平扩展:将数据集分布在多个服务器上。水平扩展即分片。
分片的工作原理

分片集群由以下3个服务组成:Shards Server: 每个shard由一个或多个mongod进程组成,用于存储数据。Router Server: 数据库集群的请求入口,所有请求都通过Router(mongos)进行协调,不需要在应用程,序添加一个路由选择器,Router(mongos)就是一个请求分发中心它负责把应用程序的请求转发到对应的Shard服务器上。Config Server: 配置服务器。存储所有数据库元信息(路由、分片)的配置。
片键(shard key)
为了在数据集合中分配文档,MongoDB使用分片主键分割集合
区块(chunk)
在一个shard server内部,MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部一部分数据。MongoDB分割分片数据到区块,每一个区块包含基于分片主键的左闭右开的区间范围
分片策略
- 范围分片(Range based sharding)
范围分片适合满足在一定范围内的查找,例如查找X的值在[20,30)之间的数据,mongo 路由根据Config server中存储的元数据,可以直接定位到指定的shard的Chunk中。缺点: 如果shard key有明显递增(或者递减)趋势,则新插入的文档多会分布到同一个chunk,无法扩展写的能力。
- hash分片(Hash based sharding)

Hash分片是计算一个分片主键的hash值,每一个区块将分配一个范围的hash值。Hash分片与范围分片互补,能将文档随机的分散到各个chunk,充分的扩展写能力,弥补了范围分片的不足,缺点是不能高效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满足条件的文档
- 组合片键 A + B(散列思想 不能是直接hash)
数据库中没有比较合适的片键供选择,或者是打算使用的片键基数太小(即变化少如星期只有7天可变化),可以选另一个字段使用组合片键,甚至可以添加冗余字段来组合。一般是粗粒度+细粒度进行组合。
三、分片集群搭建过程

1.配置 并启动config 节点集群
节点1 config-17017.conf
# 数据库文件位置
dbpath=config/config1
#日志文件位置
logpath=config/logs/config1.log
# 以追加方式写入日志
logappend=true
# 是否以守护进程方式运行
fork = true
bind_ip=0.0.0.0
port = 17017
# 表示是一个配置服务器
configsvr=true
#配置服务器副本集名称
replSet=configsvr
# 数据库文件位置
节点2 config-17018.conf
# 数据库文件位置
节点3 config-17019.conf
启动配置节点
进入任意节点的mongo shell 并添加 配置节点集群 注意use admin
dbpath=config/config2
#日志文件位置
logpath=config/logs/config.log
# 以追加方式写入日志
logappend=true
# 是否以守护进程方式运行
fork = true
bind_ip=0.0.0.0
port = 17018
# 表示是一个配置服务器
configsvr=true
#配置服务器副本集名称
replSet=configsvr
节点3 config-17019.conf
# 数据库文件位置
dbpath=config/config3
#日志文件位置
logpath=config/logs/config3.log
# 以追加方式写入日志
logappend=true
# 是否以守护进程方式运行
fork = true
bind_ip=0.0.0.0
port = 17019
# 表示是一个配置服务器
configsvr=true
#配置服务器副本集名称
replSet=configsvr
启动配置节点
./bin/mongod -f config/config-17017.conf
./bin/mongod -f config/config-17018.conf
./bin/mongod -f config/config-17019.conf
进入任意节点的mongo shell 并添加 配置节点集群 注意use admin
./bin/mongo --port 17017
use admin
var cfg ={"_id":"configsvr",
"members":[
{"_id":1,"host":"192.168.211.133:17017"},
{"_id":2,"host":"192.168.211.133:17018"},
{"_id":3,"host":"192.168.211.133:17019"}]
};
rs.initiate(cfg)
实操
mkdir shard_cluster
mv mongodb-linux-x86_64-amazon-3.6.21.tgz shard_cluster/
cd shard_cluster/
tar -xvf mongodb-linux-x86_64-amazon-3.6.21.tgz
rm -rf mongodb-linux-x86_64-amazon-3.6.21.tgz
mv mongodb-linux-x86_64-amazon-3.6.21 shard_cluster
cd shard_cluster/
[root@VM_0_4_centos shard_cluster]# mkdir config/config1 -p
[root@VM_0_4_centos shard_cluster]# mkdir config/config2 -p
[root@VM_0_4_centos shard_cluster]# mkdir config/config3 -p
[root@VM_0_4_centos shard_cluster]# mkdir config/logs/ -p
新建节点配置文件,并依次修改10717、17018、17019数据位置,和端口
[root@VM_0_4_centos shard_cluster]# vi mongo_17017.conf
[root@VM_0_4_centos shard_cluster]# cp mongo_17017.conf mongo_17018.conf
[root@VM_0_4_centos shard_cluster]# cp mongo_17017.conf mongo_17019.conf
依次启动各节点
查看配置节点信息


configsvr:SECONDARY> rs.status()
{
"set" : "configsvr",
"date" : ISODate("2020-12-24T07:37:22.074Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"configsvr" : true,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 1,
"name" : "152.136.193.58:17017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 455,
"optime" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-12-24T07:37:18Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1608795352, 1),
"electionDate" : ISODate("2020-12-24T07:35:52Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "152.136.193.58:17018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 99,
"optime" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-12-24T07:37:18Z"),
"optimeDurableDate" : ISODate("2020-12-24T07:37:18Z"),
"lastHeartbeat" : ISODate("2020-12-24T07:37:20.977Z"),
"lastHeartbeatRecv" : ISODate("2020-12-24T07:37:21.680Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "152.136.193.58:17017",
"syncSourceHost" : "152.136.193.58:17017",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 3,
"name" : "152.136.193.58:17019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 99,
"optime" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1608795438, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-12-24T07:37:18Z"),
"optimeDurableDate" : ISODate("2020-12-24T07:37:18Z"),
"lastHeartbeat" : ISODate("2020-12-24T07:37:20.978Z"),
"lastHeartbeatRecv" : ISODate("2020-12-24T07:37:21.674Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "152.136.193.58:17017",
"syncSourceHost" : "152.136.193.58:17017",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1608795438, 1),
"$gleStats" : {
"lastOpTime" : Timestamp(1608795342, 1),
"electionId" : ObjectId("7fffffff0000000000000001")
},
"$clusterTime" : {
"clusterTime" : Timestamp(1608795438, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
configsvr:PRIMARY>
以上配置节点完成
2.配置shard集群
[root@VM_0_4_centos shard1]# mkdir shard1-37017 shard1-37018 shard1-37019
[root@VM_0_4_centos shard1]# mkdir logs
[root@VM_0_4_centos shard1]# vi shard1_37017.conf
[root@VM_0_4_centos shard1]# cp shard1_37017.conf shard1_37018.conf
[root@VM_0_4_centos shard1]# cp shard1_37018.conf shard1_37019.conf
shard1集群搭建37017到37019
dbpath=shard/shard1/shard1-37017
bind_ip=0.0.0.0
port=37017
fork=true
logpath=shard/shard1/shard1-37017.log
replSet=shard1
shardsvr=true
dbpath=shard/shard1/shard1-37018
bind_ip=0.0.0.0
port=37018
fork=true
logpath=shard/shard1/logs/shard1-37018.log
replSet=shard1
shardsvr=true
dbpath=shard/shard1/shard1-37019
bind_ip=0.0.0.0
port=37019
fork=true
logpath=shard/shard1/logs/shard1-37019.log
replSet=shard1
shardsvr=true
启动每个mongod 然后进入其中一个进行集群配置(之前如果搭建过复制集replica_sets 请先停掉)
var cfg ={"_id":"shard1",
"protocolVersion" : 1,
"members":[
{"_id":1,"host":"152.136.193.58:37017"},
{"_id":2,"host":"152.136.193.58:37018"},
{"_id":3,"host":"152.136.193.58:37019"}
]
};
rs.initiate(cfg)
rs.status()
shard1搭建完成
shard2集群搭建47017到47019
dbpath=shard/shard2/shard2-47017
bind_ip=0.0.0.0
port=47017
fork=true
logpath=shard/shard2/logs/shard2-47017.log
replSet=shard2
shardsvr=true
dbpath=shard/shard2/shard2-47018
bind_ip=0.0.0.0
port=47018
fork=true
logpath=shard/shard2/logs/shard2-47018.log
replSet=shard2
shardsvr=true
dbpath=shard/shard2/shard2-47019
bind_ip=0.0.0.0
port=47019
fork=true
logpath=shard/shard2/logs/shard2-47019.log
replSet=shard2
shardsvr=true
var cfg ={"_id":"shard2",
"protocolVersion" : 1,
"members":[
{"_id":1,"host":"152.136.193.58:47017"},
{"_id":2,"host":"152.136.193.58:47018"},
{"_id":3,"host":"152.136.193.58:47019"}
]
};
rs.initiate(cfg)
rs.status()
实操过程 ,参照shard1 过程
3.配置和启动 路由节点
route-27017.conf
port=27017
bind_ip=0.0.0.0
fork=true
logpath=route/logs/route.log
configdb=configsvr/192.168.211.133:17017,192.168.211.133:17018,192.168.211.133:1
7019
启动路由节点使用 mongos (注意不是mongod)
./bin/mongos -f route/route-27017.conf
4. mongos(路由)中添加分片节点
进入路由mongos
mongo --port 27017
sh.status()
sh.addShard("shard1/152.136.193.58:37017,152.136.193.58:37018,152.136.193.58:37019");
sh.addShard("shard2/152.136.193.58:47017,152.136.193.58:47018,152.136.193.58:47019");
sh.status()
5. 开启数据库和集合分片(指定片键)
继续使用mongos完成分片开启和分片大小设置(路由节点)
为数据库开启分片功能
sh.enableSharding("wg_test")
为指定集合开启分片功能.使用 hash 分片
sh.shardCollection("wg_test.t_datas",{"name":"hashed"})
6. 向集合中插入数据测试
通过路由循环向集合中添加数
use wg_test;
for(var i=1;i<= 1000;i++){
db.t_datas.insert({"name":"test"+i,
salary:(Math.random()*20000).toFixed(2)});
}
7.验证分片效果
分别进入 shard1 和 shard2 中的数据库 进行验证

down...............................................................ao li gei