在最近的一个客户项目上,为了做性能优化,我们花了大量的时间,然而最终结果还是不够理想。我们的场景是实现特征处理过程和机器学习模型线上推理服务。由于用户量巨大,我们需要做到2万的TPS,每个请求需要在30ms内返回,且每个请求中包括对1000个项目的处理过程。
我们所使用的技术栈是spring
和grpc
。在经过极致的代码优化及内存调优之后,运行在一台32GB
内存64核
CPU的服务器上,我们发现90%
的请求可以在25ms
完成。但是如果观察99%
的分位线时,响应时间就下降到了70ms
,有时候还可能超过100ms
。
为什么会出现上面这么明显的波动呢?问题出在java
的gc
上。其实对于gc
,我们已经非常仔细的做过调优了,整个过程没有full gc
的发生。然而,在持续的压力测试下,java
的young gc
却在频繁的工作。由于处理的数据量过大,新生代的gc
几乎每秒都会触发一次,每次释放5GB
内存,耗时30ms
左后。