关于节点新旧版本的性能问题

有时,支持旧节点应用程序的开发人员对于将应用程序从旧版本转移到新节点的需求有疑问。 支持保留旧功能的主要论据是“我不使用新功能,但是它们的实现肯定会减慢整个处理的速度。” 另外,由于存在对新节点不再支持的库的依赖关系,因此情况可能会变得非常复杂,并且节点版本的更改会自动转换为对应用程序体系结构的重大处理。 我希望我的文章可以帮助他们决定这个问题。

在您开始之前,我提醒您IT业务的基本原则:工作,请勿触摸!

如果您的应用程序按其应有的方式工作,并且能够完全处理任务,并且没有紧迫的处理需求,则最好保留所有内容。 回收可能是一个非常痛苦而漫长的过程。 结果,除了获得审美上的满足感之外,您将不会获得任何切实的利益,并且此时您的企业将蒙受损失。

我的文章适合那些仍然有需要的人。 我将描述我的最新情况,讨论解决该问题时遇到的困难,并给出最终得到的结果。

我正在开发一个用于收集和处理其他应用程序日志的系统。 建立的工作负载-每个组件每分钟数十万条日志。 该系统水平扩展良好,具有模块化体系结构,成功工作了一年以上,并能应对整个功能。 节点的使用版本为0.10

你要面对什么

自然,不缺少功能。 es6的新功能甚至都没有被考虑。 当然,它们使生活更美好,但仅此而已。 对于我们的任何任务,旧节点的功能就足够了。 随着功能变得更加复杂,问题出现在最意想不到的地方。

问题一:

峰值负载和低于5GB的内存消耗的组件之一突然开始缓慢地变慢。 通常并不是在高峰期结束时每次都自发地出现问题。 如果应用程序没有超时,则性能会在半小时或一个小时内逐渐恢复。 重新启动立即解决。

经过“深度调试”过程后,事实证明整个过程开始变慢,甚至同步操作也开始变慢,这就是为什么可以得出结论,垃圾收集器本身正在“变得更糟”。 完全不清楚该怎么做。 唯一的解决方案是在几个月内搜索代码更改历史并回滚重要功能。 另一方面,该问题并非每天都经常发生,并且手动重启系统似乎也是完全可以接受的解决方案(手动表示基于积压检测器信号的脚本)。 我们更倾向于第二种选择。 如果不是第二个问题,那么很可能已经实现了。

第二个问题:

我们的另一个组件正在消耗大量内存。 由于此组件实际上是缓存,因此原则上可以解释其“贪婪”。 直到需要从上方将其限制为严格指定的体积为止。 然后事实证明,该组件正在获得内存,并不急于放弃它。 甚至以几乎空转的速度工作。 也就是说,在峰值负载时,节点内存管理器选择了最大内存,即使有余量,也一直保留到本世纪末(例如,重新启动组件)。 我将立即提到泄漏选项已经过检查和验证。 las,没有泄漏,而我们又陷入了死胡同。

我试图在Internet上的各个地方询问如何执行节点的内存管理以及如何解决我们的情况。 但是作为回应,我对使用0.10节点只抱有很多负面意见。 通常,正是这种消极情绪使我开始着手切换到最新版本的节点。

什么阻碍了?

1.担心生产力下降。

那些使用python的人记得,从2.x到3.x的过渡是伴随着生产力的大幅下降。 我现在不知道python中的情况如何,也许情况有所改善。 但是可以预料,在将所有这些新功能添加到es6中之后,该节点也可以稳定地下沉。 我试图用Google搜索一些基准,以将新节点与旧节点进行比较,但没有发现任何明智的方法。

2.性能JSON.parse

由于我们使用日志,因此JSON.parse占据了处理器的最大份额。 一次,我们在不同版本的节点上进行了比较,性能下降了约30%。 将4.x节点与0.10和0.12进行比较。

实际上,这些原因并不是决定性的,因为处理器不是瓶颈。 此外,对于此类任务,还有水平缩放。

3.包依赖性

但这是一个绊脚石。 我们最复杂的中央组件使用libmysqlclient软件包,该软件包仅在节点0.10下工作。 更糟糕的是,它的同步调用。 也就是说,如果不深入处理组件架构从部分同步到完全异步的处理,就不可能简单地更改mysql驱动程序,用一个调用替换另一个调用。 而且,此任务中最困难的部分不是处理本身,而是如何证明管理层的需求合理性并表明它将为项目带来什么:)

什么给了?

结果,我们仍然从节点0.10移到最后的lts8.11.x。

1.不降低性能。 相反,我们收到了10-15%的数量级增长
2.显着提高内存消耗,大约30-50%(取决于组件)
3.上面提到的“无法解决”的问题由他们自己解决了
4.我们终于有机会使用es6的新功能! 尽管出于习惯,我们仍然不使用它们)))

Source: https://habr.com/ru/post/zh-CN413673/


All Articles