mongodb log ,warning: chunk is larger than 65203623200 bytes because of key

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
日志服务 SLS,月写入数据量 50GB 1个月
简介:
公司的一台放多媒体文件的MONGODB要转成SHARD,在测试环境里面对gridfs里面的fs.chunks做sharding的时候。

在一段时间后报错如下 : 
warning: chunk is larger than 65203623200 bytes because of key { files_id: ObjectId('4e2ea40efa30e751113fc633') }

Tue Sep 27 12:27:11 [conn7] about to log metadata event: { _id: "db-xxx-xxx-xxx-xxx.sky-mobi.com.sh.nj-2011-09-27T04:27:11-4388", server: "db-xxx-xxx-xxx-xxx.sky-mobi.com.sh.nj", clientAddr: "xxx.xxx.xxx.xxx:10751", time: new Date(1317097631976), what: "moveChunk.from", ns: "digoal.fs.chunks", details: { min: { files_id: ObjectId('4e2ea40efa30e751113fc633') }, max: { files_id: ObjectId('4e2ea41afa30e751bd40c633') }, step1: 0, step2: 111, note: "aborted" } }

Tue Sep 27 12:28:34 [conn12] warning: can't move chunk of size (approximately) 97528508 because maximum size allowed to move is 67108864 ns: digoal.fs.chunks { files_id: ObjectId('4e2ea40efa30e751113fc633') } -> { files_id: ObjectId('4e2ea41afa30e751bd40c633') }

Tue Sep 27 12:28:45 [conn7] command admin.$cmd command: { moveChunk: "digoal.fs.chunks", from: "digoal001/xxx.xxx.xxx:xxxx,xxx.xxx.xxx:xxxx ,xxx.xxx.xxx:xxxx ", to: "digoal004/ xxx.xxx.xxx:xxxx,xxx.xxx.xxx:xxxx ,xxx.xxx.xxx:xxxx ", min: { files_id: ObjectId('4e2ea40efa30e751113fc633') }, max: { files_id: ObjectId('4e2ea41afa30e751bd40c633') }, maxChunkSizeBytes: 67108864, shardId: "digoal.fs.chunks-files_id_ObjectId('4e2ea40efa30e751113fc633')", configdb: " xxx.xxx.xxx:xxxx,xxx.xxx.xxx:xxxx ,xxx.xxx.xxx:xxxx " } ntoreturn:1 reslen:109 176ms

从日志中可以看到有一个chunk的SIZE是97528508字节,无法移动,because maximum size allowed to move is 67108864
查询了fs.chunks之后,发现有超过150MB的文件。不过这个警告信息是对的,这么大的CHUNK确实不应该被MOVE。应该先SPLIT到64M以下再被MOVE。否则BALANCE进程会带来严重的性能问题。

如果要修改64M的限制,可以进入mongos/config库
db.settings.find() 
{ "_id" : "chunksize", "value" : 64 } 

db.settings.update( {"_id" : "chunksize"}, { $set: {"value" : 
200 } } ) 
这将改为200MB.
这个值修改后可能要重启mongos才能生效.

但是推荐还是不要修改。


处理这类事件的手段举例 : 
修改chunksize : 
> use config
> db.settings.update( {"_id" : "chunksize"}, { $set: {"value" : new_chunk_size_in_mb } } ) 
Note though that for an existing cluster, it may take some time for the collections to split to that size, if smaller than before, and currently
autosplitting is only triggered if the collection gets new documents or updates.

手工拆分chunk : 
The following command splits the chunk where the { _id : 99 }} resides (or would reside if present) in two. The key used as the split point is computed internally and is approximately the key which would divide the chunk in two equally sized new chunks.
> use admin
switched to db admin
> db.runCommand( { split : "test.foo"  , find : { _id : 99 } } ) 
...
The Balancer treats all chunks the same way, regardless if they were generated by a manual or an automatic split.

预split : 
In the example below the command splits the chunk where the _id 99 would reside using that key as the split point. Again note that a key need not exist for a chunk to use it in its range. The chunk may even be empty.
> use admin
switched to db admin
> db.runCommand( { split : "test.foo"  , middle : { _id : 99 } } ) 
...
split后的chunk值范围:
["$MinKey", "99")
["99", "$MaxKey")

预move chunk : 
> db.printShardingStatus("verbose")  找到属于哪个shard,需要移动到哪个shard
> db.runCommand({ moveChunk : "foo.bar" , find : { hash : "8000"  }, to : "shard0000"  })

预split和预move chunk的好处 : 
1. Chunks will not split until the data reaches a certain minimum amount in size (hundreds of megabytes). Until this occurs balancing and migration will not take place. When the data volume is this small, distributing data between multiple servers is not required anyway. When pre-splitting manually, many chunks can exist even if very little data is present for each chunk initially.
2. "db.runCommand( { split : "test.foo"  , middle : { _id : 99 } } ) " , This version of the command allows one to do a  data presplitting that is especially useful in a load. If the range and distribution of keys to be data presplitting inserted are known in advance, the collection can be split proportionately to the number of servers using the command above, and the (empty) chunks could be migrated upfront using the moveChunk command.

其他参考资料:
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
Linux 网络安全
【Linux】INFO: attempting to log in with the new key(s), to filter out any that are already...
【Linux】INFO: attempting to log in with the new key(s), to filter out any that are already...
560 0
|
6月前
|
SQL
WARNING: too many parse errors' in the 12.2 Alert.log
WARNING: too many parse errors' in the 12.2 Alert.log
68 2
|
关系型数据库 Oracle 数据库
|
存储 运维 Kubernetes
上海·2020线上年会来了!| MongoDB,More than Document Database.
2020年MongoDB中文社区年终大会一起重新认识MongoDB!(2021-1-8 上海线下)
2545 0
上海·2020线上年会来了!| MongoDB,More than Document Database.
|
SQL 监控
backup log is terminating abnormally because for write on file failed: 112(error not found)
昨天遇到一个案例,YourSQLDba做事务日志备份时失败,检查YourSQLDba输出的错误信息如下:   yMaint.backups backup log [gewem] to disk = 'M:\DB_BACKUP\LOG_BACKUP\xxxx_[2016-11-22_01h11m05_Tue]_logs.
1237 0