前言
分片(sharding)是MongoDB将大型集合分割到不同服务器(或者说集群)上所采用的方法,主要为应对高吞吐量与大数据量的应用场景提供了方法。
将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。通过一个名为mongos的路由进程进行操作,mongos知道数据和片的对应关系(通过配置服务器)。大部分使用场景都是解决磁盘空间的问题,对于写入有可能会变差(+++里面的说明+++),查询则尽量避免跨分片查询。
使用分片的时机:
1,机器的磁盘不够用了。使用分片解决磁盘空间的问题。
2,单个mongod已经不能满足写数据的性能要求。通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。
3,想把大量数据放到内存里提高性能。和上面一样,通过分片使用分片服务器自身的资源。
和既有的分库分表、分区方案相比,MongoDB的最大区别在于它几乎能自动完成所有事情,只要告诉MongoDB要分配数据,它就能自动维护数据在不同服务器之间的均衡。
一. 分片的集群组件
1.Mongos 【路由】
作为请求的访问入口,所有的请求都由mongos来路由、分发、合并,这些动作对客户端driver透明,用户连接mongos就像连接mongod一样使用。Mongos会根据请求类型及shard key将请求路由到对应的Shard。
2.Config Server 【配置服务器】
存储Sharding Cluster 的所有元数据,所有的元数据都存储在config数据库;
*保存每个分片上的chunk的信息 * 保存chunk上的片键范围。
3. Shard 【分片】
存储应用数据记录。
二. 分片优势
1.对集群进行抽象,让集群“不可见”,分片对应用系统是透明的。
Mongos是专有路由进程,其会将客户端发来的请求准确无误的路由到集群中的一个或者一组服务器上,同时会把接收到的响应拼装起来发回到客户端。
2.保证集群总是可读写
将MongoDB的分片和复制集功能结合使用,在确保数据分片到多台服务器的同时,也确保了每分数据都有相应的备份,可以确保有服务器坏掉时,其他的从库可以立即接替坏掉的部分继续工作。提高了集群的可用性和可靠性。
3.使集群易于扩展
当系统需要更多的空间和资源的时候,MongoDB使我们可以按需方便的扩充系统容量。
三. 分片部署注意事项(常见错误)
1.配置可复制集作为分片节点与配置单独使用的可复制集基本一样。但启动参数中需指定—shardsvr参数。
否则,在启动数据库分片时报错: {"code" : 193,"ok" : 0, "errmsg" : "Cannot accept sharding commands if not started with --shardsvr“}
。
2.创建配置服务器集群时,不能设置见证节点。
否则,报错 "errmsg" : "Arbiters are not allowed in replica set configurations being used for config servers"
。
3.配置Mongos 实例时,请不要配置dbpath参数。
否则,设置dbpath参数,服务无法正常启动,报错:Error parsing INI config file: unrecognised option 'dbpath'
。
4.配置Mongos 实例时,需设置Keyfile。
否则,不设置Keyfile,Service无法正常启动, 报错:2018-05-10T15:30:26.791+0800 W SHARDING [mongosMain] Error initializing sharding state, sleeping for 2 seconds and trying again :: caused by :: Unauthorized: Error loading clusterID :: caused by :: not authorized on config to execute command { find: “version”, readConcern: { level: “majority”, afterOpTime: { ts: Timestamp 1525937413000|2, t: 1 } }, maxTimeMS: 30000
5.分片集合设置。
分片不会默认生成,需要先在数据库中启动分片(sh.enableSharding(“DBName”)
),然后再设置集合分片(sh.shardCollection(“Collection”{片键})
)
四. 分片管理的注意事项(常用命令)
1.检查shards 配置及状态
1
|
db.runCommand({listshards:1}) |
2. 检查数据库主片的地址以及是否分区
1
|
db.getSiblingDB( "config" ).databases.find() |
3. 检查数据块的数量
db.chunks.count()
--需切换到配置数据库(config)
4. 查看分片的详细信息,包括数据库信息和范围信息
1
|
sh.status() |
5. 索引是优化查询性能的重要手段。当在分片集合上声明索引时,每个分片都会为自己的集合部分定义单独的索引。分片集合只允许在_id字段和分片键上建立唯一索引。
6. 分割和迁移 MongoDB底层依赖2个机制来保持集群的平衡:分割和迁移。
分割是把一个大的数据块分割为2个更小的数据块的过程。迁移就是在分片之间移动数据块的过程。当某些分片服务器包含的数据块数据量大大超过其他分片服务器时就会触发迁移的过程,这个触发器叫做迁移回合(migration round)
6.1 迁移触发条件
6.2 查看Balancer 进程是否开启 sh.getBalancerState()
6.3 停Balancer 进程 sh.stopBalancer()
和开启Balancer 进程
6.4. 默认情况下 Balancer 进程一直在运行,为了降低Balancer进程对系统的运行,可以为Balancer进程设置运行时间窗口,让Balancer进程在指定的时间窗口操作。
6.4.1 例如设置Balancer进程在23:00到6:00时间窗口内执行。
1
|
db.settings. update ({ _id : "balancer" }, { $ set : { activeWindow : { start : "23:00" , stop : "6:00" } } }, true ) ; |
6.4.2 删除Balancer进程运行时间窗口
6.5. 查看块的范围
6.5.1 如果集合数据量较小,可以直接通过sh.status()查看
6.5.2 如果集合数据量较大,sh.status()无法反应此集合的分块信息。此时,可通过执行以下命令查看printShardingStatus(db.getSisterDB("config"),1);
6.5.3 也可将命令切换到config数据库下,执行db.chunks.find()
查看。可以输入制定参数,例如,查看分片repsms2,集合cloud-docs.PushMessageRecord的块情况(cloud-docs为数据库名称)
1
|
db.chunks.find({ "shard" : "repsms2" , "ns" : "cloud-docs.PushMessageRecord" }).pretty() |
五. 备注
分片集群管理的数据量比较大,并且分片的架构相对比较复杂。所以,一定在业务需求需要上分片时,再上分片,且不可准求“炫”的技术而上分片。另外,上线后,相关的监控一定要部署,逐渐完善。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://www.cnblogs.com/xuliuzai/p/9620163.html