难度:简单 |
MongoDB 8.0已经推出有一段时间了,今天来聊聊8.0有哪些值得关注的新东西。相比之前的版本推出新功能,8.0的主要精力集中在提升性能和可维护性上面,可以说是目前性能最好的一个版本。
1 新版的TCMalloc
8.0版本性能提升的一个重要原因来自于使用了新的TCMalloc,从而能够使用per-CPU Cache,取代了7.0及之前版本中的per-thread Cache。用工程师团队的话说,这是一个非常激进的决定。内存管理涉及了整个MongoDB的运行过程,动它无异于心脏置换手术,风险很高。但相应地,这个改动使得内存碎片问题得到有效控制,从而在高压力环境中表现得更佳。
此处跳过若干TCMalloc的工作原理问题(反正我也讲不明白),总之结果是:
- 降低了18%内存碎片
- 碎片产生更慢
为了使新的TCMalloc更好地工作,运行8.0时请注意以下几点优化措施:
- 启用THP (Transparent Huge Pages)。没错,8.0开始THP启用时性能更好。
- 使用RSEQ启用per-CPU Cache。
- 使用受支持的系统。大部分人应该不会遇到这个问题。只有ppc64le和s390x平台才需要考虑。
相关说明已经在文档中有说明,请参考:链接2。
2 setQuerySettings
通过新命令setQuerySettings(链接3)可以为不同的查询模式做一些定制,主要包括两方面功能:
2.1 持久化hint
设想在运行过程中你发现一个查询选择的索引不是最优的,虽然这种情况并不多见,但如果想要人工干预,你只有以下两种选择:
- 在代码中找到这个查询,在执行时通过hint指定你要的索引;
- 在服务端设置query plan filter;
无论哪种做法都有明显的缺陷:前者需要修改代码重新上线,很不灵活。后者可以实时生效,但不能持久化,重启即失效。8.0相当于能够在服务端随时指定hint,并且能够持久化,重启后仍然有效。
用法并不复杂,请参考文档不再赘述。一点需要说明的是如何识别你想定制的查询模式:
- 通过指定查询字段,排序字段,集合……当所有这些都匹配时,这个查询就是你要找的查询,hint将对它生效。注意只是匹配字段,不包括值。比如{age: 60}跟{age: 70}是同一个查询,尽管它们的查询值不同。
- 通过queryHash来匹配。queryHash可以在慢查询或者profiling记录中找到。
个人倾向于使用后者,更方便。本质上它与前者等价,只是做了个Hash变成一个更简短的字符串。
2.2 拒绝查询
设想运行过程中发现一个没命中索引的查询,消耗了大量资源,作为DBA你要怎么做?第一想法肯定是要Kill掉所有造成问题的查询来缓解问题。但这并不足够,因为不断会有新的同样的查询涌进来,直到:
- 应用方面重新上线停止了这个查询,或者
- 创建了合适的索引解决了问题
显然前者依赖应用上线,不是短时间能够完成的工作。而且前者没有解决的情况下,大量资源消耗在慢查询上又会造成后者难以完成,而且在完成过程中整个系统效率会更低,因为建索引本身也是一个消耗极大的任务。基于这种情况,8.0提供了一个迅速拒绝某种查询模式的功能来暂时规避问题:所有符合查询模式或者queryHash的查询都会被直接拒绝,以此立即缓解线上问题。
这个功能通过setQuerySettings的reject实现,具体请参考文档(链接3)。
一点需要注意的情况是,这个配置只对新查询有效。如果一个慢查询已经在执行中,不会被立即杀掉,你仍然需要等它执行完,或人工kill掉。
3 默认读超时
在以前的版本中读超时是通过应用端在连接字符串或者驱动API中指定的。在理想情况下一个查询执行多长时间确实应该由应用决定,也只有应用最清楚。但现实是,并不是所有时候应用都能准确地给出查询需要执行的时间,又或者根本忘记指定最长执行时间。后者我在现实中见过很多。
同样当遇到线上问题时,动应用通常都不是最快的解决办法。有什么管理员能做的事情?从8.0开始MongoDB允许在服务端设置一个默认超时时间。所有没有超时时间的查询均遵循这个超时时间,过时不候。而原先设置了超时时间的查询,仍然以客户端的设置为准。
同样需要注意,设置只对新进入的查询生效,旧操作仍然需要自己处理或者等待超时。
db.adminCommand({ setClusterParameter: { defaultMaxTimeoutMS: { readOperations: 5000 } } }); db.adminCommand({ getClusterParameter: “defaultMaxTimeoutMS” }); |
更多请参考:链接4
4 总结
8.0的宗旨在加强性能上,相较7.0,某些类型的查询和更新性能甚至提供了25%以上。本期先说了一部分,下期继续。
5 参考文档
- 链接1 – RSEQ:https://github.com/google/tcmalloc/blob/master/docs/design.md#restartable-sequences-and-per-cpu-tcmalloc
- 链接2 – TCMalloc Performance Optimization for a Self-Managed Deployment:https://www.mongodb.com/docs/manual/administration/tcmalloc-performance/
- 链接3 – setQuerySettings:https://www.mongodb.com/docs/manual/reference/command/setQuerySettings/
- 链接4 – defaultMaxTimeMS:https://www.mongodb.com/docs/manual/reference/cluster-parameters/defaultMaxTimeMS/
关于作者:
张耀星,MongoDB Distinguished Engineer,10余年MongoDB使用经验,供职于MongoDB售后服务团队8年。 |
评论前必须登录!
注册