Canal增量订阅MySQL数据同步工具

一.背景

我们在很多的业务场景都需要用到MySQL数据库进行存储,同时呢也会用到Redis缓存、Elasticsearch全文检索引擎等等。 最常见的业务场景就是MySQL和Redis缓存数据同步问题了。一般而言我们是怎么做的呢?

我们常见做法就是在代码里面写逻辑,首先访问redis缓存,如果访问不到则访问mysql拿到数据,之后再更新缓存. 这种做法没问题,简单高效。 但是这种情况要牺牲的是你需要在代码层面来维护这个同步流程,假设一种极端情况,你的redis和mysql数据不一定是一致的,那就是mysql查询到数据之后,往redis塞失败了,导致缓存数据过时问题。 并且如果你的系统有很多地方都是这种逻辑,那么对相关源代码进行铺天盖地的修改,工作量增加很多。

那么有没有一种工具或者方法,能够让它监听我们的mysql数据变化,把变化的数据更新到redis里面,并且不需要修改我们的源代码呢? 确保这种同步数据流程和我们业务无关。 答案就是canal可以做到.

二.简介

阿里巴巴开源的工具canal: https://github.com/alibaba/canal

canal [kə’næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费.

基本原理就是:

canal伪装成为mysql的一个【slave从节点】订阅master的binlog, 解析binlog拿到更新后的数据,拿到更新后的数据之后, 一般会将数据推送到MQ(例如Kafka、RabbitMQ等)中间件, 之后我们再通过消费MQ拿到增量更新数据进行业务处理.

说白了, canal也是可以理解为一个【特殊的mysql从节点】.正常的mysql从节点是同步数据插入自己的实例中,而canal是将数据放到MQ, 后面你想针对增量数据做什么都是你的自由.

三.运行canal

docker-compose运行canal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
version: "3"
services:
  canal:
    image: canal/canal-server:v1.1.5
    volumes:
    - "./docker/canal/conf:/home/admin/canal-server/conf" #配置文件目录
    - "./docker/canal/logs:/home/admin/canal-server/logs" #日志目录
    ports:
      - "11112:11112" #metrics
    healthcheck: # 健康检查
      test: [ "CMD-SHELL", "ss -lntp | grep -w '11112' || exit 1" ]
      interval: 10s
      timeout: 10s
      retries: 3

很简单的一个canal, 需要先在MySQL master节点创建canal从节点账号,之后填写配置文件启动canal即可将增量数据传输到MQ.

官网有现成的MQ消费者: 例如 将MySQL数据同步到Elasticsearch、同步到Hbase、同步到RDB等等.

如果现有的MQ消费者不满足你的需求,那最简单的就是自己写一个消费者从MQ消费数据(JSON格式),再做自己的业务处理即可.

详细配置文件等相关问题,可以在官方文档查找,支持中文.

官方文档地址: Home · alibaba/canal Wiki · GitHub