当前位置:Gxlcms > 数据库问题 > MongoDB使用小结:一些不常见的经验分享

MongoDB使用小结:一些不常见的经验分享

时间:2021-07-01 10:21:17 帮助过:2人阅读

21、副本数也不用太多

如果你的副本数量超过了12个(MongoDB3.0.0超过了50个),那么就要选择使用 master-slave ,但这样会失去故障自恢复功能,主节点故障时,需要手动去切换到无故障节点。

22、mongos的config server配置信息中不要使用localhost、127.0.0.1

启动mongos时,config server的配置信息不得使用localhost、127.0.0.1,否则添加其它机器的shard时,会出现错误提示:
"can’t use localhost as a shard since all shards need to communicate. either use all shards and configdbs in localhost or all in actual IPs host: xxxxx isLocalHost"

以新的config server启动mongos,也需要重启config server,否则会有错误提示:
“could not verify config servers were active and reachable before write”

如果改完后面又出现 “mongos specified a different config database string”  错误,那么还需要重启mongod,

修改了config server 几乎是要全部实例重启。另外,在配置replica set时也不得使用localhost、127.0.0.1。
参考:http://stackoverflow.com/questions/21226255/where-is-the-mongos-config-database-string-being-stored

23、shard key的选择跟update性能紧密关联

分布式MongoDB,shard key的选择跟update性能,甚至是update可用性有很大关系,需要注意。
1、在对文档个别字段update时,如果query部分没有带上shard key,性能会很差,因为mongos需要把这条update语句派发给所有的shard 实例。
2、当update 的upsert参数为true时,query部分必须带上 shard key,否则语句执行出错,例子:
mongos> db.test.update({"_id":".7269993106A92327A89ABCD70D46AD5"}, {"$set":{"P": "aaa"}, "$setOnInsert":{"TEST":"a"}}, true)
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 61,
"errmsg" : "upsert { q: { _id: \".7269993106A92327A89ABCD70D46AD5\" }, u: { $set: { P: "aaa" }, $setOnInsert: { TEST: \"a\" } }, multi: false, upsert: true } does not contain shard key for pattern { _: 1.0, B: 1.0 }"
}
})
这是因为如果没有shard key,mongos既不能在所有shard实例上执行这条语句(可能会导致每个shard都插入数据),也无法选择在某个shard上执行这条语句,于是出错了。
另外,需要特别注意,如果使用pymongo引擎,它不会告诉你出错了,只是函数调用陷入不返回,在shell下执行才能看到错误信息。

附:
以下英文部分来自:https://jira.mongodb.org/browse/SERVER-13010
It‘s actually not clear to me that this is something we can support - problem is this:
> db.coll.update({ _id : 1 }, { }, true);
> db.coll.find()
{ "_id" : ObjectId("53176700a2bc4d46c176f14a") }
Upserts generate new _ids in response to this operation, and therefore we can‘t actually target this correctly in a sharded environment. The shard on which we need to perform the query may not be the shard on which the new _id is placed.
意思是说,upsert产生了新的_id,_id就是shard key,但是如果query里没有shard key,它们不知道要到哪个shard上执行这个命令,upsert产生的shard key可能并不是执行这条命令的shard的。
另外,如果_id不是shard key我们的例子也是不能成功的,因为没有shard key,这条upsert要在哪个shard上执行呢?不能像普通update那样给所有的shard去做,否则可能导致插入多条。
参考:
https://jira.mongodb.org/browse/SERVER-13010
http://docs.mongodb.org/manual/core/sharding-shard-key/
http://stackoverflow.com/questions/17190246/which-of-the-following-statements-are-true-about-choosing-and-using-a-shard-key

24、通过repairDatabase提高性能

从db.stats()中可以看到几个跟碎片相关的关键字段,dataSize,表示数据的大小,它包含了padding的空间;storageSize,表示这些数据存储占用的空间,包含了dataSize和被删除数据所占空间,可以认为storageSize/dataSize就是磁盘碎片比例,当删除、update文档比较多后,它会变大,考虑做repairDatabase,以减少碎片让数据更紧凑,在实践中,这对提高CURD性能极其有用。repairDatabase时需要注意:它是把数据拷贝到新的地方,然后再做处理,所以repair之前在DB目录所在磁盘需要预留一倍的空闲磁盘空间,如果你发现磁盘空间不足,可以停止服务,然后增加一块新磁盘,再执行实例级别的repair,并指定--repairpath为新磁盘路径,eg:mongod --dbpath /path/to/corrupt/data --repair --repairpath /media/external-hd/data/db,实例的数据会拷贝到/media/external-hd/data/db上做处理。

参考:《MongoDB——The Definitive Guide 2nd Edition》page325

25、索引字段的长度不能大于1024字节

索引字段的长度不能大于1024字节,否则shell下会有插入错误提示:"errmsg" : "insertDocument :: caused by :: 17280 Btree::insert: key too large to index”。 使用pymongo的“continue_on_error”参数,不会发出错误提示,要注意。 参考:http://docs.mongodb.org/manual/reference/limits/#Index-Key-Limit

26、修改索引的expireAfterSeconds之后,负载均衡失败

修改索引的expireAfterSeconds之后,负载均衡失败,出现错误提示“2015-06-05T09:59:49.056+0800 [migrateThread] warning: failed to create index before migrating data.  idx: { v: 1, key: { _: -1 }, name: "__-1", ns: "cswuyg_test.cswuyg_test", expireAfterSeconds: 5227200 } error: IndexOptionsConflict Index with name: __-1 already exists with different options 检查发生moveChunk的两个shard,并没有发现不一致,怀疑存在缓存,重启所有shard解决。

27、config DB无法写入

因config DB无法修改,只可读,导致drop、enablesharding失败: config server 相关日志:2015-06-11T16:51:19.078+0800 [replmaster] local.oplog.$main Assertion failure isOk() src/mongo/db/storage/extent.h 80 mongos 相关日志: [LockPinger] warning: pinging failed for distributed lock pinger ‘xxx:1234/xxx:1235:1433993544:1804289383‘. : : caused by :: isOk() 这是同事遇到的问题,不确定是什么操作引起的。重启、configdb做repair均无法解决。 最后通过dump、restore解决:(1)把旧configdb dump出来;(2)restore到新的configure server;(3)mongos采用新的configure server;(4)重启全部mongod。   http://www.cnblogs.com/cswuyg/p/4355948.html http://www.cnblogs.com/cswuyg/p/4595799.html

MongoDB使用小结:一些不常见的经验分享

标签:

人气教程排行