1

重新启航

没想到学习的进程一下中断了半年时间。最开始是因为项目的原因、之后是新年、然后是新冠……,当然,最重要的原因是懒,哈哈。

第二十一天

今天要学习的是《24 | MongoDB开发最佳实践》节。这节是第二章的最后一篇文章,课程的链接点这里,是第二章课程的一个总结。

连接到MongoDB

首先强调的一点就是,一定要选择与你所使用的版本相兼容的驱动程序,特别是使用程序框架的时候,否则会遇到一些无法解释的奇葩问题。驱动的兼容列表点这里

连接字符串

连接地址建议使用域名而不是IP,方便物理机出现故障时更换。

连接到复制集(建议写上所有的复制节点)

mongodb://节点1,节点2,节点3.../database?[options]

连接到分片集(写上mongos地址就行了)

mongodb://mongos1,mongos2,mongos3.../database?[options]
常用连接字符串参数
参数 说明
maxPoolSize 连接池大小不一定非要设置,有默认值的
MaxWaitTime 建议设置,慢查询超时时,后自动杀掉
WriteConcern 建议设置,用于保证数据的安全性
ReadConcern 不一定非要设置,有默认值,用于保证数据的一致性
mongodb+srv:// 协议

不用在连接串中写所有节点地址,而是通过虚拟域名来进行解析,3.6版本后支持。

mongos自带负载均衡

连接字符串写全就行了,系统会自动处理连接到哪个mongos

游标的使用

一般游标查询结束后,会自动关闭。如果查询太大,没自动关,可以调用close()方法手工关了,如果不关,10分钟后系统自动杀掉。

关于查询及索引

  1. 理论上是要每个查询都需要有对应的索引,因为mongodb没有资源隔离,慢查询会影响系统的所有操作。
  2. 尽量使用 Covered Indexes 索引(从索引里看出来要取的字段了,避免去读数据文件)。
  3. 需要啥字段就读啥字段,别一下都读出来,然后到客户端再过滤,提高性能

关于写入

  1. 更新啥就写啥更新字段
  2. 使用批量写入来提高性能
  3. 使用TTL索引,来处理自动过期的日志类型的数据,到期会自动删除

关于文档结构

  1. 别使用太长的字段名,浪费存储空间
  2. 数据嵌套别太多,虽然mongodb支持多层嵌套,别超过2层。
  3. 使用英文字母来当字段名,别使用中文、标点符号等

处理分页

避免使用count,因为使用 count 的时候,有多少条记录都会逐条遍历一次。当然也避免使用skip/limit形式的分页,特别是数据量大的时候;

db.coll.find({x: 100}).limit(50); 
db.coll.count({x: 100});

那分页怎么办?
没啥好办法!

替代方案:使用查询条件+唯一排序条件;
例如:
第一页: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);

关于事务

  1. 不建议使用事务,效率太低
  2. 建议通过模型设计来避免事务的使用,一个文档解决就好
  3. 如果非要用,别使用大事务(这里指超过1000个文档的事务),小批量来处理,因为60秒默认超时限制
  4. 必须使用事务时,也要让文档都分布在一个分片上(虽然支持存在多个分片上),提高性能

最后

好啦,今天的学习到此结束,明天开始学习第三章运维的部分,同时复习一下第二章的内容。


xiaopohair
68 声望27 粉丝

把这辈子活的热气腾腾!