Canal解决Mysql和Redis数据同步问题

目录

前言

一、Mysql主从工作原理

主从复制步骤:

二、使用方法

1.软件下载

软件需求(所有安装包,我的资源都有)

2.修改配置

1:数据库配置修改

2:canal配置修改

3:RocketMQ配置

4:RocketMQ可视化工具配置

3:测试数据

1:启动canal 与 RocketMQ 和 RocketMQ可视化工具

4:Java控制Redis和数据同步

1:准备SpringBoot项目

2:配置文件

总结


前言

今天带给大家的是阿里的一个工具Canal的使用方法,也是市面上解决数据同步相对成熟的方法。

一、Mysql主从工作原理

Mysql主从,根据2/8原则,80%的性能问题都在读上面,当我们数据库的读并发较大的时候,我们可以使用Mysql主从来分担读的压力。它的原理是所有的写操作在主库上,读操作在从库上,当然主库也可以承担读请求,而从库的数据则通过主库复制而来

主从复制步骤:

将Master的binary-log日志文件打开,mysql会把所有的DDL,DML,TCL写入BinaryLog日志文件中
Master会生成一个 log dump 线程,用来给从库的 i/o线程传binlog
从库的i/o线程去请求主库的binlog,并将得到的binlog日志写到中继日志(relaylog)中
从库的sql线程,会读取relaylog文件中的日志,并解析成具体操作,通过主从的操作一致,而达到最终数据一致

而Canal的工作原理就是伪装成mysql的从库去获取Binlog中SQL语句再更新到Redis。

二、使用方法

1.软件下载

软件需求(所有安装包,我的资源都有)

1:Mysql mysql 5.5以上 (有需要的伙伴可以去我资源里自取)

2:Canal组件:官网下载 Canal : https://github.com/alibaba/canal/releases(有需要的资源自取)

3:RocketMQ :官网下载:http://rocketmq.apache.org/release_notes/release-notes-4.2.0/

4:RocketMQ可视化工具 :下载地址:https://github.com/apache/rocketmq-externals/releases

2.修改配置

1:数据库配置修改

找到MYSQL的my.ini文件

Canal解决Mysql和Redis数据同步问题_第1张图片

Canal解决Mysql和Redis数据同步问题_第2张图片

 找到[mysqlid]开启Mysql bin-log日志 :首先你的数据库里必须有metaclassroom-system(可以自定义,建库建表就不描述了)修改好之后,重启Mysql服务。{搜索服务:找到mysql服务重启即可}

#开启bInlog
log-bin=mysql-bin
#给mysql服务指定一个唯一的ID
server-id=1
#以数据的方式写binlog日志 :statement 是记录SQL,row是记录数据
binlog-format=ROW
#同步的数据库名
binlog-do-db=metaclassroom-system
#忽略的表
binlog-ignore-db=mysql
# 启动mysql时不启动grant-tables授权表
skip-grant-tables

分配为canal分配角色权限canal文件配合文件可见(conf/example/instance.properties),SQL脚本,在相应库中执行即可。(数据库配置完成)

flush privileges;
#创建用户cannal
CREATE USER canal IDENTIFIED BY 'canal';
#把所有权限赋予canal,密码也是canal
GRANT ALL PRIVILEGES ON canaldb.user TO 'canal'@'%' identified by "canal";
//GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%' identified by "canal";
#刷新权限
flush privileges;

2:canal配置修改

资源下载后解压

Canal解决Mysql和Redis数据同步问题_第3张图片

 进入conf/example/instance.properties,修改配置

master.address :Mysql的地址,默认是3306
dbUsername :上面开通的Mysql用户
dbPassword : 密码
canal.mq.topic=example : 数据同步到MQ中的topic名字

进入conf/canal.properties,修改为RocketMQ方式,配置好之后,找到 canal 安装目录下 bin目录下的 startup.bat 双击启动

# 这里使用RocketMQ
canal.serverMode = rocketMQ
........
# RocketMQ的地址
rocketmq.namesrv.addr = 127.0.0.1:9876

3:RocketMQ配置

RocketMQ解压好了之后需要,配置RocketMQ的环境配置RocketMQ_HOME(修改runbroker.cmd)的内存大小,默认也可。提供启动脚本 {创建txt文件,写入之后修改后缀为bat即可双击运行}

start mqnamesrv.cmd

start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true

4:RocketMQ可视化工具配置

解压后,修改配置:src/main/resource/application.properties ,配置端口号,以及Name Server 的地址

server.contextPath=
server.port=8080
#spring.application.index=true
spring.application.name=rocketmq-console
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
logging.config=classpath:logback.xml
#if this value is empty,use env value rocketmq.config.namesrvAddr  NAMESRV_ADDR | now, you can set it in ops page.default localhost:9876
rocketmq.config.namesrvAddr=127.0.0.1:9876
#if you use rocketmq version < 3.5.8, rocketmq.config.isVIPChannel should be false.default true
rocketmq.config.isVIPChannel=
#rocketmq-console's data path:dashboard/monitor
rocketmq.config.dataPath=/tmp/rocketmq-console/data
#set it false if you don't want use dashboard.default true
rocketmq.config.enableDashBoardCollect=true

3:测试数据

1:启动canal 与 RocketMQ 和 RocketMQ可视化工具

为我们同步的数据库添加数据。

 浏览器输入你配置的可视化工具的地址{进入Message,搜索配置的Topic}

例如:http://127.0.0.1:8080/

 表示配置成功!

4:Java控制Redis和数据同步

1:准备SpringBoot项目

导入如下依赖:


        
            org.springframework.boot
            spring-boot-starter-data-redis
            
                
                    io.lettuce
                    lettuce-core
                
            
        
        
        
            redis.clients
            jedis
        
         
        
            org.apache.rocketmq
            rocketmq-spring-boot-starter
            2.0.4
        
      
        
            org.springframework.boot
            spring-boot-starter-web
        

2:配置文件

server:
  port: 11008
spring:
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password: 123456
    jedis:
      pool:
        max-wait: 2000ms
        min-idle: 2
        max-idle: 8
  application:
    name: service-system #服务名
rocketmq:
  name-server: 127.0.0.1:9876
  # 是否开启自动配置
  producer:
    enable-msg-trace: true
    group: "service-producer"
    # 消息最大长度 默认 1024 * 4 (4M)
    max-message-size: 4096
    # 发送消息超时时间,默认 3000
    send-message-timeout: 3000
    # 发送消息失败重试次数,默认2
    retry-times-when-send-failed: 2
    retry-times-when-send-async-failed: 2

3:创建新项目启动加载热点数据

@Component
@Slf4j
public class StartConfig implements ApplicationRunner {

    @Autowired
    private StartProperties startProperties;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("开始加载redis,字典数字据");
        // 执行你的方法
        startProperties.initialization();
        log.info("加载结束!");
    }
}

4:创建MQ消费者,消费消息

@Slf4j
@Component
@RocketMQMessageListener(topic = "example",
        selectorExpression="*" 
        ,consumerGroup = "canal-syn-consumer"
        ,messageModel = MessageModel.CLUSTERING
)
public class CanalSynListenner implements RocketMQListener {

    //注入Redis
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void onMessage(MessageExt messageExt) {
        try {
            String json = new String(messageExt.getBody(), "utf-8");
            CanalSynBlack canalSynDto = JSON.parseObject(json, CanalSynBlack.class);
            log.info("canal同步 {}", canalSynDto);
            if(canalSynDto.getType().equals("INSERT") || canalSynDto.getType().equals("UPDATE")){
                canalSynDto.getData().forEach(blacklist -> {
                    redisTemplate.opsForValue().set("ID:"+blacklist.getId(),blacklist);
                });
            }else if (canalSynDto.getType().equals("DELETE")){
                canalSynDto.getData().forEach(blacklist -> {
                    redisTemplate.delete("ID:"+blacklist.getId());
                });
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

总结

以上就是今天全部内容,本文介绍了Canal的配置与使用。对你有帮助的话,还是请一键三连哦!

你可能感兴趣的:(Redis,redis,缓存,中间件,java)