返回
记录因Sharding Jdbc批量操作引发的一次fullGC
后端
2023-10-15 10:37:07
一、背景
我们有一个使用Sharding Jdbc管理数据库分库分表的项目,最近在进行压力测试时,发现项目在进行大批量数据插入操作时,会出现fullGC的问题。为了解决这个问题,我们对GC日志进行了分析,并总结了经验教训。
二、问题复现
为了复现问题,我们在本地环境中搭建了一个模拟项目。项目使用Spring Boot框架,数据库使用MySQL。分表策略是使用Sharding Jdbc的RangeShardingAlgorithm,对ID字段进行分片。
我们使用以下代码进行批量插入操作:
List<User> users = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
User user = new User();
user.setId(i);
user.setName("user" + i);
users.add(user);
}
jdbcTemplate.batchUpdate("insert into user (id, name) values (?, ?)", users);
在运行这段代码时,我们发现项目在插入大约10万条数据后,会出现fullGC的问题。
三、GC日志分析
为了分析GC日志,我们使用MAT工具打开了堆内存快照。
在堆内存快照中,我们发现有一个名为"byte[]"的数组占据了大量的内存空间。这个数组是Sharding Jdbc用于批量操作的临时缓冲区。
当Sharding Jdbc进行批量操作时,它会将数据先缓存到这个临时缓冲区中,然后一次性将所有数据插入到数据库中。
如果批量操作的数据量过大,那么这个临时缓冲区就会占用大量的内存空间,从而导致fullGC的发生。
四、解决方案
为了解决这个问题,我们可以通过以下两种方式来减少临时缓冲区占用的内存空间:
- 减少批量操作的数据量。
- 增大临时缓冲区的容量。
在我们的项目中,我们通过减少批量操作的数据量来解决了这个问题。我们将批量操作的数据量从10万条减少到1万条,这样就不会导致fullGC的发生了。
五、经验教训
通过这次事件,我们总结了以下经验教训:
- 在使用Sharding Jdbc进行批量操作时,要控制好批量操作的数据量,以避免导致fullGC的发生。
- 在使用Sharding Jdbc进行批量操作时,可以适当增大临时缓冲区的容量,以减少临时缓冲区占用的内存空间。
- 在进行压力测试时,要模拟真实的业务场景,以避免出现意外情况。
六、结语
以上就是我们记录因Sharding Jdbc批量操作引发的一次fullGC的经验教训。希望对大家有所帮助。