MongoDB 分片
在Mongodb里面存在一种集群技术,就是分片技术,可以满足MongoDB数据量大量增长的需求。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
分片的优点
读/写性能高 :MongoDB将读写负载分散到分 片集群中的分片中,允许每个分片处理集群操作的子集。读取和写入工作负载可以通过增加更多的分片在集群中水平扩展。
存储容量很容易扩展 :拆分分配整个数据碎片集群中,允许每个碎片以包含总簇数据的子集。随着数据集的增长,额外的分片增加了集群的存储容量。
高可用性 :即使一个或多个碎片是不可用的部分读/写操作。尽管在停机期间无法访问不可用分片上的数据子集,但是针对可用分片的读取或写入仍可能成功。
何时使用分片
- 存储容量需求超出单机磁盘容量
- 活跃的数据集超出单机内存容量,导致很多请求都要从磁盘读取数据,影响性能
- IOPS (Input/Output Operations Per Second),即每秒进行读写(I/O)操作的次数,超过单个MongoDB节点的读写服务能力
分片交互方式
下图描述了分片群集内组件的交互:
Shard: 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障
mongos: 应用程序通过驱动程序直接连接router,router启动时从配置服务器复制集中读取shared信息,然后将数据实际写入或读取(路由)到具体的shard中。
config servers :主要是记录shard的配置信息(元信息metadata),如数据存储目录,日志目录,端口号,是否开启了journal等信息,为了保证config服务器的可用性,一般也需要做复制集处理,注意,一旦配置服务器无法使用,则整个集群就不能使用了,一般是独立的三台服务器实现冗余备份,这三台可能每一台是独立的复制集架构
实例
由于没有多台服务器,那么下面实例中就使用一台服务器开启多个MongoDB实例来演示分片技术。
第一步:启动Shard Server:
mkdir -p /www/mongoDB/shard/s0
mkdir -p /www/mongoDB/shard/s1
mkdir -p /www/mongoDB/shard/s2
mkdir -p /www/mongoDB/shard/s3
mkdir -p /www/mongoDB/shard/log
sudo mongod --port 27020 --dbpath=/www/mongoDB/shard/s0 --logpath=/www/mongoDB/shard/log/s0.log --logappend --fork
sudo mongod --port 27021 --dbpath=/www/mongoDB/shard/s1 --logpath=/www/mongoDB/shard/log/s1.log --logappend --fork
sudo mongod --port 27022 --dbpath=/www/mongoDB/shard/s2 --logpath=/www/mongoDB/shard/log/s2.log --logappend --fork
sudo mongod --port 27023 --dbpath=/www/mongoDB/shard/s3 --logpath=/www/mongoDB/shard/log/s3.log --logappend --fork
第二步:启动Config Server
sudo mkdir -p /www/mongoDB/shard/config
sudo mongod --port 27100 --dbpath=/www/mongoDB/shard/config --logpath=/www/mongoDB/shard/log/config.log --logappend --fork
第三步:启动 mongos
sudo mongos --port 40000 --configdb localhost:27100 --fork --logpath=/www/mongoDB/shard/log/route.log --chunkSize 500
--configdb 指定 Config Server 为 localhost:27100
--chunkSize 这一项是用来指定chunk的大小的,单位是MB,默认大小为200MB.
第四步:配置
连接到mongos进程,并切换到admin数据库做以下配置
mongo admin --port 40000
添加Shard
db.runCommand({ addshard:"localhost:27020" })
db.runCommand({ addshard:"localhost:27021" })
db.runCommand({ addshard:"localhost:27022" })
db.runCommand({ addshard:"localhost:27023" })
查看已添加的Shard
use admin
db.runCommand( { listshards : 1 } )
设置分片存储的数据库
db.runCommand({enablesharding:"test2"});
通过执行以上命令,可以让数据库跨shard,如果不执行这步,数据库只会存放在一个shard,一旦激活数据库分片,数据库中不同的collection将被存放在不同的shard上,但一个collection仍旧存放在同一个shard上,要使单个collection也分片,还需单独对collection作些操作
Collecton分片
要使单个collection也分片存储,需要给collection指定一个分片key,通过以下命令操作:
db.runCommand( { shardcollection : "test2.books", key : { id : 1 } } );
通过执行以上命令,test2数据库下的books文档也会分片存储不同的Shard中
查看状态:
use test2
db.stats()
db.books.stats()
测试
像数据库中插入数据
mongos> for (var i = 1; i <= 20000; i++) db.books.save({id:i,name:"12345678",sex:"male",age:27,value:"test"});
可以看到插入20000条数据,分布在不同的Shard中。
通过MongoDB 复制与分片技术结合,可以搭建高性能MongoDB集群。集群搭建推荐阅读