高并发系统避免频繁Y-GC_高并发处理方式
商家使用你的平台,产生了大量数据,基于这些数据你要为商家提供一些数据报表,如:每个商家每天有多少访客?有多少交易?付费转化率是多少?这就需要BI系统,Business Intelligence,商业智能。让商家能更好了解自己经营状况,然后让老板“智能”的去调整经营策略,提升业绩。
所以类似这样的一个BI系统,首先会从我们提供给商家日常使用的一个平台上会采集出来很多商家日常经营数据:
接着就能对这些经营数据依托各种大数据计算平台,如Hadoop、Spark、Flink等进行计算,得到数据报表:
然后,将计算好的各种数据分析报表都持久化,如MySQL、Elastcisearch、HBase都可:
最后一步,基于MySQL、HBase、ES存的数据报表,基于Java开发一套BI系统,通过该系统把各种存储好的数据暴露给前端,允许前端基于各种条件对存储好的数据进行复杂的筛选和分析:
系统初期部署架构
初期使用商家不多,比如几千个,所以刚开始系统部署很简单,几台4核8G机器部署BI系统,给堆内存中的新生代分配内存约1.5G,Eden区约1G:
自动刷新报表 + 大数据量报表
在突然使用系统的商家数量开始暴涨时,在BI系统中有种数据报表,支持前端页面有一个JS脚本,自动每隔几s发送请求到后台刷新数据,即“实时数据报表”:
假设仅几万商家作为你的系统用户,可能同时打开那个实时报表的商家就有几千个。然后每个商家打开实时报表之后,前端页面都会每隔几s请求后台加载最新数据,BI系统部署的每台机器每s请求达到几百,假设500个请求/s。然后每个请求会加载出来一张报表需要的大量数据,因为BI系统可能还需要针对那些数据进行内存中的现场计算加工一下,才返给前端。
每个请求约需加载100kb数据进行计算,因此每秒500个请求,就需要加载出来50MB数据到内存进行计算:
频繁Y-GC
上述系统运行模型下,每s会加载50M数据到Eden区,只要200s,就会填满Eden,然后触发Y-GC。1G左右的Eden进行Y-GC其实速度较快了,可能几十ms搞定。
所以对系统性能影响并不大。而且BI场景下,基本上每次Y-GC后,存活对象可能就几十甚至几MB。所以若仅是这样,可能BI系统运行几min后,卡顿10ms,但对终端用户和系统性能几乎无影响:
使用大内存机器
随商家越来越多,并发压力越来越大,高峰期10万请求/s。若还是4核8G,那可能要部署上百台机器抗10万并发。
所以一般提升机器配置,本身BI就是吃内存系统,所以我们将部署机器全面提升到16核32G。每台机器可抗几千并发,部署二三十台。
若用大内存机器,则新生代至少分到20G,Eden区占16G以上:
此时几千请求/s,每s大概加载到内存中几百MB数据,大概可能几十s甚至1min左右填满Eden区,开始执行Y-GC,回收那么大的内存,速度会慢很多,也许此时就会导致系统卡顿个几百ms或1s:
要是系统卡顿时间过长,必然导致瞬间很多请求积压排队,严重时导致线上前端请求频繁超时:前端请求后,发现1、2s还没返回就超时报错。
G1优化大内存机器Y-GC
采用G1应对大内存Y-GC过慢问题。对G1设置预期停顿时间,如100ms,让G1保证每次Y-GC时最多停顿100ms,避免影响用户使用。这样,也许Y-GC频率更高,但每次停顿时间很小,对系统影响就不那么大了。
总结
通常Y-GC哪怕发生很频繁,其实一般都对系统造成不了太大的影响。只有在你机器内存特别大时,要注意Y-GC也可能导致较长时停顿,针对大内存机器推荐直接G1。