【canal】canal同步msyql到redis

java层面 canal client配置pom文件

复制代码
     <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.13.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>33.5.0-jre</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.otter</groupId>
            <artifactId>canal.client</artifactId>
            <version>1.1.7</version> <!-- 使用最新版本 -->
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <!-- Redisson -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.23.5</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.otter</groupId>
            <artifactId>canal.protocol</artifactId>
            <version>1.1.7</version>
        </dependency>

java client

1.将接收到的canal数据2进制转为10进制数据

2.redis client需要2进制转10进制,否则key是10进制,内部还是2进制

java 复制代码
package org.example.cannal.redis;

import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.protocol.Message;
import com.alibaba.otter.canal.protocol.CanalEntry.*;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CanalBinaryParseWithRedisson {

    public static void main(String[] args) {
        // 1. 创建 Canal 连接
        CanalConnector connector = CanalConnectors.newSingleConnector(
                new InetSocketAddress("127.0.0.1", 11111),
                "example", "", ""
        );

        // 2. 创建 Redisson 客户端
        RedissonClient redisson = createRedissonClient();

        try {
            connector.connect();
            connector.subscribe(".*\\..*");
            connector.rollback();

            while (true) {
                Message message = connector.getWithoutAck(100); // 每次取100条
                long batchId = message.getId();
                int size = message.getEntries().size();

                if (batchId == -1 || size == 0) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ignored) {}
                } else {
                    handleEntries(message.getEntries(), redisson);
                    connector.ack(batchId); // 确认消费
                }
            }
        } finally {
            connector.disconnect();
            redisson.shutdown();
        }
    }

    private static void handleEntries(List<Entry> entrys, RedissonClient redisson) {
        for (Entry entry : entrys) {
            if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN ||
                entry.getEntryType() == EntryType.TRANSACTIONEND) {
                continue;
            }

            RowChange rowChange;
            try {
                // 关键:把二进制解析成 RowChange
                rowChange = RowChange.parseFrom(entry.getStoreValue());
            } catch (Exception e) {
                throw new RuntimeException("解析 RowChange 失败", e);
            }

            EventType eventType = rowChange.getEventType();
            String tableName = entry.getHeader().getTableName();

            for (RowData rowData : rowChange.getRowDatasList()) {
                if (eventType == EventType.INSERT || eventType == EventType.UPDATE) {
                    Map<String, String> dataMap = new HashMap<>();
                    String id = null;
                    for (Column column : rowData.getAfterColumnsList()) {
                        dataMap.put(column.getName(), column.getValue());
                        if ("id".equals(column.getName())) {
                            id = column.getValue();
                        }
                    }
                    // 用 Redisson 写入 Redis Hash
                    RMap<String, String> map = redisson.getMap(tableName + ":" + id);
                    map.putAll(dataMap);
                    System.out.println("写入 Redis: " + tableName + ":" + id + " -> " + dataMap);
                } else if (eventType == EventType.DELETE) {
                    String id = null;
                    for (Column column : rowData.getBeforeColumnsList()) {
                        if ("id".equals(column.getName())) {
                            id = column.getValue();
                            break;
                        }
                    }
                    // 删除 Redis Key
                    redisson.getMap(tableName + ":" + id).delete();
                    System.out.println("删除 Redis: " + tableName + ":" + id);
                }
            }
        }
    }

    private static RedissonClient createRedissonClient() {
        Config config = new Config();
        // 1. 配置Redis连接(单节点为例)
        config.useSingleServer()
                .setAddress("redis://127.0.0.1:6379")
//                .setPassword("你的密码") // 无密码则省略
                .setDatabase(1);

        // 2. 关键:设置序列化器为StringCodec(明文字符串序列化)
        config.setCodec(new org.redisson.client.codec.StringCodec());

        return org.redisson.Redisson.create(config);
    }
}
相关推荐
深盾科技_Virbox2 分钟前
软件交付保护如何从加壳走向代码虚拟化
java·python·安全
YUS云生40 分钟前
Python学习笔记·第28天:Git入门——版本控制与基础操作
笔记·python·学习
Bryce学亮41 分钟前
1688 半自动化拟人浏览信息处理工具爬虫
爬虫·python
是枚小菜鸡儿吖44 分钟前
服务器出问题别等用户反馈:用Python和钉钉搭一套轻量告警系统
服务器·python·钉钉
三少爷的鞋1 小时前
Android 面试系列:Kotlin 协程的 delay 到底发生在哪个线程?
android
聪明的一休丶10 小时前
VLLM v0.24.0 版本深度解析:新引擎、新架构与大规模服务全家桶升级
python·架构·vllm
万亿少女的梦16812 小时前
基于Python的高考志愿填报辅助系统设计与实现
java·spring boot·python·mysql·vue
TechNomad12 小时前
Kotlin_Lambda编程详解
android·kotlin
熊猫_豆豆13 小时前
QT6 Android C++ 自制美观闹钟
android·c++·qt·闹钟
美狐美颜SDK开放平台13 小时前
Android/iOS直播APP平台开发中的视频美颜SDK优化技巧
android·ios·音视频·美颜sdk·第三方美颜sdk