案例实战:每秒10万并发的BI系统是如何频繁发生Young GC的?

扫描下方海报二维码,试听课程:
前端

(课程详细大纲,请参见文末)面试

=========================================架构

本文来源于公众号狸猫技术窝的专栏:
并发

《从零开始带你成为JVM实战高手》分布式

是做者救火队队长开放的试读文章高并发

救火队队长,阿里资深技术专家oop

=========================================
性能

一、前文回顾

本周咱们的一个重点就是给你们再次强调JVM频繁GC对系统性能的危害性。大数据

所以在分析完JVM发生GC的场景以及原理,以及梳理清楚各类GC名词的概念和触发时机以后,咱们就能够来用两个以前咱们线上系统真实的案例来给你们再次在脑海中强化一下频繁GC带来的性能问题。优化

二、服务于百万级商家的BI系统是什么?

先给你们说一下咱们线上一个真实的生产系统,是一个服务于百万级商家的BI系统。

这个所谓BI系统,不少开发业务系统的同窗可能没接触过,因此简单介绍一下他的背景。

简单来讲,好比你是一个平台,而后有数十万甚至上百万的商家在你的平台上作生意,会使用你的这个平台系统

此时必定会产生大量的数据,基于这些数据咱们须要为商家提供一些数据报表

好比:每一个商家天天有多少访客?有多少交易?付费转化率是多少?

固然实际状况会比这个简单几句话复杂不少,这里就是简单说一下它的概念。

所以就须要一套BI系统,所谓BI,英文全称是“Business Intelligence”,也就是“商业智能”,听起来是否是特别的高大上?

其实也别想的过高大上了,说白了,就是把一些商家平时平常经营的数据收集起来进行分析,而后把各类数据报表展现给商家的一套系统。

所谓“商务智能”,指的就是给你看一些数据报表,而后让你平时可以更好的了解本身的经营情况,而后让老板“智能”的去调整经营策略,提高业绩。

因此相似这样的一个BI系统,大体的运行逻辑以下所示,首先从咱们提供给商家平常使用的一个平台上会采集出来不少商家平常经营的数据。

以下图所示:

接着就能够对这些经营数据依托各类大数据计算平台,好比Hadoop、Spark、Flink等技术进行海量数据的计算,计算出来各类各样的数据报表。

以下图所示:

而后咱们须要将计算好的各类数据分析报表都放入一些存储中,好比MySQL、Elastcisearch、HBase均可以存放相似的数据

以下图所示:

最后一步,就是基于MySQL、HBase、Elasticsearch中存储的数据报表,基于Java开发出来一个BI系统。

而后经过这个系统,把各类存储好的数据暴露给前端,容许前端基于各类条件对存储好的数据进行复杂的筛选和分析。

以下图所示:


三、刚开始上线系统时候的部署架构

咱们在这里重点做为案例分析的就是上述场景中的BI系统,其余环节都跟大数据相关的技术是有关联的,暂时先不涉及,将来有机会能够给你们出更多的课程来阐述那些技术。

刚开始,这个BI系统使用的商家是很少的。

由于你们要知道,即便在一个庞大的互联网大厂里,虽然大厂自己积累了大量的商家,可是你要是针对他们上线一个付费的产品,刚开始未必全部人都买帐

因此一开始系统上线大概就少数商家在使用,好比就几千个商家。

所以刚开始系统部署的很是简单,就是用几台机器来部署了上述的BI系统,机器都是普通的4核8G的配置

而后在这个配置之下,通常来讲给堆内存中的新生代分配的内存都在1.5G左右,Eden区大概也就1G左右的空间

以下图所示:


四、技术痛点:实时自动刷新报表 + 大数据量报表

其实刚开始,在少数商家的量级之下,这个系统是没多大问题的,运行的很是良好,但问题就出在使用系统的商家数量开始暴涨的时候。

忽然使用系统的商家开始愈来愈多,好比给你们举个例子,当商家的数量级达到几万的时候。

此时要给你们说明一个此类BI系统的特色,就是在BI系统中有一种数据报表,他是支持前端页面有一个JS脚本,自动每隔几秒钟就发送请求到后台刷新一下数据的。

这种报表称之为“实时数据报表”,以下图所示:

那么你们能够设想一下,假设仅仅就几万商家做为你的系统用户,极可能同一时间打开那个实时报表的商家就有几千个

而后每一个商家打开实时报表以后,前端页面都会每隔几秒钟发送请求到后台来加载最新数据。

这时基本上会出现你的BI系统部署的每台机器每秒的请求会达到几百个,这里就假设每秒500个请求。

而后每一个请求会加载出来一张报表须要的大量数据,由于BI系统可能还须要针对那些数据进行内存中的现场计算加工一下,才能返回给前端页面展现。

根据咱们以前的测算,每一个请求大概须要加载出来100kb的数据进行计算,所以每秒500个请求,就须要加载出来50MB的数据到内存中进行计算。

以下图所示:

五、没什么大影响的频繁Young GC

其实你们都已经发现上述系统的问题了,在上述系统运行模型下,基本上每秒会加载50MB的数据到Eden区中。

也就是说,只要区区200s,也就是3分钟左右的时间,就会迅速填满Eden区,而后触发一次Young GC对新生代进行垃圾回收。

固然1G左右的Eden进行Young GC其实速度相对是比较快的,可能也就几十ms的时间就能够搞定了。

因此以前也分析过,这其实对系统性能影响并不大。并且上述BI系统场景下,基本上每次Young GC后存活对象可能就几十MB,甚至是几MB。

因此若是仅仅只是这样的话,你们可能会看到以下场景,BI系统运行几分钟事后,就会忽然卡顿个10ms,可是对终端用户和系统性能几乎是没有影响的

以下图:


六、提高机器配置:运用大内存机器

针对这样的一套系统,后来随着愈来愈多的商家来使用,并发压力愈来愈大,甚至高峰期会有每秒10万的并发压力

若是仍是用4核8G的机器来支撑,那么可能须要部署上百台机器来抗住每秒10万的高并发压力。

因此通常针对这种状况,咱们会提高机器的配置。

自己BI系统就是很是吃内存的系统,因此咱们将部署的机器全面提高到了16核32G的高配置机器上去。每台机器能够抗个每秒几千请求,此时只要部署二三十台机器就能够了。

可是此时问题就来了,若是要是用大内存机器的话,那么新生代至少会分配到20G的大内存,Eden区也会占据16G以上的内存空间。

以下图所示:


此时每秒几千请求的话,每秒大概会加载到内存中几百MB的数据,那么大概可能几十秒,甚至1分钟左右就会填满Eden区,就须要执行Young GC了。

此时Young GC要回收那么大的内存,速度会慢不少,也许此时就会致使系统卡顿个几百毫秒,或者1秒钟

以下图所示:


那么你要是系统卡顿时间过长,必然会致使瞬间不少请求积压排队,严重的时候会致使线上系统时不时出现前端请求超时的问题,就是前端请求以后发现一两秒后还没返回就超时报错了。


七、用G1来优化大内存机器的Young GC性能

因此当时对这个系统的一个优化,就是采用G1垃圾回收器来应对大内存的Young GC过慢的问题。

ps:关于G1回收器,咱们此前已经经过一步一图的方式,详细阐述了其工做原理,若是忘记了的同窗,能够回看一下)

能够对G1设置一个预期的GC停顿时间,好比100ms,让G1保证每次Young GC的时候最多停顿100ms,避免影响终端用户的使用。

此时效果是很是显著的,G1会自动控制好在每次Young GC的时候就回收一部分Region,确保GC停顿时间控制在100ms之内

这样的话,也许Young GC的频率会更高一些,可是每次停顿时间很小,这样对系统影响就不大了。


八、本文总结

本文用一个案例,其实就想说明一个问题,一般Young GC哪怕发生的频繁一些,其实通常都对系统形成不了太大的影响

只有在你机器内存特别大的时候,才须要注意Young GC也可能会致使比较长时间的停顿,此时针对大内存机器一般建议采用G1垃圾回收器


九、小小思考题

看到这里,给你们留一个小思考题,去想办法看看本身线上系统:


  • 多长时间发生一次Young GC?

  • Young GC耗时多久?

  • 而后你以为它对你的系统影响大吗?

END


点击下方连接,了解更多专栏详情:

《从零开始带你成为JVM实战高手》

或者直接关注公众号:石杉的架构笔记,点击下方菜单栏-训练营查看

《21天互联网Java进阶面试训练营(分布式篇)》详细目录,扫描图片末尾的二维码,试听课程

相关文章
相关标签/搜索