canal+Kafka实现mysql与redis数据同步

canal+Kafka实现mysql与redis数据同步,第1张

前言

上篇文章简单介绍canal概念,本文结合常见的缓存业务去讲解canal使用。在实际开发过程中,通常都会把数据往redis缓存中保存一份,做下简单的查询优化。如果这时候数据库数据发生变更 *** 作,就不得不在业务代码中写一段同步更新redis的代码,但是这种 数据同步的代码和业务代码糅合在一起 看起来不是很优雅,而且还会出现数据不一致问题。那能不能把这部分同步代码从中抽离出来,形成独立模块呢?答案是肯定的,下面通过canal结合Kafka来实现mysql与redis之间的数据同步。

架构设计

通过上述结构设计图可以很清晰的知道用到的组件:MySQL、Canal、Kafka、ZooKeeper、Redis。

Kafka&Zookeeper搭建

首先在 官网 下载Kafka:

下载后解压文件夹,可以看到以下几个文件:

Kafka内部自带了zookeeper,所以暂不需要去下载搭建zookeeper集群,本文就使用Kafka自带zookeeper来实现。

通过上述zookeeper启动命令以及Kafka启动命令把服务启动,可以通过以下简单实现下是否成功:

Canal搭建

canal搭建具体可以参考上文,这里只讲解具体的参数配置:

找到/conf目录下的canal.properties配置文件:

然后配置instance,找到/conf/example/instance.properties配置文件:

经过上述配置后,就可以启动canal了。

测试

环境搭建完成后,就可以编写代码进行测试。

1、引入pom依赖

2、封装Redis工具类

在application.yml文件增加以下配置:

封装一个 *** 作Redis的工具类:

3、创建MQ消费者进行同步

创建一个CanalBean对象进行接收:

最后就可以创建一个消费者CanalConsumer进行消费:

测试Mysql与Redis同步

mysql对应的表结构如下:

启动项目后,新增一条数据:

可以在控制台看到以下输出:

如果更新呢?试一下Update语句:

同样可以在控制台看到以下输出:

经过测试完全么有问题。

总结

既然canal这么强大,难道就没缺点嘛?答案当然是存在的啦,比如:canal只能同步增量数据、不是实时同步而是准实时同步、MQ顺序问题等; 尽管有一些缺点,毕竟没有一样技术或者产品是完美的,最重要是合适。比如公司目前有个视图服务提供宽表搜索查询功能就是通过 同步Mysql数据到Es采用Canal+Kafka的方式来实现的。

本文以开源项目SpringBlade和Saber为例。

1、创建自定义网络

目的是将用到的服务都放到同一个网络段,以方便互相通信。

docker network create --subnet 172.19.0.0/16 mynetwork

2、Docker安装MySQL、Redis、Nginx

(1)安装MySQL

docker pull mysql:5.7.30

cd ~

mkdir docker/mysql/{conf,logs,data} -p

cd docker/mysql

docker run --name mysql_blade --network=mynetwork --ip=172.19.0.6 -p 3307:3306 -v PWD/logs:/var/log/mysql -v PWD/data:/data:rw -v $PWD/conf/redis.conf:/etc/redis/redis.conf:ro --privileged=true --name redis-6389 -d redis redis-server /etc/redis/redis.conf

(3)安装Nginx

将Saber发布到Nginx中要用到

docker pull nginx

2、Docker打包SpringBlade

3、Docker打包并发布Saber

(1)编写nginx.conf

cd Saber

touch nginx.conf,写入以下内容:

//nginx.conf开始

user root

worker_processes 1

error_log /var/log/nginx/error.log warn

pid/var/run/nginx.pid

events {

worker_connections 1024

}

http {

include /etc/nginx/mime.types

default_type application/octet-stream

}

//nginx.conf结束

(2)修改env.js文件

baseUrl要与下面的SpringBlade容器的地址和端口匹配:

(3)编写Dockerfile

编写dockerfile并将其放到与dist同一目录:

FROM nginx

VOLUME /tmp

ENV LANG en_US.UTF-8

ADD ./dist/ /usr/share/nginx/html/

COPY./nginx.conf /etc/nginx/

EXPOSE 1889

EXPOSE 443

(4)打包并发布

cd ~

mkdir docker/saber/conf -p

cd docker/saber

cp ~/Saber/nginx.conf conf

yarn run build

docker build -t saber:1.0 .(注意最后的.)

docker run -itd --name saber --network=mynetwork --ip=172.19.0.8 -p 1889:1889 -v $PWD/conf:/mnt/ saber:1.0

4、Docker打包并发布SpringBlade

(1)pom.xml配置

/

<docker.repostory>10.10.0.127:10080</docker.repostory>

<docker.registry.name>blade</docker.registry.name>

<docker.image.tag>0.0.1</docker.image.tag>

<docker.maven.plugin.version>1.4.10</docker.maven.plugin.version>

<build>

<finalName>SpringBlade</finalName>

<resources>

<resource>

<directory>src/main/resources</directory>

</resource>

<resource>

<directory>src/main/java</directory>

<includes>

<include>* / .xml</include>

</includes>

</resource>

</resources>

<pluginManagement>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<version> {project.build.finalName}</finalName>

</configuration>

<executions>

<execution>

<goals>

<goal>repackage</goal>

</goals>

</execution>

</executions>

</plugin>

<plugin>

<groupId>com.spotify</groupId>

<artifactId>dockerfile-maven-plugin</artifactId>

<version> {project.basedir}</contextDirectory>

<useMavenSettingsForAuth>true</useMavenSettingsForAuth>

<repository> {docker.registry.name}/ {docker.image.tag}</tag>

<buildArgs>

<JAR_FILE>target/ {java.version}</source>

<target>${java.version}</target>

<encoding>UTF-8</encoding>

<compilerArgs>

<arg>-parameters</arg>

</compilerArgs>

</configuration>

</plugin>

</plugins>

</build>

(2)yml配置

redis及mysql都要与前面的创建容器时的配置相同:

(3)创建私有仓库(利用Harbor)

在harbor管理界面创建项目blade,下面上传镜像的时候要加入项目路径。

(4)打包

mvn clean install dockerfile:build -Dmaven.test.skip=true

(5)上传到私有仓库

两种方式:

mvn dockerfile:push

或者docker push 10.10.0.127:10080/blade/springblade:0.0.1

然后在Harbor管理后台就可以看到镜像了。

要pull下来的话:

docker pull 10.10.0.127:10080/blade/springblade:0.0.1

(6)发布

cd ~

mkdir docker/blade/app -p

cd docker/blade

docker run -itd --name blade --network=mynetwork --ip=172.19.0.7 -p 9001:9001 -v $PWD/app:/mnt/ 10.10.0.127:10080/blade/springblade:0.0.1

至此,就可以通过localhost:1889来访问Saber了。

另外,我通过uri来区分多租户。例如localhost:1889是管理租户,localhost:1889/test是名为test的租户。这样就避免了在登录界面填写租户id。

mysql 与Redis 数据一致性问题 直接将Redis清空

中间件 canal框架 基于 docker环境构建

canal 框架 原理:

<u>https://gitee.com/mirrors/canal?utm_source=alading&utm_campaign=repo</u>

canal 框架原理

1,canal伪装成mysql从节点 订阅mysql 主节点的binlog文件

2,当我们的mysql 主节点 binlog 文件发生了变化,则将binlog 文件发送给canal服务器端

3,canal 服务器端将该binlog 文件二进制转换成json格式给canal客户端

4,canal客户端在将改数据同步到Redis/ES

基于Binlog 开启方式

1.mysql 开启binlog 文件配置

windows 配置

查询 my.ini配置文件位置

C:\ProgramData\MySQL\MySQL Server 5.7

2, linux mysql

安装canal

进入容器

编辑配置文件

重启canal

Docker-compose 构建canal

canal.instance.mysql.slaveId:slaveId不能与mysql的serverId一样

canal.instance.master.address:mysql地址

canal.instance.dbUsername:mysql账号

canal.instance.dbPassword:mysql密码


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8625195.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-19
下一篇 2023-04-19

发表评论

登录后才能评论

评论列表(0条)

保存