MongoDB分片 在部署和维护管理 中常见事项的总结
分片(sharding)是MongoDB将大型集合分割到不同服务器(或者说集群)上所采用的方法,主要为应对高吞吐量与大数据量的应用场景提供了方法。
和既有的分库分表、分区方案相比,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 配置及状态
db.runCommand({listshards:1})
2. 检查数据库主片的地址以及是否分区
db.getSiblingDB(“config”).databases.find()
3. 检查数据块的数量
db.chunks.count() —需切换到配置数据库(config)
4. 查看分片的详细信息,包括数据库信息和范围信息
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时间窗口内执行。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为数据库名称)
db.chunks.find({“shard” : “repsms2″,”ns” : “cloud-docs.PushMessageRecord”}).pretty()
五. 备注
分片集群管理的数据量比较大,并且分片的架构相对比较复杂。所以,一定在业务需求需要上分片时,再上分片,且不可准求“炫”的技术而上分片。另外,上线后,相关的监控一定要部署,逐渐完善。