• MongoDB开发最佳实践


    MongoDB开发最佳实践

    1. 连接到MongoDB · 关于驱动程序:总是选择与所用之MongoDB相兼容的驱动程序。这可以很容易地从驱动兼容对照表中查到;

       · 如果使用第三方框架(如Spring Data),则还需要考虑框架版本与驱动的兼容性;
      

      · 关于连接对象MongoClient:使用MongoClient对象连接到MongoDB实例时总是应该保证它单例,并且在这个生命周期 中都从它获取其他操作对象。

      · 关于连接字符串:连接字符串中可以配置大部分连接选项,建议总是在连接字符串中配置这些选项;

      // 连接到复制集 mongodb://节点1,节点2,节点3.../database?[options]

      // 连接到分片集 mongodb://mongos1,mongos2,mongos3.../database?[options]

    2. 常见连接字符串参数 · maxPoolSize

       · 连接池大小
      

      · maxWaitTime

       · 建议设置,自动杀掉太慢的查询
      

      · writeConcern

       · 建议majority保证数据安全
      

      · readConcern

       · 对于数据一致性要求高的场景适当使用 
      
    3. 连接字符串节点和地址 · 无论对于复制集或分片集,连接字符串中都应尽可能多地提供节点地址,建议全部列出;

       · 复制集利用这些地址可以更有效地发现集群成员;
       
       · 分片集利用这些地址可以更有效的分散负载;
      

      · 连接字符串中尽可能使用与复制集内部配置相同的域名或IP;

    4. 使用域名连接集群 在配置集群时使用域名可以为集群变更时提供一层额外的保护。例如要将集群整体迁移到新网段,直接修改域名解析即可。

      另外,MongoDB提供的mongoDB+srv://协议可以提供额外一层保护。该协议允许通过域名解析得到所有mongos或节点的地址, 而不是写在连接字符串中。

      mongodb+srv://server.example.com/

      Record TTL Class Priority Weight Port Target _mongodb._tcp.server.example.com.86400

      IN SRV 0 5 27317 mongodb1.example.com._mongodb._tcp.server.example.86400 IN SRV 0 5 27017 mongodb2.example.com.

    5. 不要在mongos前面使用负载均衡 基于前面提到的原因,驱动已经直销在不同的mongos之间实现负载均衡,而复制集则需要根据节点的角色来选择发送请求的目标。 如果在mongos或复制集上层部署负载均衡:

      · 驱动会无法探测具体那个节点存活,从而无法完成自动故障恢复;

      · 驱动会无法判断游标是在哪个节点创建的,从而遍历游标时出错;

      结论:不要在mongos或复制集上层放置负载均衡器,让驱动处理负载均衡和自动故障恢复。

    6. 游标使用 如果一个游标已经遍历完,则自动关闭;如果没有遍历完,则需要手动调用close()方法,否则该游标将在服务器上存在 10分钟(默认值)后超时释放,造成不必要的资源浪费。

      但是,如果不能遍历完一个游标,通常意味着查询条件太宽泛,更应该考虑的问题是如何将条件收紧。

    7. 关于查询及索引 · 每一个查询都必须要有对应的索引

      · 尽量使用覆盖索引Covered indexes(可以避免读数据文件)

      · 使用projection来减少返回客户端的文档内容

    8. 关于写入 · 在update语句里只包括需要更新的字段

      · 尽可能使用批量插入语句来提升写入性能

      · 使用TTL自动过期日志类型的数据

    9. 关于文档结构 · 防止使用太长的字段名(浪费空间)

      · 防止使用太深的数组嵌套(超过2层操作比较负责)

      · 不使用中文,标点符号等非拉丁字母作为字段名

    10. 处理分页问题-避免使用count 尽可能不要计算总页数,特别是数据量大和查询条件不能完整命中索引时。

      考虑以下场景:假设集合总共有1000W条数据,在没有索引的情况下考虑以下查询:

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

      · 前者只需要遍历前n条,直到找到50条队伍 x = 100 的文档即可结束;

      · 后者需要遍历完1000W条所有符合要求的文档才能得到结果。

      为了计算总页数而进行count()往往是拖慢页面真题加载速度的原因。

    11. 处理分页问题——巧分页 避免使用skip/limit形式的分页,特别是数据量大的时候;

      替代方案:使用条件查询+唯一条件排序;

      例如:

      第一页:db.find({}).sort({_id: 1}).limit(20);

      第二页:db.find({_id:{$gt:<第一页最后一个_id>}}).sort({_id: 1}).limit(20);

      第三页:db.find({_id:{$gt:<第二页最后一个_id>}}).sort({_id: 1}).limit(20);

      ······

    12. 关于事务 使用事务的原则:

      · 无论何时,事务的使用总是能避免则避免;

      · 模型设计先于事务,尽可能用模型设计规避事务;

      · 不要使用过大的事务(尽量控制在1000个文档更新以内);

      · 当必须使用事务时,尽可能让涉及事务的文档分布在同一片上,这将有效地提高效率;

  • 相关阅读:
    py pandas
    wxPython 创建基本窗口
    js 动态修改页面文本字体
    uniapp 万年历
    uniapp设置不同的主题(Theme)
    flutter 插件调用callback函数
    题解:[SDOI2009]HH的项链
    模板:线段树(2)——加法,乘法,求和
    模板:KMP算法
    模板:单源最短路径。堆优化的dijkstra。
  • 原文地址:https://www.cnblogs.com/w3liu/p/12380460.html
Copyright © 2020-2023  润新知