• 新部署是否适合进行分片?
• 在对集合进行分片后是否可以更改片键?
• 为什么文档没有分布到各个分片?
• mongos是如何检测到分片集群配置更改的?
• 日志中出现的writebacklisten是什么意思?
• mongos是如何使用连接的?
本文档回答了有关分片的常见问题。或者可以参考手册的分片章节,其提供了 分片的概述,包括如下细节:
• 片键和选择片键的注意事项
• 查询路由
• 高可用性
• 数据分块(Chunk)和数据块(Chunk)迁移过程
新部署是否适合进行分片?
有时是适合的。但是,如果您的数据集适合放在单个服务器,则应该以非分片部署作为分开始,因为数据集很小,分片几乎没有优势。
在对集合进行分片后是否可以更改片键?
不可以。
MongoDB中没有对集合分片后更改片键的自动支持。这一现实情况强调了选择好的片键的重要性。如果在集合分片后必须更改片键,最佳选择是:
• 将MongoDB中的所有数据转储为外部格式。
• 删除原始分片集合。
• 使用更理想的片键配置分片。
• 预分割(pre-split)片键范围以确保初始均匀分布。
• 将转储的数据恢复到MongoDB中。
也可以参考:
片键
为什么文档没有分布到各个分片?
一旦数据块(chunk)的分布达到某个阈值,均衡器就开始在分片上迁移均衡数据。请参阅 迁移阈值。
此外,如果块中的文档数超过一定数量,MongoDB将无法移动块。请参阅 每个要迁移的块的最大文档数和不可分割的块。
mongos是如何检测到分片集群配置更改的?
mongos实例维护配置数据库(config)的缓存,该缓存包含分片集群的元数据。
mongos通过向分片发出请求并发现其元数据已过期来懒更新其缓存。要强制 mongos重新加载其缓存,可以对每个mongos 直接执行flushRouterConfig命令。
日志中出现的writebacklisten是什么意思?
回写监听器(writeback listener)是一个进程,它打开一个长轮询,在迁移之后从mongod或mongos将写入取回,以确保它们没有进入错误的服务器。如有必要,回写监听器会将写入发送回正确的服务器。
这些消息是分片的基础关键部分,不需要引起关注。
(译者理解:写入数据根据片键发送到对应分片mongod,但到达时发现对应chunk已经迁移到其他分片mongod了,回写监听器监听到这种情况,就会把数据取回到mongos,然后再发往正确的mongod。这一些列动作,对用户来说都是透明的,所以不用关注)
mongos是如何使用连接的?
每个mongos实例都维护一个与分片集群成员的连接池。客户端请求一次使用一个连接; 即请求不是多路复用或流水线化的。
客户端请求完成后,mongos将连接归回到连接池。当客户端数量减少时,这些池不会收缩。这可能导致未使用的mongos占用大量打开的连接。如果mongos不再使用,则可以安全地重新启动进程以关闭现有连接。
要返回mongos所使用的所有对外连接池相关的聚合统计信息,请将mongo shell 连接 到mongos,然后运行 connPoolStats命令:
db.adminCommand (“connPoolStats” );
请参阅UNIX ulimit设置 文档的“ 系统资源利用率”部分。
译者:钟秋
您好,请教一个问题。我使用mongo 4.2.0 通过docker 搭建的分片集群,但发现使用混合片键后应用报错。这时我的集群配置有问题导致的吗?
mongo 版本:4.2.0
部署方式:docker
混合片键:
db.runCommand({shardcollection:”leaguedb.user_query_count_log_test”,key:{“memberUserId”:1,”memberId”:1,”queryType”:1,”createTime”:1,”companyName”:1}})
java应用错误日志:
org.springframework.dao.DataIntegrityViolationException: Write failed with error code 61 and error message ‘Failed to target upsert by query :: could not extract exact shard key’; nested exception is com.mongodb.WriteConcernException: Write failed with error code 61 and error message ‘Failed to target upsert by query :: could not extract exact shard key’
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:85)
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2146)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:484)
at org.springframework.data.mongodb.core.MongoTemplate.saveDBObject(MongoTemplate.java:1104)
at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:1037)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:984)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:972)
at com.benben.mongo.dao.benben.UserQueryCountLogDao.save(UserQueryCountLogDao.java:42)
at com.benben.mongo.service.impl.UserQueryCountLogService.saveUserQueryCountLogDTO(UserQueryCountLogService.java:145)
at com.benben.mongo.service.impl.UserQueryCountLogService.createUserQueryLog(UserQueryCountLogService.java:77)
at com.benben.mq.jms.consumer.BenbenMessageListener.saveLeagueLog(BenbenMessageListener.java:214)
at com.benben.mq.jms.consumer.BenbenMessageListener.onMessage(BenbenMessageListener.java:96)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:746)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:684)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.mongodb.WriteConcernException: Write failed with error code 61 and error message ‘Failed to target upsert by query :: could not extract exact shard key’
问题已找到,因为_id主键使用了string类型,改为Object 问题解释。