首页 > 数据库 >MongoDB运行环境的十个建议

MongoDB运行环境的十个建议

时间:2023-07-29 14:00:56浏览次数:42  
标签:regex MongoDB 十个 使用 查询 索引 分片 运行

 

1.生产环境始终开启身份验证
这不是性能建议,而是安全建议。
安装后建议创建admin用户,重启mongodb实例并开启身份验证:

> use admin
switched to db admin
> db.createUser({
...   user: "abce",
...   pwd: "password",
...   roles : [ "root" ]
... })
Successfully added user: { "user" : "abce", "roles" : [ "root" ] }
Then, you need to enable authorization and restart the instance, if you are deploying MongoDB from the command line:
mongod --port 27017 --dbpath /data/db --auth
Or if you are deploying MongoDB using a config file, you need to include:
security:
    authorization: "enabled"

 

2.升级到主要版本的最新补丁集
如果是历史遗留应用或驱动程序的依赖问题而必须使用EOL版本,建议尽快升级应用
不要使用带有"critical issues"或"not recommended for production use"提醒的版本。这些版本中包含的错误可能会严重影响性能或导致数据完整性问题,从而可能造成数据损坏或数据丢失。
建议在从初始构建、测试到生产的所有开发阶段保持一致,因为这样可以减少我们需要支持的变量数量、出现问题的可能性以及管理所有这些实例的成本。

关注版本发布说明,比如5.0版本:

https://www.mongodb.com/docs/upcoming/release-notes/5.0/

生命周期计划说明:

https://www.mongodb.com/support-policy/lifecycles

 

3.生产环境始终使用至少三个节点的复制集
最佳做法是拥有奇数个复制集成员,以维持法定投票人数。副本集的最小成员数为三个节点。目前,一个副本集最多可有 50 个节点。其中只有 7 个成员拥有投票权。这些投票权决定了在出现问题、故障切换或选举时哪个成员成为主要成员。
在副本集的所有节点上安装相同的硬件配置非常重要。


在生产环境中部署副本集后,检查副本和节点的健康状况非常重要。在实际操作中,MongoDB 有两个重要的检查命令。
rs.status()使用从副本集其他成员发送的心跳包中获取的数据,提供副本集当前状态的信息。作为检查副本集中所有节点状态的工具,它非常有用。
rs.printSecondaryReplicationInfo() 提供了复制集状态的格式化报告。检查是否有辅助节点在数据复制上落后于主节点是非常有用的,因为这将影响你在出错时恢复所有数据的能力。如果辅助服务器落后于主服务器太远,那么最终丢失的数据可能会多得多。

不过,这些命令提供的是时间点信息,而不是对副本集健康状况的持续监控。在实际生产环境中,或者如果你有很多集群需要检查,运行这些命令会变得既耗时又烦人,因此我们建议使用集群监控系统(如 Percona Monitoring and Management)来监控它们。

 

4.避免使用成本昂贵的查询类型或操作符
有时,在数据库中检索的最简单方法就是使用正则表达式或$regex操作。很多开发人员都会选择这种方法,但它实际上会对大规模检索操作造成损害。相反,你必须避免使用$regex查询,尤其是当你的数据库很大时。

$regex查询会消耗大量的CPU时间,通常会非常缓慢且效率低下。创建索引也不会有太大帮助,有时性能还会比没有索引时更差。

例如,我们可以在一个包含1,000万个文档的集合上使用$regex查询,并使用.explain(true)查看查询耗时多少毫秒。

没有索引:

>db.people.find({"name":{$regex: "abce"}}).explain(true)
- -   Output omitted  - -
"executionStats" : {
                "nReturned" : 19851,
                "executionTimeMillis" : 4171,
                "totalKeysExamined" : 0,
                "totalDocsExamined" : 10000000,
- -   Output omitted  - -
And if we created an index on "name":
db.people.find({"name":{$regex: "abce"}}).explain(true)
- -   Output omitted  - - 
  "executionStats" : {
                "nReturned" : 19851,
                "executionTimeMillis" : 4283,
                "totalKeysExamined" : 10000000,
                "totalDocsExamined" : 19851,
- -   Output omitted  - -

从这个示例中可以看出,创建索引无助于提高$regex的性能。
使用$regex操作的新应用程序很常见。这是因为一开始开发人员和DBA都没有注意到性能方面的问题,因为集合的大小很小,而且任何应用程序开始时的用户都很少。
但是,当集合变大,越来越多的用户开始使用应用程序时,$regex 操作就会开始拖慢集群的运行速度,成为团队的噩梦。随着时间的推移,随着应用程序规模的扩大,越来越多的用户希望执行检索请求,性能水平会显著下降。
可以使用文本索引来支持文本检索,而不是使用$regex查询。这比$regex更有效,但需要提前做好准备,在数据集中添加文本索引。它们可以包括任何值为字符串或字符串元素数组的字段。一个集合只能有一个文本索引,但该索引可以覆盖多个字段。

使用示例中的相同集合,我们可以测试使用文本检索进行相同查询需要多少毫秒:

> db.people.find({$text:{$search: "abce"}}).explain(true)
- -   Output omitted  - -
"executionStages" : {
                         "nReturned" : 19851,
                        "executionTimeMillisEstimate" : 445,
                        "works" : 19852,
                        "advanced" : 19851,
- -   Output omitted  - -


实际上,用文本检索进行同样的查询比用$regex查询少花了4秒钟。在"数据库时间"上,4秒钟就已经不少了,更不用说在线应用时间了。

总之,如果使用文本检索可以解决查询问题,请使用文本检索而不要使用$regex,并将$regex保留给真正需要的用例,同时始终限制使用其他查询模式和操作符,如findAndModify和$NIN。

 

5.正确地选择索引策略
一开始就对查询进行一些思考,随着时间的推移会对性能产生巨大影响。首先,需要了解应用程序以及作为服务一部分的预期查询类型。在此基础上,可以创建支持这些查询的索引。

索引可以帮助加快读取查询的速度,但会带来额外的存储成本,而且会降低写入操作的速度。因此,需要考虑哪些字段应该创建索引,以避免创建过多索引。

例如,如果要创建复合索引,那么必须遵循"等价、排序、范围"规则,使用索引对结果进行排序可以提高查询速度。

同样,你也可以使用.explain()检查你的查询是否真的使用了创建的索引。有时,我们会看到一个已创建索引的集合,但查询要么没有使用索引,要么完全使用了错误的索引。重要的是,只创建读取查询实际会用到的索引。创建永远不会使用的索引不仅浪费存储空间,还会降低写入操作的速度。

查看.explain()输出时,有三个主要字段值得注意。例如:

keysExamined:0 
docsExamined:207254 
nreturned:0


这个例子中,没有使用索引。这是因为检查的键数是0,而检查的文档数是207254。理想情况下,查询需要达到nreturned/keysExamined=1的比率。例如:

keysExamined:5 
docsExamined: 0 
nreturned:5


最后一点建议是,如果使用.explain()发现某个查询使用了错误的索引,可以使用.hint()强制查询使用特定的索引,这将覆盖MongoDB的默认索引选择和查询优化过程,允许指定使用的索引,或执行正向集合或反向集合扫描。

 

6.关注查询模式、应用程序变化或索引使用随时间的变化情况
每个数据库都是独一无二的,都是应用所特有的,都会随着时间的推移而增长和变化。没有人知道应用程序会如何随时间推移而增长,也没有人知道查询会如何随时间推移而变化。无论你做了什么假设,你的预测都不可避免地会出错,因此随着时间的推移检查你的数据库和索引是非常重要的。

例如,你可能会规划一个特定的查询优化方法和一个特定的索引,但一年后,你发现有几个查询正在使用该索引,而它已不再必要。继续使用这种方法会增加存储成本,却无法提高应用程序性能。因此,有必要执行查询优化,并经常查看每个集合的索引。

MongoDB提供了一些查询优化工具,如数据库profiler或.explain()方法;我们建议使用这些工具来查找哪些查询速度较慢、查询如何使用索引以及哪些地方需要改进优化。

除了移除使用效率不高的索引外,还要注意是否存在不需要运行的重复索引。

可以使用一些脚本来检查是否存在重复索引或未使用的索引。你可以从以下地址检查并使用它们:

https://github.com/percona/support-snippets/tree/master/mongodb/scripts

同样,你还可以查看希望从查询中获得多少结果,因为提供过多结果会影响性能和时间。可以使用.limit()限制查询结果的数量,因为有时只需要查询的前五个结果,而不是几十个或几百个。另一种有用的方法是使用投影,只获取必要的数据。如果只需要文档中的一个字段,可以使用投影而不是获取整个文档,然后在应用程序端进行过滤。最后,如果需要对查询结果进行排序,请确保使用了索引,并利用索引提高效率。

 

7.不要在同一服务器上运行多个MongoD
即使可以在同一服务器上使用不同进程和端口运行多个 MongoD,我们也强烈建议不要这样做。

在同一服务器上运行多个MongoD进程时,很难监控它们及其所消耗的资源(CPU、内存、网络等)。因此,如果出现任何问题,就很难找出问题所在并找到问题的根本原因。

我们遇到过很多客户发现服务器资源出现问题的情况,但由于他们运行的是多个 MongoD 实例,因此无法排除故障,因为发现哪个特定进程出现问题比较困难。

同样,有时我们会看到开发人员实施了分片集群来扩展应用数据,但在同一台服务器上却运行着多个分片。在这种情况下,路由器会向同一个节点发送大量查询。这可能会导致节点超载,从而导致性能低下,这与分片策略想要解决的问题恰恰相反。

 

8.制定可靠而且强大的备份策略

 

9.了解何时对副本集进行分片以及如何选择分片键很重要
分片是使用MongoDB部署的最复杂的架构
随着数据库的增长,你需要为服务器增加更多容量。这可能涉及增加内存、I/O 容量,甚至是更强大的CPU 来处理数据。这就是所谓的纵向扩展。但是,如果数据库增长过快,超出了单台机器的容量,那么可能需要分担工作负载。有几种情况可能导致这种情况,例如,可能没有足够大的物理服务器来处理工作负载,或者服务器实例的成本太高,无法承受。在这种情况下,需要开始考虑将数据库分片,这就是所谓的水平扩展。

选择分片键一定是MongoDB上最困难的任务。在选择分片键之前,有必要思考、研究数据集和查询,并提前做好计划,因为一旦进行了分片,就很难再恢复了。对于4.2版之前的MongoDB版本,分配分片键是一个单向过程,无法撤销。对于4.4以上的MongoDB版本,可以完善分片键,而MongoDB 5.0及以上版本则可以使用reshardCollection命令更改分片键。

如果选择了一个糟糕的分片键,那么很大一部分文档可能会被分到其中一个分片,而只有少数文档被分到另一个分片。


这将导致分片集群不平衡,并随着时间的推移影响性能。这种情况通常发生在选择单调增长的分片键对集合进行分片时,因为所有超过给定值的文件都会被分到一个分片,而不是平均分配。

除了考虑用于分片数据的值,还需要考虑在分片上进行的查询。查询必须使用分片键,这样MongoS才能在分区集群中分配查询。如果查询不使用分片键,那么MongoS就会将查询发送到集群的每个分片,从而影响性能,使分片策略效率低下。

 

10.不要一掷千金地解决问题
最后,但并非最不重要的一点是,团队在数据库问题上一掷千金的情况非常常见。增加内存、CPU,以及迁移到更大的实例或更大的机器都可以解决性能问题。但是,如果不分析真正的问题或瓶颈就采取这种行动,将来可能会出现更多同样的问题。不如横向思考,想象一个更好的解决方案。在大多数情况下,答案并不是在资源上花更多的钱,而是在同一水平上优化你的实施,以获得更好的性能。

标签:regex,MongoDB,十个,使用,查询,索引,分片,运行
From: https://www.cnblogs.com/abclife/p/17589689.html

相关文章

  • 3-1 在上面有关折半查找的例子中,while 循环语句内共执行了两次测试,其实 只要一次就足
    ArchlinuxGCC13.1.1 202304292023-07-2911:07:02星期六 点击查看代码#include<stdio.h>intbinsearch(intx,intv[],intn){intlow,high,mid;low=0;high=n-1;mid=(low+high)/2;while((low<=high)&&(......
  • C#计算代码运行时间(Stopwatch的使用)
    一、什么是StopwatchStopwatch:提供一组方法和属性,可以准确的测量运行时间。使用的时候需要引用命名空间:System.Diagnostics。 二、Stopwatch的简单使用//创建Stopwatch实例Stopwatchsw=newStopwatch();//开始计时sw.Start();for(inti=0;i<100;i++){Cons......
  • 安装spark local运行出现错误NoClassDefFoundError: org/slf4j/Logger 原来是要设置
    Error:Unabletoinitializemainclassorg.apache.spark.deploy.SparkSubmitCausedby:java.lang.NoClassDefFoundError:org/slf4j/Logger HowtoinstallsparklocallyConsideringsparkwithouthadoopbuilt-in.Downloadhadoopunpackto/opt/hadoop/Downloadsp......
  • Dapr中国社区活动之 分布式运行时开发者日 (2022.09.03)
    自2019年10月首次发布以来,Dapr(DistributedApplicationRuntime,分布式应用运行时)因其“更稳定”、“更可靠”、“更一致”、“更简单”,吸引了大量的关注和喜爱,至今在GitHub上已有近1.9万Stars,俨然已成为开发者圈的新晋“网红”。Dapr具备先天的跨语言优势,其设计更是从根基上兼......
  • Windows本地IDEA运行mapreduce报错java.io.FileNotFoundException: HADOOP_HOME and h
    问题原因在windows运行hadoopJob程序的时候需要模拟下hadoop的运行环境。否则出现会出现标题的问题。解决方案下载Hadoop的bin目录https://github.com/s911415/apache-hadoop-3.1.3-winutils将步骤1中下载的文件配置成环境变量HADOOP_HOME(指向解压之后的的bin的上级目录)。......
  • dephi RTI (Runtime Type Information)获取运行时的控件信息
    varEdit:TComponent;beginEdit:=FindComponent("Edit1");IfEditisTEditthenTEdit(Edit).Text:='你好Delphi7';end;  RTTI(RunTimeTypeInformation):运行时类型信息,就是在程序运行后也能得到类型(譬如TButton类)的信息. 这在早期主要用于IDE......
  • How to uninstall MongoDB from Mac
    TocompletelydeleteanyversionofMongoDBfromMac,followthebelowstepsontheterminal:Checkifanymongoserviceisrunning:launchctllist|grepmongoIfyouhadinstalledMongoDBusingHomebrew,unloadmongodb:launchctlunload~/Library/Launch......
  • Mongodb的部署和应用
    1、MongoDB的作用和优势 1)MongoDB 存储的是关系数据 读写速度快 2)特点  面向集合存储数据,Mongodb不在包含表信息 支持动态查询、索引、类SQL语言进行管理 采用二进制数据进行存储 支持Python、Java、php、javascript、C++2、Mongodb支持的应用场景和不适合场......
  • Mongodb的部署和应用
    1、MongoDB的作用和优势 1)MongoDB 存储的是关系数据 读写速度快 2)特点  面向集合存储数据,Mongodb不在包含表信息 支持动态查询、索引、类SQL语言进行管理 采用二进制数据进行存储 支持Python、Java、php、javascript、C++2、Mongodb支持的应用场景和不适合场......
  • linux服务:基本介绍 | linux运行级别和服务 | 基本服务指令service
    摘要介绍linux的服务介绍service指令一、linux服务介绍服务(service):本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如(mysqld,sshd防火墙等),因此我们又称为守护进程。linux的后台服务,每个服务在一个端口监听(比如mysqld服务,在3306端口监......