1.5 搭建路由节点
我们在 172.18.87.20
和 172.18.86.119
上分别搭建一个路由节点
1.5.1 第一个路由节点
创建存放日志的目录
mkdir -p /mongodb/sharded_cluster/mymongos_27018/log
创建配置文件
vi /mongodb/sharded_cluster/mymongos_27018/mongos.conf
配置文件内容
systemLog:
#日志输出为文件
destination: file
#日志文件的路径
path: "/mongodb/sharded_cluster/mymongos_27018/log/mongod.log"
#mongod实例重新启动时,会将新条目附加到现有日志文件的末尾。
logAppend: true
processManagement:
#启用守护进程模式。
fork: true
#指定进程ID的文件位置
pidFilePath: "/mongodb/sharded_cluster/mymongos_27018/log/mongod.pid"
net:
#服务实例绑定的IP
bindIp: 0.0.0.0
#绑定的端口
port: 27018
sharding:
#指定配置节点副本集
configDB: myconfrs01/172.18.86.227:27017,172.18.86.227:27117,172.18.86.227:27217
启动mongos
/usr/local/mongodb/bin/mongos -f /mongodb/sharded_cluster/mymongos_27018/mongos.conf
登录mongos
/usr/local/mongodb/bin/mongo --host 172.18.87.20 --port 27018
目前只是连接了路由节点,还不能通过路由节点去操作分片集群,因此即使连接了,也无法写入数据。
1.5.2 在路由节点上设置分片
添加分片
sh.addShard("副本集名称/ip:port,ip:port,ip:port")
现在我们将第一套副本集添加进来
sh.addShard("myshardrs01/172.18.87.20:27017,172.18.87.20:27117,172.18.87.20:27217")
查看分片状态
sh.status()
将第二套副本集添加进来
sh.addShard("myshardrs02/172.18.86.119:27017,172.18.86.119:27117,172.18.86.119:27217")
查看分片状态
sh.status()
如果添加分片失败,可以移除分片。当只剩下最后一个分片时,无法删除。移除时会自动转移分片数据,转移完成后,需要再执行一次删除分片命令
use admin
db.runCommand({removeShard: "myshardrs01"})
开启分片功能
需要先开启数据库的分片功能
sh.enableSharding("库名")
开启库的分片功能后,才能对集合进行分片
sh.shardCollection("库名.集合名", {"key", 1})
在bbs数据库配置sharding
sh.enableSharding("bbs")
查看分片状态
sh.status()
集合分片
sh.shardCollection(namespace, key, unique)
如果片键添加错误,可以查看config下collections集合中的数据,删掉对应的片键即可
参数 | 描述 |
---|---|
namespace | 命名空间,格式用 库名.集合名 |
key | 片键,片键是每条记录都必须包含,并且建立了索引的单个字段或者复合字段。MongoDB按照片键将数据划分到不同的数据库中,将数据库均匀的分不到所有分片中。MongoDB使用哈希的分片方式(随机平均分配)或者基于范围的分片方式(数值大小分配)。 |
unique | 当值为true的情况下,片键字段上会限制为唯一索引。哈希策略片键不支持唯一索引,默认是false |
1.5.2.1 哈希策略分片
基于哈希分片,mongodb会计算一个字段的哈希值,并用这个值来创建数据块。拥有相近片键的文档,很可能不会存储在同一个数据块中,这样就使数据的分离性更好些。
使用name作为片键
sh.shardCollection("bbs.user", {"_id": "hashed"})
查看分片状态
sh.status()
1.5.2.2 范围策略分片
范围策略分片,MongoDB按照片键的范围把数据分成不同部分。
假设有一条从0到无穷的直线,每一个片键都是这条线上的点,MongoDB就是把这条线划分为更短的不可重叠的片段,这就是每个数据块。每个数据块包含了片键一定范围内的数据。
基于范围策略的分片虽然范围查询性能相对较高,但是存在着比较严重的弊端。如果片键是线性增长的,就可能会导致一定时间内所有的请求都集中到了某个特定的数据块中,导致那个数据块的压力过大,违背了我们搭建集群的初衷。
而基于哈希的分片策略牺牲了范围查询的性能,但是保证了数据的均衡,保证了系统的高可用性。
无特殊情况,一般就只使用哈希策略分片,并且一般都是使用_id作为片键。
剩余的鸡哥命令
显示集群的详细信息
db.printShardingStatus()
查看当前均衡器状态(了解)
sh.getBalancerState()
1.5.3 分片后插入数据测试
像user中插入1000条数据测试
use bbs
for(var i=1;i<=1000;i++) { db.user.insert({_id: i+"", name:"wsq"+i}) }
插入完毕后查看数量
db.user.count()
从路由上插入的数据,必须要包含片键,否则无法插入
分别登录两个分片副本集的主节点,查看数量
第一个分片副本集,即在第一台服务器上操作,再开一个窗口
/usr/local/mongodb/bin/mongo --host 172.18.87.20 --port 27017
myshardrs01:PRIMARY> use bbs
switched to db bbs
myshardrs01:PRIMARY> db.user.count()
497
myshardrs01:PRIMARY>
use bbs
db.user.count()
第二个分片副本集
/usr/local/mongodb/bin/mongo --host 172.18.86.119 --port 27017
use bbs
db.user.count()
myshardrs02:PRIMARY> show dbs
admin 0.000GB
bbs 0.000GB
config 0.000GB
local 0.001GB
myshardrs02:PRIMARY> use bbs
switched to db bbs
myshardrs02:PRIMARY> db.user.count()
503
myshardrs02:PRIMARY>
可以看到,1000条数据较为均匀的分布到了两个分片上。这种方式非常易于水平扩展,一旦数据需要更大的空间,再增加分片即可。
1.5.4 第二个路由节点
第二个节点在 172.17.238.236
上搭建
创建存放数据和日志的目录
mkdir -p /mongodb/sharded_cluster/mymongos_27018/log
创建配置文件
vi /mongodb/sharded_cluster/mymongos_27018/mongos.conf
配置文件内容
systemLog:
#日志输出为文件
destination: file
#日志文件的路径
path: "/mongodb/sharded_cluster/mymongos_27018/log/mongod.log"
#mongod实例重新启动时,会将新条目附加到现有日志文件的末尾。
logAppend: true
processManagement:
#启用守护进程模式。
fork: true
#指定进程ID的文件位置
pidFilePath: "/mongodb/sharded_cluster/mymongos_27018/log/mongod.pid"
net:
#服务实例绑定的IP
bindIp: 0.0.0.0
#绑定的端口
port: 27018
sharding:
#指定配置节点副本集
configDB: myconfrs01/172.18.86.119:27017,172.18.86.119:27117,172.18.86.119:27217
启动mongos
/usr/local/mongodb/bin/mongos -f /mongodb/sharded_cluster/mymongos_27018/mongos.conf
登录mongos
/usr/local/mongodb/bin/mongo --host 172.18.86.119 --port 27018
登录后我们发现,第二个路由并不需要配置,因为分片配置都保存到了配置服务器中。
show dbs
use bbs
show tables
db.user.find()
1.5.5 路由搭建过程中出错如何处理
我们使用 sh.status()
查看路由的状态,发现有 databases
和 shards
两个属性,分别表示分片的数据库和分片的集群,我们只需要把这两个给清除就好了。
因为集群中的配置都在配置节点上,因此我们只需要修改 config
数据库即可.
use config()
show tables
mongos> use config
switched to db config
mongos> show tables
actionlog
changelog
chunks
collections
databases
lockpings
locks
migrations
mongos
shards
system.sessions
tags
transactions
version
移除分片
我们使用 db.shards.find()
发现,查询出来的数据,和 sh.status()
中 shards
的数据吻合,因此,我们将该集合需要删除的分片,给删除
db.shards.remove({})
移除分片数据库
我们使用 db.databases.find()
发现,里面的数据正是我们配置的需要分片的数据库,直接删除即可.
db.databases.remove({_id: "bbs"})
此时,我们再使用 sh.status()
发现,已经没有了分片的配置。但是,我们的工作还没有结束。
移除分片的集合
我们使用 db.collections.find()
发现,有一条数据是我们配置的要分片的集合,直接删除这条数据
db.collections.remove({_id: "bbs.user"})
移除数据块
我们使用 db.chunks.find()
发现,里面还有一些和我们分片数据库相关的数据,全部删除
db.chunks.remove({_id: /^bbs.user/})
至此,我们完全移除了之前的分片配置
1.6 关闭分片
使用shutdownServer依次关闭,按照分片服务器、配置服务器、路由的顺序依次关闭。而分片服务器和配置服务器分别又是副本集,因此又要按照仲裁者、子节点、主节点进行关闭。关闭的命令如下
rs.stepDowdn()
use admin
db.shutdownServer()
也有人是这样做的
killall mongod
killall mongos