大数据量插入Mysql的爬坑经历

性能测试阶段,预先插入一批数据到Mysql中。并分为三个阶段。

第一阶段:向Mysql的三张表里,插入有关联关系的18万+18 * 3万+18 * 4万的数据。

第二阶段:插入第一阶段数据量5倍的数据,即90万为基数

第三阶段;插入第一阶段数据量10倍的数据即180万为基数

方法1:本地JDBC插入。List<?>有1+3+4,共8个List<?>

方法1的问题有两点:
1.JDBC顺序执行效率很低
2.大数据量下,耗时会超过连接时间,导致连接超时。

方法2:本地或服务器端启动多个任务将基础数据List<?>插入。其他的关联数据,先检索基础数据List<?>,再将生成的关联数据插入。

将其余的7个List<?>做成7个类,在服务器上分别启动。
方法2的优点:
1.效率快,先插入基础数据后,时间复杂度O,其余数据数据并行插入。时间总共O*2;
但是在实际执行情况下,第一阶段和第二阶段都顺利执行。但是第三阶段却暴露了问题。
方法2的问题:
1.7个任务,将180万*7的数据检索到内存后,内存溢出(OutOfMemoryError)。(下班开了任务就走的我,第二天看日志,瞬间泪流满面)

鉴于方法2的问题,就在方法1的基础上,做了修改。 方法一也有优点,就是数据都在内存中,关联数据的生成比较方便。不需要再去检索数据库,再额外占用内存。方法三在此优点上修改 方法3:基础数据和关联数据生成后,开启多线程插入数据。8个List<?>就分8个线程插入。提升效率。

方法3暴露的问题:(也许此方法暴露的不是问题,而是我的智商)
问题如下:
1.程序改为多线程后,对应的List<?>没有改动。ArrayList<?>是线程非安全的。java.util.ConcurrentModificationException
2.线程的创建,阻塞,销毁。多线程(ExecutorService service = Executors.newFixedThreadPool(8);)的使用

线程安全的类:
CopyOnWriteArrayList<?> 参考资料(https://blog.csdn.net/liyu121/article/details/87873858)与(https://www.cnblogs.com/dolphin0520/p/3938914.html)
CocurrentHashMap<key,value> (https://blog.csdn.net/fwt336/article/details/81110760)
List<String> list = Collections.synchronizedList(new LinkedList<String>());(很low啊)
将LinkedList全部换成ConcurrentLinkedQueue(没用过)

最终被智商打败的我(阻塞处理不好,导致的连接提前关闭没有解决)选择了方法4

方法4:在方法2的基础上,将检索条件改为按id检索。并实现了可配置。 配置文件中,检索id为0-10000,然后7个任务并行,先检索0-10000,插入。 修改配置文件,检索id为10001-20000...以此类推。解决了内存不足的问题。

转载于:https://my.oschina.net/u/3957231/blog/3052775

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值