1、同步双写
通过应用服务,直接为数据库及ES写如数据。
优点:
- 业务逻辑简单;
- 实时性高
缺点:
- 业务耦合,耦合大量数据同步代码
- 硬编码,有需要写入 MySQL 的地方都需要添加写入 ES 的代码;
- 影响性能,写入两个存储,响应时间变长
- 不便扩展:搜索可能有一些个性化需求,需要对数据进行聚合,这种方式不便实现
- 存在双写失败丢数据风险;
- 性能较差,本来 MySQL 的性能不是很高,再加一个 ES,系统的性能必然会下降。
2、异步双写
优点:
- 解耦合
- 不易出现数据丢失问题,主要基于 MQ 消息的消费保障机制;
- 实时性较好,使用MQ,正常情况下,同步完成在秒级;
缺点:
- 引入了新的组件和服务,增加了复杂度
- 硬编码问题
- MQ是异步消费模型,用户写入的数据不一定可以马上看到,造成延时。
3、数据抽取
优点:
- 实现比较简单
- 没有硬编码、无业务耦合
缺点:
- 实时性难以保证
- 对存储压力较大
经典方案:借助 Logstash 实现数据同步,其底层实现原理就是根据配置定期使用 SQL 查询新增的数据写入 ES 中,实现数据的增量同步。
4、数据订阅
MySQL通过binlog订阅实现主从同步,各路数据订阅框架比如canal就依据这个原理,将client组件伪装成从库,来实现数据订阅。
优点:
- 业务入侵较少
- 实时性较好、无业务耦合
缺点:
- 构建 Binlog 系统复杂;
- 如果采用 MQ 消费解析的 Binlog 信息,也会像方案二一样存在 MQ 延时的风险。
至于数据订阅框架的选型,主流的大体上是这些:
Cancal | Maxwell | Python-Mysql-Rplication | |
---|---|---|---|
开源方 | 阿里巴巴 | Zendesk | 社区 |
开发语言 | Java | Java | Python |
活跃度 | 活跃 | 活跃 | 活跃 |
高可用 | 支持 | 支持 | 不支持 |
客户端 | Java/Go/PHP/Python/Rust | 无 | Python |
消息落地 | Kafka/RocketMQ 等 | Kafka/RabbitNQ/Redis 等 | 自定义 |
消息格式 | 自定义 | JSON | 自定义 |
文档详略 | 详细 | 详细 | 详细 |
Boostrap | 不支持 | 支持 | 不支持 |