在实际项目开发中,我们经常将Mysql作为业务数据库,ES作为查询数据库,用来实现读写分离,缓解Mysql数据库的查询压力,应对海量数据的复杂查询。
这其中有一个很重要的问题,就是如何实现Mysql数据库和ES的数据同步,今天和大家聊聊Mysql和ES数据同步的各种方案。
开源免费、高并发、稳定、支持事务、支持SQL查询
ES 几个显著的特点,能够有效补足 MySQL 在企业级数据操作场景的缺陷,而这也是我们将其选择作为下游数据源重要原因
核心特点:支持分词检索,多维筛选性能好,支持海量数据查询
这是一种最为简单的方式,在将数据写到mysql时,同时将数据写到ES。
/**
* 新增商品
*/
@Transactional(rollbackFor = Exception.class)
public void addGoods(GoodsDto goodsDto) {
//1、保存Mysql
Goods goods = new Goods();
BeanUtils.copyProperties(goodsDto,goods);
GoodsMapper.insert();
//2、保存ES
IndexRequest indexRequest = new IndexRequest("goods_index","_doc");
indexRequest.source(JSON.toJSONString(goods), XContentType.JSON);
indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
highLevelClient.index(indexRequest);
}
针对这种情况,有数据强一致性要求的,就必须双写放到事务中来处理,而一旦用上事物,则性能下降更加明显。
针对多数据源写入的场景,可以借助MQ实现异步的多源写入,这种情况下各个源的写入逻辑互不干扰,不会由于单个数据源写入异常或缓慢影响其他数据源的写入,虽然整体写入的吞吐量增大了,但是由于MQ消费是异步消费,所以不适合实时业务场景。
上面两种方案中都存在硬编码问题,也就是有任何对mysq进行增删改查的地方要么植入ES代码,要么替换为MQ代码,代码的侵入性太强。
如果对实时性要求不高的情况下,可以考虑用定时器来处理,具体步骤如下:
如下图所示:
该方案的典型实现是借助logstash实现数据同步,其底层实现原理就是根据配置定期使用sql查询新增的数据写入ES中,实现数据的增量同步。
具体实现可以参考:通过Logstash实现mysql数据定时增量同步到ES
上面三种方案要么有代码侵入,要么有硬编码,要么有延迟,那么有没有一种方案既能保证数据同步的实时性又没有代入侵入呢?
当然有,可以利用mysql的binlog来进行同步。其实现原理如下:
数据迁移同步工具的选择比较多样,下表仅从 MySQL 同步 ES 这个场景下,对一些笔者深度使用研究过的数据同步工具进行对比,用户可以根据自己的实际需要选取适合自己的产品。
特性\产品 | Canal | DTS | CloudCanal |
---|---|---|---|
是否支持自建ES | 是 | 否 | 是 |
ES对端版本支持丰富度 | 中 支持ES6和ES7 | 高 支持ES5,ES6和ES7 | 中 支持ES6和ES7 |
嵌套类型支持 | join/nested/object | object | nested/object |
join支持方式 | 基于join父子文档&反查 | 无 | 基于宽表预构建&反查 |
是否支持结构迁移 | 否 | 是 | 是 |
是否支持全量迁移 | 是 | 是 | 是 |
是否支持增量迁移 | 是 | 是 | 是 |
数据过滤能力 | 中 -仅全量可添加where条件 | 高 -全增量阶段where条件 | 高 -全增量阶段where条件 |
是否支持时区转换 | 否 | 是 | 是 |
同步限流能力 | 无 | 有 | 有 |
任务编辑能力 | 无 | 有 | 无 |
数据源支持丰富度 | 中 | 高 | 中 |
架构模式 | 订阅消费模式 需先写入消息队列 | 直连模式 | 直连模式 |
监控指标丰富度 | 中 性能指标监控 | 中 性能指标监控 | 高 性能指标、资源指标监控 |
报警能力 | 无 针 | 对延迟、异常的电话报警 | 针对延迟、异常的钉钉、短信、邮件报警 |
任务可视化创建&配置&管理能力 | 无 | 有 | 有 |
是否开源 | 是 | 否 | 否 |
是否免费 | 是 | 否 是社区版、 | SAAS版免费 |
是否支持独立输出 | 是 | 否依赖云平台整体输出 | 是 |
是否支持SAAS化使用 | 否 | 是 | 是 |
本文主要对Mysql和ES进行数据同步的常见方案进行了汇总说明。
同步双写
是最简单的同步方式,能最大程度保证数据同步写入的实时性,最大的问题是代码侵入性太强。异步双写
引入了消息中间件,由于MQ都是异步消费模型,所以可能出现数据同步延迟的问题。好处是在大规模消息同步时吞吐量更、高性能更好,便于接入更多的数据源,且各个数据源数据消费写入相互隔离互不影响。基于Mysql表定时扫描同步
,原理是通过定时器定时扫描表中的增量数据进行数据同步,不会产生代码侵入,但由于是定时扫描同步,所以也会存在数据同步延迟问题,典型实现是采用 Logstash 实现增量同步。基于Binlog实时同步
,原理是通过监听Mysql的binlog日志进行增量同步数据。不会产生代码侵入,数据同步的实时也能得到保障,弊端是Binlog系统都较为复杂。典型实现是采用 canal 实现数据同步。阅读量:2016
点赞量:0
收藏量:0