简介
在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
为什么使用分片
- 复制所有的写入操作到主节点
- 延迟的敏感数据会在主节点查询
- 单个副本集限制在12个节点
- 当请求量巨大时会出现内存不足。
- 本地磁盘不足
- 垂直扩展价格昂贵
MongoDB分片
下图展示了在MongoDB中使用分片集群结构分布:
上图中主要有如下所述三个主要组件:
-
Shard:
用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障
-
Config Server:
mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
-
Query Routers:
前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。
分片简介术语介绍
- Shard 用于存储实际的数据块,实际生产环境中的一个shard server角色可由几台及其组成replica set承担,防止单点故障
- config server mongod实例,存储了整个ClusterMetadata,其中包括chunk信息。
- Routers 前端路由,客户端由此接入,让整个集群看上去像单一数据库,前端应用可以透明使用。
- Shard Key 数据的分区根据Shard key,对于每个需要sharding的collection,都需要指定Shard key(分片键);分片键必须是索引字段或者为组合索引的左前缀。mongodb根据分片键将数据分成多个chunks,并将它们均匀在多个shards节点上,目前,mongodb支持两种分区算法:区间分区或哈希分区。
- Range 首先shard key必须是数字类型或字符串类型。整个区间的上下边界分别为正无穷大、负无穷大,每个chunk覆盖一段子区间。区间为左闭右开,每个区间均不会有重叠覆盖,且互相接近。
- Hash 计算shard key的hash值,并以此作为range来分区,hash具有很强的散列能力,通常不同的shard key具有不同的hash值。
搭建分片集群
准备10个节点,1路由,3个节点组成复制集作为配置服务器config server,3个节点组成复制集作为分片1用于存储数据,3个节点组成复制集作为分片2用于存储数据,分片1和分片2组成分片数据存储集群。
环境准备
cd /usr/local/mongo/data
mkdir clusters
cd clusters
mkdir router
mkdir config
mkdir rs0
mkdir rs1
mkdir config/n0
mkdir config/n1
mkdir config/n2
mkdir rs0/n0
mkdir rs0/n1
mkdir rs0/n2
mkdir rs1/n0
mkdir rs1/n1
mkdir rs1/n2
cd /usr/local/mongo/logs/
mkdir clusters
touch clusters/router.log
touch clusters/config0.log
touch clusters/config1.log
touch clusters/config2.log
touch clusters/rs0-n0.log
touch clusters/rs0-n1.log
touch clusters/rs0-n2.log
touch clusters/rs1-n0.log
touch clusters/rs1-n1.log
touch clusters/rs1-n2.log
mkdir -p /usr/local/mongo/pids/clusters
cd /usr/local/mongo/conf
mkdir clusters
cp mongodb.conf clusters/rs0-n0.conf
配置数据分片Shard
vi clusters/rs0-n0.conf
dbpath=/usr/local/mongo/data/clusters/rs0/n0
logpath=/usr/local/mongo/logs/clusters/rs0-n0.log
logappend=true
bind_ip_all=true
port=27217
fork=true
pidfilepath=/usr/local/mongo/pids/clusters/rs0-n0.pid
replSet=shard0
oplogSize=1000
shardsvr=true
同理配置其余两个同一分片数据存储节点,稍微修改一点配置。
cp rs0-n0.conf rs1-n0.conf
dbpath=/usr/local/mongo/data/clusters/rs1/n0
logpath=/usr/local/mongo/logs/clusters/rs1-n0.log
logappend=true
bind_ip_all=true
port=27317
fork=true
pidfilepath=/usr/local/mongo/pids/clusters/rs1-n0.pid
replSet=shard1
oplogSize=1000
shardsvr=true
启动:
cd /usr/local/mongo
bin/mongod -f conf/clusters/rs0-n0.conf
bin/mongod -f conf/clusters/rs0-n1.conf
bin/mongod -f conf/clusters/rs0-n2.conf
bin/mongod -f conf/clusters/rs1-n0.conf
bin/mongod -f conf/clusters/rs1-n1.conf
bin/mongod -f conf/clusters/rs1-n2.conf
配置复制集
bin/mongo --port 27217
use admin
rs.initiate({
"_id":"shard0",
"members":[
{"_id":0,"host":"192.168.1.43:27217","priority":3},
{"_id":1,"host":"192.168.1.43:27218","priority":1},
{"_id":2,"host":"192.168.1.43:27219","arbiterOnly":true}
]
});
rs.isMaster();
bin/mongo --port 27317
use admin
rs.initiate({
"_id":"shard1",
"members":[
{"_id":0,"host":"192.168.1.43:27317","priority":3},
{"_id":1,"host":"192.168.1.43:27318","priority":1},
{"_id":2,"host":"192.168.1.43:27319","arbiterOnly":true}
]
});
rs.isMaster();
配置配置服务器
cd /usr/local/mongo/conf/clusters
cp rs0-n0.conf config-n0.conf
vi config-n0.conf
dbpath=/usr/local/mongo/data/clusters/config/n0
logpath=/usr/local/mongo/logs/clusters/config0.log
logappend=true
bind_ip_all=true
port=27417
fork=true
pidfilepath=/usr/local/mongo/pids/clusters/config0.pid
replSet=config0
oplogSize=1000
configsvr=true
cp config-n0.conf config-n1.conf
vi config-n1.conf
dbpath=/usr/local/mongo/data/clusters/config/n1
logpath=/usr/local/mongo/logs/clusters/config1.log
logappend=true
bind_ip_all=true
port=27418
fork=true
pidfilepath=/usr/local/mongo/pids/clusters/config1.pid
replSet=config0
oplogSize=1000
configsvr=true
#同理配置config2
#启动配置服务
cd /usr/local/mongo
bin/mongod -f conf/clusters/config-n0.conf
bin/mongod -f conf/clusters/config-n1.conf
bin/mongod -f conf/clusters/config-n2.conf
设置配置服务器:
bin/mongo --port 27417
use admin
rs.initiate({
"_id":"config0",
"members":[
{"_id":0,"host":"192.168.1.43:27417","priority":3},
{"_id":1,"host":"192.168.1.43:27418","priority":1},
{"_id":2,"host":"192.168.1.43:27419","priority":1}
]
});
rs.isMaster();
配置路由
cd /usr/local/mongo/conf/clusters
cp config-n0.conf router.conf
logpath=/usr/local/mongo/logs/clusters/router.log
logappend=true
bind_ip_all=true
port=27517
fork=true
pidfilepath=/usr/local/mongo/pids/clusters/router.pid
configdb=config0/192.168.1.43:27417,192.168.1.43:27418,192.168.1.43:27419
启动:
cd /usr/local/mongo/
#注意,不要用mongod启动
bin/mongos -f conf/clusters/router.conf
bin/mongo --port 27517
use admin
db.runCommand({"addShard":"shard0/192.168.1.43:27217,192.168.1.43:27218,192.168.1.43:27219"});
db.runCommand({"addShard":"shard1/192.168.1.43:27317,192.168.1.43:27318,192.168.1.43:27319"});
use config
db.shards.find()
use admin
db.runCommand({"enablesharding":"test"});
use test
db.createCollection("users");
show tables
db.users.ensureIndex({"name":1})
use admin
db.runCommand({"shardcollection":"test.users","key":{"name":"hashed"}});
use config
show tables
db.chunks.find()
use admin
use test
db.users.insert({'name':'wj'});
db.users.insert({'name':'zhangsan'});
use admin
sh.status()