记录一次安装canal同步mysql数据到es的经历
ps:工作中需要搭建elasticsearch配合canal,实现数据库表任何固定字段的变动都要同步到es的需求,过程蛮坑的,记录下,防止遗忘。另外,得!翻!墙!不然github上访问不了,灰常麻烦
各软件版本:
| 软件 | 版本 | 下载方式 |
|---|---|---|
| mysql | 8.0.39 | – |
| kibana | 8.19.6 | https://www.elastic.co/cn/downloads/past-releases/kibana-8-19-6 |
| elasticsearch | 8.19.6 | docker |
| canal-server | v1.1.8 | docker |
| canal-adapter | v1.1.8 | https://github.com/alibaba/canal/releases/tag/canal-1.1.8 |
一、安装elasticsearch
1.拉取镜像
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/elasticsearch:8.19.6
2.创建目录与配置文件
# 创建主目录及其子目录
sudo mkdir -p /home/elasticsearch/{data,plugins,config}
# 授予目录读写权限,避免容器内无权限操作
sudo chmod -R 777 /home/elasticsearch/
3.创建Elasticsearch的配置文件 elasticsearch.yml 并写入基本配置
# 编辑配置文件
echo 'http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
xpack.security.enabled: false
xpack.security.enrollment.enabled: false' | sudo tee /home/elasticsearch/config/elasticsearch.yml
http.host: 0.0.0.0 使得ES可以被外部网络访问。
http.cors.enabled: true 和 http.cors.allow-origin: “*” 用于开启跨域访问支持,便于后续使用Elasticsearch-head等工具连接。
这边因为是内网使用,所以关闭了鉴权,如果需要鉴权,去掉最后两行即可
4.启动Elasticsearch容器
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -v /home/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /home/elasticsearch/data:/usr/share/elasticsearch/data -v /home/elasticsearch/plugins:/usr/share/elasticsearch/plugins --restart=unless-stopped swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/elasticsearch:8.19.6
这边是单机模式启动,配置文件挂载到外部,以便后续有修改需求
es很大可能需要比默认更大的内存映射区域的最大数量,可以通过修改vm.max_map_count参数实现
临时调整(重启后失效):
sudo sysctl -w vm.max_map_count=262144
永久调整(需要修改配置文件):
在/etc/sysctl.conf文件中添加或修改一行:
vm.max_map_count=262144
然后执行sudo sysctl -p使其立即生效。
5.安装ik分词器并重启elasticsearch
网上都是方法,不赘述
二、安装并使用kibana配置索引
1.从es官网下载安装包,上传服务器并解压
2.编辑 config/kibana.yml 文件
server.port: 5601
server.host: "0.0.0.0" # 允许远程访问
elasticsearch.hosts: ["http://localhost:9200"] # 根据你的ES地址调整
# i18n.locale: "zh-CN" # 可选:设置中文界面[citation:7]
如果ES有认证,需配置elasticsearch.username和elasticsearch.password。
若ES不在本机,将localhost替换为ES服务器的实际IP。
3.启动服务
在终端执行 ./bin/kibana 前台启动,或配置为服务
4.配置索引

在索引管理中,打开控制台,配置索引
在控制台添加索引信息,博主这边只需要一个搜索条件,所以就是主键加需要的字段
三、操作mysql
1.修改MySQL配置文件
编辑MySQL的配置文件(如my.cnf或mysqld.cnf),确保包含以下设置
[mysqld]
log-bin=mysql-bin # 开启binlog
binlog-format=ROW # 设置binlog格式为ROW
server-id=1 # 配置服务器ID
修改后需要重启服务让修改的配置生效
2.创建Canal专用用户
Canal需要连接到MySQL,建议创建一个专门的用户并授予必要的权限
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal_password';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;
四、安装canal-server
1.拉取镜像
docker pull canal/canal-server:v1.1.8
2.准备配置文件
首次启动容器主要是为了复制出默认配置文件:
# 创建docker实例
docker run -p 11111:11111 --name canal -d canal/canal-server:v1.1.8
# 创建配置文件存储路径
mkdir -p /opt/software/canal_server
# 将docker实例中配置文件复制到创建目录中
docker cp canal:/home/admin/canal-server/conf /opt/software/canal_server
# 删除实例
docker rm -f canal
3.运行Canal容器修改复制到宿主机上的配置文件。
主要是/opt/software/canal_server/conf/example/instance.properties
# 配置MySQL主库的地址和端口,如果是docker容器,这边得是宿主机ip
canal.instance.master.address=127.0.0.1:3306
# 配置在MySQL中创建的Canal用户名和密码
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal_password
# 配置Canal关注哪些数据库表的变更,通常使用正则表达式
# 例如 `.*\\..*` 表示所有数据库的所有表[citation:2],`mytest.user`表示mytest库的user表
canal.instance.filter.regex=.*\\..*
4.运行Canal容器
使用挂载了配置目录的方式运行容器:
docker run -p 11111:11111 \
--name canal \
-v /opt/software/canal_server/conf:/home/admin/canal-server/conf \
-v /opt/software/canal_server/logs:/home/admin/canal-server/logs \
-d \
--restart unless-stopped \
canal/canal-server:v1.1.8
5.查看canal是否注册mysql成功
查看mysql是否有名为canal的从库信息
检查进程列表:
SHOW PROCESSLIST;

有这条信息代表canal-server已经安装成功
五、安装canal-adapter
1.下载软件
从github上下载软件,地址:https://github.com/alibaba/canal/releases/tag/canal-1.1.8
2.上传linux服务器并解压
博主解压目录为:/opt/software/canal_adapter
3.修改配置文件
conf/application.yml
server:
port: 8081
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
canal.conf:
mode: tcp #tcp kafka rocketMQ rabbitMQ
flatMessage: true
zookeeperHosts:
syncBatchSize: 1000
retries: 10
timeout:
accessKey:
secretKey:
consumerProperties:
# canal tcp consumer
canal.tcp.server.host: 127.0.0.1:11111
canal.tcp.zookeeper.hosts:
canal.tcp.batch.size: 500
canal.tcp.username:
canal.tcp.password:
srcDataSources:
defaultDS:
url: jdbc:mysql://127.0.0.1:3306/xxxxxx?useUnicode=true
username: root
password: 123456
canalAdapters:
- instance: example # canal instance Name or mq topic name
groups:
- groupId: g1
outerAdapters:
- name: es8
key: es-key
hosts: http://127.0.0.1:9200 # 127.0.0.1:9200 for rest mode
properties:
mode: rest # transport or rest
security.auth: elastic:12345678
# security.ca.path: /etc/canal/http_ca.crt
cluster.name: docker-cluster
- name: logger
内里相关地址和账户密码按照需求修改
ps:该配置文件里面的retries默认为-1,意思是如果同步失败,会无限重试,博主刚开始配置文件有误,错误日志无限打印,看的很心烦,建议改成几次,能看到错误信息就好
conf/es8/mytable.yml
dataSourceKey: defaultDS # 对应applicaiton.yml中srcDataSources下内容
destination: example # 对应applicaiton.yml中canalAdapters.instance
outerAdapterKey: es-key # 对应applicaiton.yml中outerAdapters.key
groupId: g1 # 对应applicaiton.yml中groupId
esMapping:
_index: "qa_question"
_id: "id"
upsert: true
#pk: id
sql: "SELECT id, question FROM qa_question"
# 可选:明确字段映射(如果自动映射有问题)
# etlCondition: " where del_flag=0" # 如果需要过滤删除的数据
commitBatch: 100
根据application.yml的配置,conf/es8下面所有yml结尾的文件内容都会被加载。
注意这边esMapping的配置一定要和es中匹配索引的内容相对应,不然同步会有问题。
4.启动软件,并查看日志是否正常
sh bin/startip.sh
六、验证是否可以同步
1.通过执行如下命令进行全量 ETL
curl -X POST http://127.0.0.1:8081/etl/es8/mytable.yml
mytable.yml 为适配器文件的名称。
如果成功,结果类似以下
2.修改mysql相关表数据,查看es中是否有更新
GET /qa_question/_search
在Kibana控制台查询索引中内容,确认最新数据是否有同步。
-----------------------------------------------20251126分割线---------------------------------------------------
今天记录一个容易忽略的问题
canal adapter添加不同数据库的多个表配置时,需要特别注意./conf/application.yml主配置文件中的srcDataSources参数,多个数据库需要配置多个dataSourceKey,不同的同步文件下药对应自己应该对应的dataSourceKey,不然容易出现库和表不同步,导致同步失败的错误
!](https://i-blog.csdnimg.cn/direct/e75fbafe35214e1c9c47db898650a41e.png)
索引对应文件中的sql,一定要添加别名!!!!!
,不然同步时会判断没有owner,导致取不到值,报空指针错误:java.lang.NullPointerException: Cannot invoke “Object.toString()” because “pkVal” is null。这里感谢博主分享问题解决方案:https://blog.csdn.net/2401_89221445/article/details/154947045,自己看了半天也没发现是这么个小细节,一直以为是啥其他的配置或者是版本适配性问题

更多推荐



所有评论(0)