airuikun / technology-blog

个人博客,前端技术收集,一起共同学习与成长
3.18k stars 292 forks source link

十万条数据插入数据库,怎么去优化和处理高并发情况下的DB插入 #26

Open airuikun opened 5 years ago

airuikun commented 5 years ago

这种题,你懂的,逼格高,亮瞎眼,大厂太爱考了。

不过装逼归装逼,有能力并且真真正正处理过这些高并发情况的FE,这题是他们一个很好的展现机会。

以前我的mentor,用nodejs实现了高并发的智能容灾,我至今记忆犹新,并且他也收获了那年的高绩效。

来玩一下?

yalishizhude commented 5 years ago

先写成文件,然后再一次性导入。 如果涉及到多次插入,可以每次导入到具有一定命名规则的collection或table,方便查询。

w10036w commented 5 years ago

最好用node本身适合处理IO

核心思路是把db操作语句在中间层(nodejs)按时间(如每10秒)合并,比如把同一集合下的nosql或者sql多句柄合并成单一句柄,时间到周期后操作db

数据量小就写内存,大就写redis

totatolin commented 5 years ago

之前处理过一个类似的nosql场景,大概说下当时处理时候的思路。 首先是优化方面,对于十万条数据,如果处理每条数据时构建一个实例化对象,处理具体业务逻辑,然后进行一次io操作,十万条数据要构建十万个对象,操作十万次io,对于内存和io方面来说这显然是不现实的。整体的思路可以考虑构建一个生产消费者模式,即一个生产队列,一个消费队列。十万条数据可以到生产队列中依次排队,每条数据出队列时先到实例享元池中进行过滤(每条数据在处理完成后进行一次对象回收,回收到享元池中,下一条数据发现享元池中已经存在该对象就不重新构建而是拿来直接使用,可以避免在两次gc之间瞬时内存过大的情况)。假设这十万条数据可能分属十张表中,那么在每张表之前构建一个消费队列,从生产队列出来的数据到各自的消费队列中依次进行业务处理,处理完的数据归属到各个表的内存中(如果只考虑插入数据的话基本包括添加、更新、删除这几个操作,对于一些异常情况,例如后面的操作先进入了队列,可以将该数据放入队列尾部重新排队。如果考虑高并发的情况,也就是在插入数据时同时要读取数据,那么需要构建两个消费队列,即一个读取队列,一个插入队列,两个队列为互斥的,对于这种情况处理就会更加复杂)。当每张表的数据处理完成后,将该表进行一次io操作,把内存中的数据同步更新到数据库中。当然如果考虑一些容灾或者宕机的场景,可以将内存中的数据每隔一段时间进行一次redis备份。

zouxiaomingya commented 5 years ago

你的公布答案,想问下答案在哪里