使用canal将mysql同步到es中

使用canal将mysql同步到es中,第1张

因为自己项目中需要用到mysql数据同步到es中,查找了相关资料最后决定用canal来做,所以便有了本文,下面一起来看如何使用canal吧

根据 https://github.com/alibaba/canal 上的原理解释,我们知道 canal 会模拟 mysql slave 的交互协议,伪装自己为 mysql slave,然后向 mysql master 发送 dump 协议。

mysql master 收到 dump 请求,开始推送 binary log 给 slave(也就是 canal),然后 canal 解析 binary log 对象(原始为 byte流)。

经 canal 解析过的对象,我们使用起来就非常的方便了。

再根据 https://github.com/alibaba/canal/releases 提供的版本信息,你会发现 canal 其实相当于一个中间件,专门用来解析 MySQL 的 binlog 日志。canal 解析好了之后,会封装成一个数据对象,通过 protobuf3.0 协议进行交互,让 canal 客户端进行消费。

根据上面的解释,以及 canal 提供的版本信息,我们在使用 canal 的时候,首选要安装一个 canal.deployer-1.1.4.tar.gz 进行解析 MySQL 的 binlog 日志。

下载后,复制 canal.deployer-1.1.4.tar.gz 到 MySQL 主机上,比如放在 /usr/local/soft/目录下。然后依次执行下面的命令:

然后修改 canal 的配置文件 vim conf/example/instance.properties

这三项改成你自己的,比如我的配置如下:

然后保存并退出。(VI 模式下,按 Esc 输入 :wq 回车退出。)

接着,我们检查一下 MySQL 的配置。确定版本和是否开启了 binlog 日志,以及日志格式。

canal 支持 binlog 格式为 ROW 的模式。如果你没开启 binlog,并且格式是非 row 的,建议修改一下 mysql 的配置文件。

执行 mysql –help | grep my.cnf 找到 mysql 的 my.cnf 文件。

执行 vim /etc/my.cnf 命令。添加下面 3 个配置。

然后保存并退出。

接着执行 sudo service mysqld restart 重启 MySQL。

需要注意的是你的 mysql 用户,必须要有 REPLICATION SLAVE 权限。该权限授予 slave 服务器以该账户连接 master 后可以执行 replicate *** 作的权利。

如果没有权限,则使用 root 账户登录进 MySQL,执行下面的语句,创建用户,分配权限。

MySQL 启动后,就可以开启 canal 服务了。

开启后,观察 canal 服务的日志,确保服务正常。

查看 canal 的日志

确定没有问题后,开始编写我们的测试程序。

pom.xml 中导入下面的依赖。

使用JAVA进行测试

然后执行 main 方法。你再修改修改 MySQL 中的数据,你会发现所有改变都同步过来了。上面是使用的Java代码进行运行,如果想用canal.adapter来进行运行可以下载

放入服务器中,依次执行下面命令

然后修改配置文件 :

然后将需要运行存储到es的的yml文件放入到

目录下。例如:

然后开启canal-adapter服务

/usr/local/soft/canal-adapter/bin/startup.sh

查看 canal-adapter 的日志,确定没有问题后修改数据 就可以同步到es了

注意:

1、canal-adapter自带mysql连接使用的5.x的,如果自己安装的是高版本的mysql需要自己去/usr/local/soft/canal-adapter/lib增加对应的jar包

2、因项目中同步es使用的sql中有数据库中没有的字段,导致原生程序一直报异常,后修改源码中

加了一个判断后才可以

3、es中使用的date字段类型和数据库中不一致,所以这里又修改了部分源码兼容我们项目中的类型

可以根据各自情况修改。

先假设有主机 A 和 B ( Linux 系统),主机 A 的 IP 分别是 1.2.3.4 (当然,也可以是动态的),主机 B 的 IP 是 5.6.7.8 。两个主机都装上了 PHP+Mysql ,现在 *** 作的是主机 A 上的资料,如果另外一个主机 B 想跟 A 的资料进行同步,应该怎么做呢? OK,我们现在就动手。 首先,如果要想两个主机间的资料同步,一种方法就是主机 A 往主机 B 送资料,另外一种主法就是主机 B 到主机 A 上拿资料,因为 A 的 IP 是动态的(假设),所以我们就得从主机 A 往主机 B 送资料。 在主机 B 上创建一个 Mysql 账户。 # GRANT ALL ON test.* TO user@% IDENTIFIED BY "password"//创建用户 user,可以从任何机器访问到主机 B 上的 test 数据库。 如果这里显示错误,先把 % 改为一个 IP ,然后再利用 phpMyAdmin 把 IP 改为 % ,测试无误后就可以写 php 程序。 <? $link=mysql_pconnect("localhost","user","password")mysql_pconnect("localhost","user","password")//连接本机(主机A)的数据库 mysql_select_db("test")//选择数据库test $re=mysql_query("select * from table order by id desc")$num=mysql_numrows($re)if (!empty($num)) { ...

如果你被上述问题困扰过,可以参考以下方案

这里需要介绍三种字段的type,分别是 object 、 nested 、 join

现在有个问题,下面的数据如何存入到es中呢,它对应的mapping应该是什么样的呢

name、url这些字段好处理,直接设定字段 "type" : "text" 或者 "type" : "keword" 或者

就行了,但是对于address和links,这种里面包含json对象,或者数组的,怎么处理呢。这里可以采用 "type" : "object" 来处理。如下

可能会对links有疑问,它明明是数组,却怎么和address的设置类似。其实es中是没有单独的数组这一类型,因为他所有的字段都支持数组,比如你是text,你可以放多个值进去,以name为例,你可以放 "name":["张三", "李四"] 这样的数据进去。

而且,es默认对这种嵌套结构建立的索引就是object类型, "type": "object" 可以省略

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存