背??景上个月,我和朋友一起创建了一个微信小程序。趁着5.20节的火爆,我在两周内迅速积累了超过一百万的用户。我们在小程序页面添加了formid的收集点。用于向微信用户发送模板消息通知。这个小程序的后端逻辑一开始是用douchat框架写的。框架自带的dc_mp_fans表用于存放微信端授权登录的用户信息,dc_mp_tempmsg表用于存放formid。截至目前,已采集数据超过380万条,成功使用formid很大一部分向用户发送模板通知,起到了很好的二次推广效果。随着数据量的增加,之前使用的服务器空间已经不够用了。最近写了一个新的小程序后台开发框架,想把原来的数据迁移到新系统的数据库中。买了一台4核8G的机器,开始数据迁移。下面简单记录下迁移过程。方案选择mysqldump迁移在平时的开发中,我们经常使用的数据备份和迁移的方法是使用mysqldump工具导出一个sql文件,然后将sql导入到新的数据库中,完成数据的迁移。测试发现,通过mysqldump将一个百万级别的数据库导出成一个sql文件,大概需要几分钟的时间。导出的sql文件大小约为1G,然后通过scp命令将1G的sql文件复制到另一台服务器上。这可能需要几分钟。在新服务器的数据库中通过source命令导入数据。跑了一晚上也没导入数据,CPU占满了。脚本迁移是一种比较方便的方式,直接通过命令行操作数据库导出导入数据,但在数据量大,对服务器性能要求比较高的情况下往往比较耗时。如果对数据迁移的时间要求不是很高,可以尝试写脚本进行数据迁移。虽然我还没有实际尝试过,但我认为可能有两个脚本选项。第一种方式是在迁移目标服务器上运行迁移脚本,远程连接源数据服务器的数据库,通过设置查询条件分块读取源数据,读取后写入目标数据库。这种迁移方式的效率可能比较低。数据的导出和导入相当于一个同步过程,需要等到读取完成再写入。如果查询条件设计得当,还可以多线程的方式启动多个迁移脚本,达到并行迁移的效果。第二种方式,可以结合redis构建“生产+消费”的迁移方案。源数据服务器可以作为数据生产者,在源数据服务器上运行多线程脚本,并行读取数据库中的数据,并将数据写入redis队列。目标服务器作为消费者,也在目标服务器上运行多线程脚本,远程连接redis,并行读取redis队列中的数据,并将读取到的数据写入目标数据库。与第一种方法相比,这种方法是一种异步的解决方案。可以同时进行数据导入和数据导出,使用redis作为数据中转站,效率会大大提高。关注公众号InternetArchitects,回复关键词2T,获取最新建筑视频。可以使用go语言编写迁移脚本,利用其原生的并发特性,达到并行数据迁移的目的,提高迁移效率。文件迁移第一种迁移方案效率太低,第二种迁移方案编码成本高。对比分析网上查到的资料,最终选择使用mysql的selectdataintooutfilefile.txt,loaddatainfilefile.txtintotable命令,以导入导出文件的形式完成百万数据的迁移.迁移过程导出源数据库中的数据文件select*fromdc_mp_fansintooutfile'/data/fans.txt';复制数据文件到目标服务器zipfans.zip/data/fans.txtscpfans.ziproot@ip:/data/导入文件解压到目标数据库/data/fans.ziploaddatainfile'/data/fans.txt'intotablewxa_fans(id,appid,openid,unionid,@dummy,created_at,@dummy,nickname,gender,avatar_url,@dummy,@d按照这些步骤,几分钟就完成了百万级数据表的跨服迁移。设置mysql安全项,在mysql中执行loaddatainfile和intooutfile命令,mysql中必须开启secure_file_priv选项,可以通过showglobalvariableslike'%secure%';查看mysql是否开启了该选项。默认值Null表示不允许导入和导出命令。通过vim/etc/my.cnf修改mysql配置项,将secure_file_priv的值为空:[mysqld]secure_file_priv='',可以通过命令导入导出数据文件。导入导出的数据表字段不对应上例中从源数据库的dc_mp_fans表到目标数据库的wxa_fans表的数据迁移。两个数据表的字段分别是:-dc_mp_fanswxa_fans导入数据时,可以设置字段名来匹配目标字段的数据,可以使用@dummy丢弃不需要的目标字段数据。总结结合本次数据迁移经验,总结如下:少量数据可以使用mysqldump命令导入导出,简单方便。-当数据量较大,并且有足够的迁移耐心时,可以选择自己编写脚本,选择合适的并行方案进行数据迁移。这种方法的编码成本更高。-当数据量较大,想在短时间内完成数据迁移时,可以使用mysql导入导出文件进行迁移,效率更高。
