1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Java基础之《JVM性能调优(7)—番外篇大流量系统的jvm性能分析和优化》

Java基础之《JVM性能调优(7)—番外篇大流量系统的jvm性能分析和优化》

时间:2022-10-21 16:36:04

相关推荐

Java基础之《JVM性能调优(7)—番外篇大流量系统的jvm性能分析和优化》

一、背景

系统经常半夜full gc

二、场景

打开app点击搜索,这种搜索场景,在互联网公司非常普遍存在。

用户先输入搜索关键字,第一个搜索结果是综合,综合就是所有的意思。下面是子搜索项。

例如:

三、数据同步问题

和jvm相关的,就是搜索ES index索引库初始化的问题。

用户在搜索之前,要先有数据,也就是说,如何把业务数据同步到搜索里面?

业务数据同步到搜索,一般有2种场景:

1、增量同步

2、全量同步

四、增量同步

1、业务数据

每新增一条数据,就实时推送给ES搜索服务,例如增加一条视频数据,视频就推送给搜索服务。

2、推送方案

一般实时推送有2种方案:

A)基于接口调用方式:业务数据新增一条,就调搜索服务接扣同步。

B)基于canal,mysql日志解析通知方式,例如视频mysql增加一条数据,cancal就mq通知搜索服务。

市面上2种都有,一般是基于cancal来实现。

五、全量同步

1、同步方案

一般是由搜索服务去拉去业务方的数据,数据同步一般有2种方案:

A)由搜索服务,定时读取业务方的mysql从库数据库。

B)由搜索服务,定时调用业务方的服务接口,同步数据。

以上2种方案,都有公司在用,一般采用A方案,数据库从库同步的比较多。

2、为什么要全量同步,而且还是定时全量同步?

因为数据一致性问题,2份数据时间久了,会导致数据不一致。

例如视频服务修改了一条数据,虽然增量同步给搜索服务了,那如果万一搜索服务异常,导致同步失败,就会导致数据不一致,导致数据脏乱。

六、jvm的问题

jvm的异常,出现在全量同步上。

1、当前jvm配置

设置了JVM为4G。按照默认比例young:old=1:2,eden:s0:s1=8:1:1

young区分到1.3G,old区分到2.7G

2、系统处理逻辑

采用定时器,夜里1点钟,由搜索服务,连接业务线的mysql从库,每次读取2万条数据,然后把2万条数据写入到es的index库中。

3、eden区多久被塞满

eden区总共1.1g,10条线程并发,2秒产生200M对象数据。故10秒钟,填满1.1g eden区。

eden区被填满了,就会触发young gc。

4、每次ygc有多少对象还存活

对象的存活,要先被栈帧引用,而栈帧存储在线程栈中。

我们开了10条线程在并行,就有10个栈帧时刻运行着。

也就是说,每时每刻都有10条线程运行,约有200mb的数据被线程栈帧引用。

所以,每10秒触发1次ygc时,就有200mb的数据存活。

5、如何处理存活的200MB数据

eden区1.1G,900m被垃圾处理了,200m是活的数据。

每次ygc后,200mb通过复制算法,复制给survivor区。但是survivor被分割为from和to区各100MB,from区100m放不下200m,只能先把s_from的50m—100m(动态年龄50%)塞满后,剩下的100-150m复制到old区。

6、old区多久被填满

old区有2.7G,每10秒触发一次ygc,就有100m进old区。

(1)我们来模拟这种动作:

第1次10秒,触发ygc,把eden的存活200m,其中100m复制进s_from,100m进old,最后清空eden。

第2次10秒,触发ygc,把eden+s_from的存活200m,其中100m复制进s_to,100m进old,最后清空eden和s_from,并from与to互换。

(2)为什么第2次ygc,eden+s_from存活是200m?

因为第一次的s_from的100m经过10秒后,老早就没有引用了,变为垃圾对象,所以eden+s_from其实只有eden200m存活

(3)就这样经过了,2.7G/100M=27次ygc后,old区满了

27 * 10秒=270秒/60=4.5分钟

即,每4.5分钟后,触发full gc,这个速度还是比较高的,频繁full gc会导致系统卡顿,影响性能。

七、jvm的性能优化

1、该案例有哪些问题

该案例最大的问题就是经常full gc导致系统卡顿。

2、为什么会full gc呢

因为每次ygc都有100mb,没地方放,导致进了old区!然后old区过了4.5分钟后触发full gc。

那现在要解决的问题就是100mb没地方放的问题,不要让他进入old区。

3、要怎么解决呢

把survivor_from和to区加到大于200M即可。比如设置为250M。

(1)把堆再加1g,变成5g:-Xms=5g -Xmx=5g

(2)把年轻代设置为2g:-Xmn=2g

(3)把survivor_from和to设置为256M

-XX:SurvivorRatio=6:设置年轻代中eden区与survivor区的大小比值。

设置为6,则两个survivor区与一个eden区的比值为2:6,一个survivor区占整个年轻代1/8,2g的8分之1,就是256。

八、小结

该案例因为survivor空间不够,导致full gc。

看看自己公司线上系统,survivor的空间是多大,按业务和并发,评估多久survivor空间不足进入old区。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。