对于ES,我并没有在实际项目中应用(自己研究过,没有实战过);我们项目使用的是MongoDB;由于项目的特殊性,我们研究了很多关于A->B的数据同步方案,包括DB2/Mysql到MongoDB,MongoDB到MongoDB等等。
MySQL数据同步到ES的方案把MySQL的数据实时同步到ES,这样可以实现在ES中低延迟的检索,有些公司的项目做了分库,可以单独搭建一套ES来放全量的数据(或全量数据的部分字段,达到全量检索的效果),常用的数据同步实现方案有这些:
MySQL Binlog:MySQL的Binlog日志可以用于数据库的主从复制、数据恢复,也可以将MySQL的数据同步给ES;这里需要注意,Binlog的日志模式只能使用ROW模式(另外两种模式是STATEMENT和MIXED);解析Binlog日志中的内容,执行ES Document API,这样就可以将数据同步到ES中;
MySQL dump:如果是新建的项目,使用Binlog做数据同步是没有问题的,但如果MySQL已经运行了一段时间,项目架构中后增加的ES,那么历史数据的迁移就要额外处理了,因为Binlog可能已经被覆盖了。这时候历史数据的同步,可以使用mysqldump对现有数据导出,之后再使用Binlog的方式;
开源工具:前两种方式都是在数据库日志这个级别做文章,我们还可以使用一些开源工具,比如go-mysql-elasticsearch;它可以帮助我们完成第一次全量数据同步,后续增量数据同步的工作(底层也是解析Binlog日志);又或者mypipe,它支持将Binlog日志内容解析后推送到Kafka,如果要写入到ES中,还需要写额外的代码从Kafka中消费数据写入ES。
我们项目中的实现方案上面提过,我们项目中是将关系型数据库DB2/Mysql中的数据同步到MongoDB中,Mysql尚且还能使用Binlog日志,DB2想要把变化的数据实时通知出来,实现起来比较困难(写程序部署到DB2服务器上,要和数据库做关联配置,当数据发生变化,程序发送MQ通知给外围系统),先不说性能是否能保证,就是“自己写一个通知程序部署到数据库所在服务器上(有侵入)”,这一点至少在我们公司是无法做到的。
我们采用了一个非常low的方式来解决这个问题,就是Java程序扫描DB2表中的时间戳,读取最近变化的数据,加工到MongoDB中;
虽然实现方案比较low,但是效果还不错,因为我们在从关系型数据到MongoDB的数据同步过程中,可以自有地做数据加工;相当于按照一定的数据维度,比如按照客户维度,把几十张表做关联,加工后行程一个document保存到MongoDB中;再对外提供服务的时候,查询效率提升的很明显,因为表关联已经提前完成了(接口响应大多数时候都是毫秒级,超过50ms就算慢了)。
缺点也很明显,数据从关系型数据库到MongoDB的延迟很高,我们项目几经优化,也需要20分钟左右;所以一定要结合着业务场景考虑是否使用这种方案。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。Copyright © 广州京杭网络科技有限公司 2005-2024 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有