共计 1464 个字符,预计需要花费 4 分钟才能阅读完成。
重新启航
没想到学习的进程一下中断了半年时间。最开始是因为项目的原因、之后是新年、然后是新冠……,当然,最重要的原因是懒,哈哈。
第二十一天
今天要学习的是《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 分钟后系统自动杀掉。
关于查询及索引
- 理论上是要每个查询都需要有对应的索引,因为 mongodb 没有资源隔离,慢查询会影响系统的所有操作。
- 尽量使用 Covered Indexes 索引(从索引里看出来要取的字段了,避免去读数据文件)。
- 需要啥字段就读啥字段,别一下都读出来,然后到客户端再过滤,提高性能
关于写入
- 更新啥就写啥更新字段
- 使用批量写入来提高性能
- 使用 TTL 索引,来处理自动过期的日志类型的数据,到期会自动删除
关于文档结构
- 别使用太长的字段名,浪费存储空间
- 数据嵌套别太多,虽然 mongodb 支持多层嵌套,别超过 2 层。
- 使用英文字母来当字段名,别使用中文、标点符号等
处理分页
避免使用 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);
关于事务
- 不建议使用事务,效率太低
- 建议通过模型设计来避免事务的使用,一个文档解决就好
- 如果非要用,别使用大事务(这里指超过 1000 个文档的事务),小批量来处理,因为 60 秒默认超时限制
- 必须使用事务时,也要让文档都分布在一个分片上(虽然支持存在多个分片上),提高性能
最后
好啦,今天的学习到此结束,明天开始学习第三章运维的部分,同时复习一下第二章的内容。
正文完