Canal实现0侵入同步缓存数据

开启MySQL binlog功能

cd /home/mysql8/conf
vim my.cnf

[mysqld]
log-bin=/var/lib/mysql/mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
binlog-do-db=imooc-hire-dev # 配置binlog给哪个数据库使用

重启MySQL:
docker restart mysql
检测binlog是否开启:
Canal实现0侵入同步缓存数据_第1张图片
Canal实现0侵入同步缓存数据_第2张图片

Docker安装Canal

docker pull canal/canal-server:v1.1.6
docker run -p 11111:11111 --name canal -e canal.destinations=imooc -e canal.instance.mysql.slaveId=20231111 -e canal.instance.master.address=192.168.233.128:3306 -e canal.instance.dbUsername=root -e canal.instance.dbPassword=Admin~123456 -e canal.instance.connectionCharset=UTF-8 -e canal.instance.filter.regex=imooc-hire-dev.data_dictionary --restart=always -d canal/canal-server:v1.1.6

canal.destinations=imooc表示起个名字跟后面的yml中对应上即可;
canal.instance.master.address=192.168.233.128:3306表示监听的数据库ip和端口;
canal.instance.filter.regex=imooc-hire-dev.data_dictionary表示的是监听imooc-hire-dev库的data_dictionary表,可以逗号分隔,多张表;
canal.instance.dbUsername=root -e canal.instance.dbPassword=Admin~123456表示被监听的数据库账号密码;

查看是否启动成功:

docker exec -it canal bash
cd canal-server/logs/imooc
vi imooc.log


不报错就对了。

SpringBoot集成Canal实现0侵入缓存同步

        <dependency>
            <groupId>top.javatool</groupId>
            <artifactId>canal-spring-boot-starter</artifactId>
            <version>1.2.1-RELEASE</version>
        </dependency>

yml

canal:
  destination: imooc
  server: 192.168.233.128:11111
  user-name: canal
  password: canal

logging:
  level:
    top.javatool.canal.client: warn
package com.imooc.canal;

import com.imooc.base.BaseInfoProperties;
import com.imooc.pojo.DataDictionary;
import com.imooc.pojo.co.DataDictionaryCO;
import com.imooc.utils.GsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;

import java.util.ArrayList;
import java.util.List;

@CanalTable("data_dictionary")      // 指定监听的表名
@Component
public class DataDictSyncHelper extends BaseInfoProperties
        implements EntryHandler<DataDictionaryCO> // 指定表关联的实体对象(javabean)
{

    private static final String DDKEY_PREFIX = DATA_DICTIONARY_LIST_TYPECODE + ":";

    @Override
    public void insert(DataDictionaryCO dataDictionary) {
        String ddkey = DDKEY_PREFIX + dataDictionary.getType_code();

        // 先查询redis中是否存在该数据字典list
        String ddListStr = redis.get(ddkey);
        List<DataDictionary> redisDDList = null;
        if (StringUtils.isBlank(ddListStr)) {
            // 如果不存在,则直接new一个list,添加并存入到redis中即可
            redisDDList = new ArrayList<>();
        } else {
            // 如果redis中存在该list,则直接在缓存的list中新增即可
            redisDDList = GsonUtils.stringToListAnother(ddListStr,
                                                        DataDictionary.class);
        }

        // 转换对象并且塞入list
        DataDictionary pendingDictionary = convertDD(dataDictionary);
        redisDDList.add(pendingDictionary);
        redis.set(ddkey, GsonUtils.object2String(redisDDList));
    }

    private DataDictionary convertDD(DataDictionaryCO dataDictionaryCO) {
        DataDictionary pendingDictionary = new DataDictionary();
        BeanUtils.copyProperties(dataDictionaryCO, pendingDictionary);
        pendingDictionary.setTypeCode(dataDictionaryCO.getType_code());
        pendingDictionary.setTypeName(dataDictionaryCO.getType_name());
        pendingDictionary.setItemKey(dataDictionaryCO.getItem_key());
        pendingDictionary.setItemValue(dataDictionaryCO.getItem_value());
        return pendingDictionary;
    }

    @Override
    public void update(DataDictionaryCO before, DataDictionaryCO after) {

        String ddkey = DDKEY_PREFIX + after.getType_code();

        // 先查询redis中是否存在该数据字典list
        String ddListStr = redis.get(ddkey);
        List<DataDictionary> redisDDList = null;
        if (StringUtils.isBlank(ddListStr)) {
            // 如果不存在,啥都不要干
        } else {
            // 如果redis中存在该list,则直接在缓存的list中修改对应的数据字典项就行,再重置缓存
            redisDDList = GsonUtils.stringToListAnother(ddListStr,
                                                        DataDictionary.class);
            for (DataDictionary dd : redisDDList) {
                if (dd.getId().equalsIgnoreCase(after.getId())) {
                    DataDictionary pendingDictionary = convertDD(after);
                    redisDDList.remove(dd);
                    redisDDList.add(pendingDictionary);
                    break;
                }
            }
            redis.set(ddkey, GsonUtils.object2String(redisDDList));
        }
    }

    @Override
    public void delete(DataDictionaryCO dataDictionary) {
        String ddkey = DDKEY_PREFIX + dataDictionary.getType_code();

        // 先查询redis中是否存在该数据字典list
        String ddListStr = redis.get(ddkey);
        List<DataDictionary> redisDDList = null;
        if (StringUtils.isBlank(ddListStr)) {
            // 如果不存在,啥都不要干
        } else {
            // 如果redis中存在该list,则直接在缓存的list中删除该数据字典项就行,再重置缓存
            redisDDList = GsonUtils.stringToListAnother(ddListStr,
                                                        DataDictionary.class);
            for (DataDictionary dd : redisDDList) {
                if (dd.getId().equalsIgnoreCase(dataDictionary.getId())) {
                    redisDDList.remove(dd);
                    break;
                }
            }
            redis.set(ddkey, GsonUtils.object2String(redisDDList));
        }
    }

}

你可能感兴趣的:(Java,Redis,Docker,java,spring,boot,开发语言)