这样的场景
一个处理程序,有很多update操作,最后会生成代办消息。多个线程去处理。
之前用的8个线程,有500个,然后用时2个多小时。
时间太长,想进行优化
现在改成24个线程,内存是'-Xmx7168m -Xms3584m -Xmn2564m ',但是出现几个问题:锁超时和GC
1.Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
2.nested exception is java.sql.SQLException: GC overhead limit exceeded
请各位大佬指导
500个:
交给 5个JVM 处理,不就是,2/5小时(24分钟)了吗?
单个任务处理(1个update)需要多久呢?
mybatis-plus的 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl 有很多批量方法吧,比如,
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
public boolean updateBatchById(Collection<T> entityList, int batchSize);
多线程的方法相对治标,容易引入新问题,确实更推荐优化原更新处理,提高性能,对多线程了解不多
这个时候你不是应该先去优化你的update操作的sql吗?
出现这种问题的原因可能是并发量太高,导致数据库锁等待超时和GC负荷过重。
针对锁超时的问题,可以考虑采用以下几种方式:
innodb_lock_wait_timeout=120
优化 SQL 语句。可以分析 SQL 执行计划,查看是否存在慢查询或者死锁等问题,优化 SQL 语句以提高数据库执行效率。
减少并发量。可以通过调整程序中线程的数量、减少更新操作的频率等方式来减少并发量。
针对 GC 负荷过重的问题,可以考虑采用以下几种方式:
增加 JVM 堆内存大小。可以通过增加 JVM 堆内存大小来减少 GC 的频率,但也要注意不要设置过大,避免出现内存溢出等问题。
调整 GC 策略。可以通过调整 JVM 的 GC 策略来减少 GC 的频率,例如将 GC 策略调整为 G1。
减少程序中不必要的对象创建。可以通过复用对象、使用对象池等方式来减少程序中不必要的对象创建,从而减少 GC 的负荷。
综上所述,针对锁超时和 GC 负荷过重的问题,需要综合考虑数据库和程序本身两方面的优化措施,以提高程序的并发性能和稳定性。
这两个问题的出现很可能是由于并发性太高导致的,特别是在24个线程的情况下,可能会导致过多的数据库连接和内存占用。下面是一些可能的解决方案:
减少并发性:减少线程数或者增加处理程序的处理速度,例如使用更快的硬件或者优化代码逻辑。可以使用线程池来限制线程数,从而避免出现过多的并发情况。
调整数据库连接池设置:可以调整连接池的配置,增加连接池的大小或者调整锁等待时间来解决锁超时的问题。例如增加数据库连接池的最大连接数或者增加锁等待时间。
增加JVM内存:可以增加JVM内存来解决GC overhead limit exceeded的问题。可以通过调整JVM参数来增加堆内存、调整GC策略等。例如增加-Xmx参数来增加最大堆内存。
优化代码:可以对代码进行优化,例如减少不必要的锁操作、使用缓存等方法来提高代码执行效率,从而减少锁超时和GC问题的发生。
总之,要解决这些问题,需要进行系统级别的优化,包括硬件、数据库、代码等方面。需要根据具体情况进行分析和调整。