前言
- 本文依据
TJ
《MongoDB 高手课》整顿,配上了官网文档链接。 - 本文对 MongoDB 4.2/4.4 实用。
MongoDB 最佳实际
对于连贯到 MongoDB
- 官网驱动程序列表:https://docs.mongodb.com/driv…
- 对于连贯对象 MongoClient:应用 MongoClient 对象连接到 MongoDB 实例时总是应该保障它单例,并且在整个生命周期中都从它获取其余操作对象。
- 对于连贯字符串:连贯字符串中能够配置大部分连贯选项,倡议总是在连贯字符串中配置这些选项。官网文档:https://docs.mongodb.com/v4.4…
# 单实例
mongodb://mongo0.example.com:27017/database?[options]
# 连贯到复制集
mongodb://mongo0,mongo1,mongo2…/database?[options]
# 连贯到分片集
mongodb://mongos1,mongos2,mongos3…/database?[options]
- 常见连贯字符串参数。官网文档:https://docs.mongodb.com/v4.4…
maxPoolSize: 连接池大小
Max Wait Time: 倡议设置,主动杀掉太慢的查问
Write Concern: 倡议 majority 保障数据安全
Read Concern: 对于数据一致性要求高的场景适当应用
- 无论对于复制集或分片集,连贯字符串中都应尽可能多地提供节点地址,倡议全副
列出
复制集利用这些地址能够更无效地发现集群成员
分片集利用这些地址能够更无效地扩散负载
- 连贯字符串中尽可能应用与复制集外部配置雷同的域名或 IP
- 应用域名连贯集群
在配置集群时应用域名能够为集群变更时提供一层额定的爱护。例如须要将集群整体
迁徙到新网段,间接批改域名解析即可。另外,MongoDB 提供的 mongodb+srv:// 协定能够提供额定一层的爱护。该协定允
许通过域名解析失去所有 mongos 或节点的地址,而不是写在连贯字符串中。
- 不要在 mongos 后面应用负载平衡。基于后面提到的起因,驱动曾经通晓在不同的 mongos 之间实现负载平衡,而复制集则须要依据节点的角色来抉择发送申请的指标。如果在 mongos 或复制集下层部署负载平衡:
驱动会无奈探测具体哪个节点存活,从而无奈实现主动故障复原
驱动会无奈判断游标是在哪个节点创立的,从而遍历游标时出错
论断:不要在 mongos 或复制集下层搁置负载均衡器,让驱动解决负载平衡和主动故
障复原。
- 游标应用。如果一个游标曾经遍历完,则会主动敞开;如果没有遍历完,则须要手动调用 close() 办法,否则该游标将在服务器上存在 10 分钟(默认值)后超时开释,造成不必要的资源节约。然而,如果不能遍历完一个游标,通常意味着查问条件太宽泛,更应该思考的问题是如何将条件收紧。
- 3 三节点正本集连贯字符串示例
mongodb://user:pass@mongo0:27017,mongo1:27017,mongo2:27017/database?
authSource=admin&replicaSet=rs0
&w=majority&wtimeoutMS=20000
&readConcernLevel=majority&readPreference=secondaryPreferred
&connectTimeoutMS=20000&socketTimeoutMS=200000
对于查问及索引
- 每一个查问都必须要有对应的索引
- 尽量应用笼罩索引 Covered Indexes(能够防止读数据文件)
- 应用 projection 来缩小返回到客户端的的文档的内容
对于写入操作
- 在 update 语句里只包含须要更新的字段
- 尽可能应用批量插入来晋升写入性能
- 应用 TTL 主动过期日志类型的数据
对于文档构造
- 避免应用太长的字段名(节约空间)
- 避免应用太深的数组嵌套(超过 2 层操作比较复杂)
- 不应用中文,标点符号等非拉丁字母作为字段名
解决分页问题
- 分页时防止应用 count。尽可能不要计算总页数,特地是数据量大和查问条件不能残缺命中索引时。思考以下场景:假如汇合总共有 1000w 条数据,在没有索引的状况下思考以下查问:
db.coll.find({x: 100}).limit(50)
db.coll.count({x: 100})
前者只须要遍历前 n 条,直到找到 50 条队伍 x=100 的文档即可完结;后者须要遍历完 1000w 条找到所有符合要求的文档能力失去后果。为了计算总页数而进行的 count() 往往是拖慢页面整体加载速度的起因。
- 巧分页。应防止应用 skip/limit 模式的分页,特地是数据量大的时候;代替计划:应用查问条件 + 惟一排序条件。例如:
第一页:db.posts.find({}).sort({_id: 1}).limit(20);
第二页:db.posts.find({_id: {$gt: < 第一页最初一个_id>}}).sort({_id: 1}).limit(20);
第三页:db.posts.find({_id: {$gt: < 第二页最初一个_id>}}).sort({_id: 1}).limit(20);
……
对于事务
- 无论何时,事务的应用总是能防止则防止
- 模型设计先于事务,尽可能用模型设计躲避事务
- 不要应用过大的事务(尽量管制在 1000 个文档更新以内)
- 当必须应用事务时,尽可能让波及事务的文档散布在同一个分片上,这将无效地提高效率
本文出自 qbit snap