记录一个将数据从mysql同步到es的思路(全量与增量)

个人认为一个项目当它做大做当后都可能会需要将数据从传统的数据库同步到另一种数据集合中,一般用于提高查询效率或将数据进行备份的目的。

其中比较常见的一种同步方式是从关系型数据库同步到es,在查阅了相关的资料后,在这里简单记录下。

全量同步

所谓全量同步就是将一个mysql的整个表的所有数据都同步到es中。全量的同步在网上查询的资料中我感觉比较简单又靠谱一点是这个:logstash-input-jdbc,通过logstash的插件来进行同步,比较简单实用,logstash通过sql语句分区间对数据进行查询,然后输出到es进行实现。(etl中也有插件可以实现,但都大同小异)

增量同步

当然logstash-input-jdbc插件也可完成将数据从mysql同步过es,但是logstash是基于sql来完成的,并且是通过cron表达式来调用,如果业务场景需要实时性较高并对要求对数据库的压力比较小的话,通过logstash来进行实现就不太合适了。

通过查询资料后发现阿里在做大做强的过程中也遇到过类似的问题,但阿里不愧就是阿里,为了达到性能的最优,他们自己通过JAVA代码实现了mysql的数据同步功能,通过解析mysql 的日志进行实现的。同时,阿里还将此项目进行了开源,那就是canal。

地址为:https://github.com/alibaba/canal

简单看了下代码,它里面是通过一个server和一个client来进行实现的,及server负责mysql的日志监听与收集,然后再传给client端,server与client端使用的netty进行数据的tcp通信。当然现在也有了kafka和rocketMQ作为通信渠道的版本。同时canal也有专门的可视化监控界面,方便进行查看,同时也有HA的实现方式,通过zookeeper来进行实现的。

在看了后感觉用canal来实现数据的增量同步还是比较靠谱的,想将数据从mysql同步到es通过canal的一个adapter就可以直接实现了。https://github.com/alibaba/canal/tree/master/client-adapter

总结

canal实现数据的增量同步性能高,可监控,但里面没有全量同步的实现

logstash-input-jdbc实现数据同步性能差,不够及时,但设计的思路还是很值得借鉴的,通过偏移量来分段进行数据同步;

 

所以个人感觉如果遇到有需要对mysql数据表进行整表同步并后期持续同步的话,通过在canal的增量同步前先通过jdbc通过游标(避免数据量过大导致内存不够用)的方法来对数据表进行一次查询,如果想要提升性能可通过偏移量(自增id或createTime)进行分片的多任务查询并汇总,全量同步完成后再记录最后一条数据的偏移量位置(自增id或createTime),然后再通知canal client进行调用进行增量同步,通过全量同步时的偏移量来处理掉数据重复的问题。

嗯~空了我还是来自己写下具体的实现,欢迎各位多多提供宝贵意见!

在看了canal esAdapter的源码后,才知道原来canal esAdater中的etl方法对全量同步的功能也已经做了实现,向阿里大佬致敬

共同学习,共同进步~

 

 

你可能感兴趣的:(DB)