elasticsearch中的酒店数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步
思路分析
常见的数据同步方案有三种:
- 同步调用
- 异步通知
-
1.同步调用
步骤如下: hotel-demo对外提供接口,用来修改elasticsearch中的数据
hotel-admin在完成数据库操作后,直接调用hotel-demo提供的接口
2.异步通知
步骤如下:hotel-admin对mysql数据库数据完成增、删、改后,发送MQ消息
hotel-demo监听MQ,接收到消息后完成elasticsearch数据修改
3.监听binlog
步骤如下:给mysql开启binlog功能
- mysql完成增、删、改操作都会记录在binlog中
hotel-demo基于canal监听binlog变化,实时更新elasticsearch中的内容
三种方式的区别
方式一:同步调用
优点:实现简单,粗暴
- 缺点:业务耦合度高,执行时间叠加
方式二:异步通知
- 优点:低耦合,实现难度一般
- 缺点:依赖mq的可靠性
方式三:监听binlog
- 优点:完全解除服务间耦合
- 缺点:开启binlog增加数据库负担、实现复杂度高
MQ实现数据同步的思路
代码就不写一大片了,说下思路。
微服务中分了两个模块,管理和搜索,管理模块是对mysql酒店数据的增删改查。搜索模块是对酒店数据进行检索的。
两个模块一个是基于mysql,一个是基于es,可谓是底层数据都互不影响。
搜索这模块基本上不会做什么改变数据的事,当管理模块改变了数据,才去同步搜索模块。
也就是说搜索模块是消费者,管理模块是发布者。
我们在两个模块都引入mq的依赖,消费者模块设置监听。
管理模块只要数据发生了变化,就给mq发消息,搜索模块监听到了消息,就执行es的增删改操作,从而实现数据同步。
比如,增加和修改酒店的时候,管理模块给mq发消息,带上的数据是酒店的id,而搜索模块监听到了消息,得到了酒店的id,又远程调用管理模块的 “根据id查酒店” 的接口,得到酒店数据,然后就加入到es中。
删除的时候,管理模块直接给mq发消息,带上被删除的酒店id,搜索模块直接用这个id去删除文档就行了。
:::danger
需要注意的是,发送消息和绑定监听的时候,需要一些交换机的名字,队列名,消息键等,这些统一写在常量类里面,不要到处写一些魔法值。
:::
:::success
关于mq的内容,可以看我写的RabbitMQ>SpringAMQP
:::