赞
踩
分片,Sharding,将数据拆分至不同数据节点的方式,MongoDB高可用集群的一种形式;需存储海量数据时,一台机器满足不了需求,单台机器读写吞吐性能也会是瓶颈。Sharding技术通过在多台机器上分割数据,使得系统能存储和处理海量数据。
分片的原因
框架图
三个主要组件(三类节点):
一般来说,MongoDB高可用集群有3种部署形式:
分布式系统最常见的部署模式,有一主一从和一主多从形式,常用于热备、读写分离。
Master节点可读可写,通过MongoDB Oplog定时将Master节点接收到的写操作同步到所有Salve节点;所有Slave 从 Master 同步数据,从节点之间不感知。
简单示意图
搭建 Master-Slave 模式:
启动 Master 节点:mongod --master --dbpath /data/masterdb/
启动 Slave 节点:mongod --slave --source <masterhostname><:<port>> --dbpath /data/slavedb/
,--source
:指定数据的复制来源,也就是 Master 的地址;
这种读写模式有个数据一致性的问题,毕竟同步不是实时的,适用于对数据一致性要求不严格的场景。
MongoDB 3.6 起已不推荐使用主从模式,自 MongoDB 3.2 起,分片群集组件已弃用主从复制。因为 Master-Slave 其中 Master 宕机后不能自动恢复,只能靠人为操作,可靠性也差,操作不当就存在丢数据的风险。
包含三类节点角色:
由于Secondary需要和其他若干个Secondary节点保持心跳信息,即,每两个Secondary节点之间都互有心跳,如何维护这个心跳信息呢?不难猜到,Secondary节点数量不宜过大。
MongoDB长于海量存储,而数据量的增长是没有上限。参考关系型数据库在应对海量数据的纵向扩展(升级机器配置)和横向扩展(增加机器数量),其中横向扩展又包括水平和垂直维度的分库分表。
Sharding是横向扩展的思路。基于图1 Sharding架构图,不难发现Sharding模式是架构在前面提到的Replica Set模式基础上,一个Shard就是一个Replica Set集群。理论上,Replica Set 的集群的个数是可以无限增长的。
Sharding模式下,数据如何选择某个Shard进行存储呢?即分片算法。
MongoDB将数据分割到Chunks。每个Chunk有一个基于分片键的左闭右开的区间。分片Shard可以含有多个Chunks。
MongoDB 使用分片集群平衡器在分片集群中迁移Chunks,目地是Chunks在分片集群中均匀分布。
不能移动文件数超过 250000 或超过 设置的 chunk 大小 / 平均文件大小 1.3 倍的 chunk。
分片键
MongoDB 根据分片键分割 collection 中的文档。
MongoDB中提供自动分片的方式,会根据数据块(chunk)大小的设定,对片键进行拆分;
Chunk切分根据分片策略进行实施,分片策略的内容包括分片键和分片算法。
MongoDB支持的分片算法:
0~100
),然后设置Chunk数量N(假如设置为4),集合存储到具体某个Chunk,如A字段的范围区间为[0-25)
的集合会存储到Chunk1。优点:能很好地满足范围查询的需求。缺点:如果Shard Key有明显递增、递减趋势,则新插入的文档会分布到同一个chunk,读写压力会集中到一个节点,从而导致单点的性能瓶颈。另一个区别:哈希分片只能选择单个字段,而范围分片允许采用组合式的多字段作为分片键。
MongoDB 4.4+版本,可将单个字段的哈希分片和一个到多个的范围分片键字段来进行组合,比如指定 x:1,y 是哈希的方式。
分片键选择:
在单机环境下,设置分片结构端口分布如下:
Shard Server 1:27020
Shard Server 2:27021
Shard Server 3:27022
Shard Server 4:27023
Config Server :27100
Route Process:40000
步骤一:启动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
/usr/local/mongoDB/bin/mongod --port 27020 --dbpath=/www/mongoDB/shard/s0 --logpath=/www/mongoDB/shard/log/s0.log --logappend --fork
# 省略
步骤二: 启动Config Server
mkdir -p /www/mongoDB/shard/config
/usr/local/mongoDB/bin/mongod --port 27100 --dbpath=/www/mongoDB/shard/config --logpath=/www/mongoDB/shard/log/config.log --logappend --fork
像启动普通mongodb服务一样启动,不需要添加—shardsvr
和configsvr
参数。因为这两个参数的作用就是改变启动端口
步骤三: 启动Route Process
/usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --fork --logpath=/www/mongoDB/shard/log/route.log --chunkSize 500
mongos启动参数中,chunkSize这一项是用来指定chunk的大小的,默认200MB。
步骤四: 配置Sharding
使用MongoDB Shell登录到mongos,添加Shard节点
/usr/local/mongoDB/bin/mongo admin --port 40000
connecting to: 127.0.0.1:40000/admin
mongos> db.runCommand({ addshard:"localhost:27020" })
{ "shardAdded" : "shard0000", "ok" : 1 }
......
mongos> db.runCommand({ addshard:"localhost:27029" })
{ "shardAdded" : "shard0009", "ok" : 1 }
mongos> db.runCommand({ enablesharding:"test" }) #设置分片存储的数据库
{ "ok" : 1 }
mongos> db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}})
{ "collectionsharded" : "test.log", "ok" : 1 }
步骤五: 程序代码内无需太大更改,直接按照连接普通的mongo数据库那样,将数据库连接接入接口40000
使用Sharding模式后,应用层编码有些注意事项:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。