k8s集群中部署canal集群
k8s集群中部署canal集群
canal原理详见[wiki](Home · alibaba/canal Wiki · GitHub),简单理解为
1、 canal将自己伪装成一个mysql的从服务器,向主服务器发送dump协议
2、 mysql主服务器收到dump协议后,推送binlog日志给canal
3、 canal解析binlog日志流
角色及功能
角色 | 功能 |
---|---|
mysql | 存储canal-admin、canal-server相关数据 |
zookeeper | 存储集群、客户端、消费位点等相关信息。负责canal-server之间的负载调度 |
canal-admin | 提供可视化界面,管理canal-server |
canal-server | 工作节点 |
前置条件
-
mysql
-
zookeeper
注意事项
-
使用canal监听的mysql必须开启binlog,且必须是row模式
-
canal-clent必须使用四层网络连接到canal-server
-
canal-admin使用mysql存储数据信息;如果不指定外部数据库的话,canal-admin会在本地启一个mysql用作数据存储
-
如使用外部数据库,需要对数据库进行初始化操作,可以到[github](GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件)上获取初始化脚本
-
canal-admin的web页面的默认登陆用户密码是:admin/123456
-
canal-admin 与 canal-server采用双向验证的方式保证连接
-
canal-server仅作为工作节点,不存储任何数据
-
instance的监控位点信息存储在zookeeper中
-
新建的instance名称需要在该zookeeper保持唯一
一、部署canal-admin
1.1、初始化数据库
- 需要两个库,一个用来存放canal-admin的数据,需要使用sql进行初始化操作;另一个用来存放canal-server工作时instance监听的库的数据结构信息,无需初始化
canal-admin的初始化sql如下
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `canal_manager` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */; USE `canal_manager`; SET NAMES utf8; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for canal_adapter_config -- ---------------------------- DROP TABLE IF EXISTS `canal_adapter_config`; CREATE TABLE `canal_adapter_config` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `category` varchar(45) NOT NULL, `name` varchar(45) NOT NULL, `status` varchar(45) DEFAULT NULL, `content` text NOT NULL, `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Table structure for canal_cluster -- ---------------------------- DROP TABLE IF EXISTS `canal_cluster`; CREATE TABLE `canal_cluster` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(63) NOT NULL, `zk_hosts` varchar(255) NOT NULL, `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Table structure for canal_config -- ---------------------------- DROP TABLE IF EXISTS `canal_config`; CREATE TABLE `canal_config` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `cluster_id` bigint(20) DEFAULT NULL, `server_id` bigint(20) DEFAULT NULL, `name` varchar(45) NOT NULL, `status` varchar(45) DEFAULT NULL, `content` text NOT NULL, `content_md5` varchar(128) NOT NULL, `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `sid_UNIQUE` (`server_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Table structure for canal_instance_config -- ---------------------------- DROP TABLE IF EXISTS `canal_instance_config`; CREATE TABLE `canal_instance_config` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `cluster_id` bigint(20) DEFAULT NULL, `server_id` bigint(20) DEFAULT NULL, `name` varchar(45) NOT NULL, `status` varchar(45) DEFAULT NULL, `content` text NOT NULL, `content_md5` varchar(128) DEFAULT NULL, `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `name_UNIQUE` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Table structure for canal_node_server -- ---------------------------- DROP TABLE IF EXISTS `canal_node_server`; CREATE TABLE `canal_node_server` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `cluster_id` bigint(20) DEFAULT NULL, `name` varchar(63) NOT NULL, `ip` varchar(63) NOT NULL, `admin_port` int(11) DEFAULT NULL, `tcp_port` int(11) DEFAULT NULL, `metric_port` int(11) DEFAULT NULL, `status` varchar(45) DEFAULT NULL, `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Table structure for canal_user -- ---------------------------- DROP TABLE IF EXISTS `canal_user`; CREATE TABLE `canal_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(31) NOT NULL, `password` varchar(128) NOT NULL, `name` varchar(31) NOT NULL, `roles` varchar(31) NOT NULL, `introduction` varchar(255) DEFAULT NULL, `avatar` varchar(255) DEFAULT NULL, `creation_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; SET FOREIGN_KEY_CHECKS = 1; -- ---------------------------- -- Records of canal_user -- ---------------------------- BEGIN; INSERT INTO `canal_user` VALUES (1, 'admin', '6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9', 'Canal Manager', 'admin', NULL, NULL, '2019-07-14 00:05:28'); COMMIT; SET FOREIGN_KEY_CHECKS = 1;
1.2、部署canal-admin
官方提供了canal-admin的镜像,可以使用官方镜像直接进行部署
部署时需要使用ENV的方式定义一些acnal-admin中的参数
- env: # 服务端口 - name: server.port value: '8089' # 外部数据的URL - name: spring.datasource.address value: '192.168.31.204:3306' # 数据库名称 - name: spring.datasource.database value: canal_admin # 数据库用户名 - name: spring.datasource.username value: canal_admin # 数据库密码 - name: spring.datasource.password value: 123qwe!@#QWE # 用来与canal-server连接的用户名 - name: canal.adminUser value: admin # 用来与canal-server连接的密码(明文) - name: canal.adminPasswd value: admin
1.3、创建集群
1、canal-admin部署完成之后,浏览器访问服务端口即可进入管理后台(默认用户名密码 admin/123456)
2、在集群管理中选择新建集群,填写集群名称与ZK地址后,点击确定即可创建新的canal-server集群
3、在集群管理中选择集群,操作-->主配置,修改集群的主配置文件
需要修改的配置项如下:
# canal-server连接的canal-admin的用户名 canal.admin.user = admin # canal-server连接的canal-admin的密码(密文) canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D615029441 # canal-server的模式,主要为tcp或mq canal.serverMode = tcp # 全局的spring配置方式的组件文件 # 所有组件的数据都选择内存模式,速度快,但无数据存储,重启后又会回到初始位点进行解析 #canal.instance.global.spring.xml = classpath:spring/memory-instance.xml # 基于file的持久化模式,支持单点canal,无HA,简单易用,会将位点信息写到meta.dat文件中 #canal.instance.global.spring.xml = classpath:spring/file-instance.xml # store选择了内存模式,其余的parser/sink依赖的位点管理选择了持久化模式,目前持久化的方式主要是写入zookeeper,保证数据集群共享 canal.instance.global.spring.xml = classpath:spring/default-instance.xml # 是否开启tablemeta的tsdb能力 canal.instance.tsdb.enable = true canal.instance.tsdb.dir = ${canal.file.data.dir:../conf}/${canal.instance.destination:} # tsdb的数据库连接地址 canal.instance.tsdb.url = jdbc:mysql://192.168.31.204:3306/canal_config?useSSL=false&useUnicode=true&characterEncoding=UTF-8 # tsdb的数据库用户名 canal.instance.tsdb.dbUsername = canal_admin # tsdb的数据库密码 canal.instance.tsdb.dbPassword = 123qweQWE!@# # v1.0.25版本新增,全局的tsdb配置方式的组件文件 #canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml canal.instance.tsdb.spring.xml = classpath:spring/tsdb/mysql-tsdb.xml
配置文件全文详解如下:
################################################# ######### common argument ############# ################################################# # tcp bind ip canal.ip = # register ip to zookeeper canal.register.ip = # canal-server的服务端口 canal.port = 11111 canal.metrics.pull.port = 11112 # canal instance user/passwd # canal.user = canal # canal.passwd = E3619321C1A937C46A0D8BD1DAC39F93B27D4458 # canal admin config #canal.admin.manager = 127.0.0.1:8089 # canal-server连接的canal-admin的端口 canal.admin.port = 11110 # canal-server连接的canal-admin的用户名 canal.admin.user = admin # canal-server连接的canal-admin的密码(密文) canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D615029441 # admin auto register #canal.admin.register.auto = true #canal.admin.register.cluster = #canal.admin.register.name = # canal-admin中定义的集群的zk地址 canal.zkServers = zookeeper-svc:2181 # flush data to zk # canal-server持久化数据到zookeeper上的更新频率,单位毫秒 canal.zookeeper.flush.period = 1000 canal.withoutNetty = false # tcp, kafka, rocketMQ, rabbitMQ # canal-server的模式,主要为tcp或mq canal.serverMode = tcp # flush meta cursor/parse position to file # 主要针对h2-tsdb.xml时对应h2文件的存放目录,默认为conf/xx/h2.mv.db canal.file.data.dir = ${canal.conf.dir} canal.file.flush.period = 1000 ## memory store RingBuffer size, should be Math.pow(2,n) # canal内存store中可缓存buffer记录数,需要为2的指数 canal.instance.memory.buffer.size = 16384 ## memory store RingBuffer used memory unit size , default 1kb # 内存记录的单位大小,默认1KB,和buffer.size组合决定最终的内存使用大小 canal.instance.memory.buffer.memunit = 1024 ## meory store gets mode used MEMSIZE or ITEMSIZE # canal内存store中数据缓存模式 # 1、ITEMSIZE : 根据buffer.size进行限制,只限制记录的数量 # 2、MEMSIZE : 根据buffer.size * buffer.memunit的大小,限制缓存记录的大小 canal.instance.memory.batch.mode = MEMSIZE canal.instance.memory.rawEntry = true ## detecing config # 是否开启心跳检查 canal.instance.detecting.enable = false #canal.instance.detecting.sql = insert into retl.xdual values(1,now()) on duplicate key update x=now() # 心跳检查sql canal.instance.detecting.sql = select 1 # 跳检查频率,单位秒 canal.instance.detecting.interval.time = 3 # 心跳检查失败重试次数 canal.instance.detecting.retry.threshold = 3 # 心跳检查失败后,是否开启自动mysql自动切换 # 说明:比如心跳检查失败超过阀值后,如果该配置为true,canal就会自动链到mysql备库获取binlog数据 canal.instance.detecting.heartbeatHaEnable = false # support maximum transaction size, more than the size of the transaction will be cut into multiple transactions delivery canal.instance.transaction.size = 1024 # mysql fallback connected to new master should fallback times # canal发生mysql切换时,在新的mysql库上查找binlog时需要往前查找的时间,单位秒 # 说明:mysql主备库可能存在解析延迟或者时钟不统一,需要回退一段时间,保证数据不丢 canal.instance.fallbackIntervalInSeconds = 60 # network config # 网络链接参数,SocketOptions.SO_RCVBUF canal.instance.network.receiveBufferSize = 16384 # 网络链接参数,SocketOptions.SO_SNDBUF canal.instance.network.sendBufferSize = 16384 # 网络链接参数,SocketOptions.SO_TIMEOUT canal.instance.network.soTimeout = 30 # binlog filter config # 是否使用druid处理所有的ddl解析来获取库和表名 canal.instance.filter.druid.ddl = true # 是否忽略dcl语句 canal.instance.filter.query.dcl = false # 是否忽略dml语句(mysql5.6之后,在row模式下每条DML语句也会记录SQL到binlog中,可参考MySQL文档) canal.instance.filter.query.dml = false # 是否忽略ddl语句 canal.instance.filter.query.ddl = false # 是否忽略binlog表结构获取失败的异常(主要解决回溯binlog时,对应表已被删除或者表结构和binlog不一致的情况) canal.instance.filter.table.error = false # 是否dml的数据变更事件(主要针对用户只订阅ddl/dcl的操作) canal.instance.filter.rows = false # 是否忽略事务头和尾,比如针对写入kakfa的消息时,不需要写入TransactionBegin/Transactionend事件 canal.instance.filter.transaction.entry = false canal.instance.filter.dml.insert = false canal.instance.filter.dml.update = false canal.instance.filter.dml.delete = false # binlog format/image check # # 支持的binlog format格式列表(otter会有支持format格式限制) canal.instance.binlog.format = ROW,STATEMENT,MIXED # 支持的binlog image格式列表(otter会有支持format格式限制) canal.instance.binlog.image = FULL,MINIMAL,NOBLOB # binlog ddl isolation # ddl语句是否单独一个batch返回(比如下游dml/ddl如果做batch内无序并发处理,会导致结构不一致) canal.instance.get.ddl.isolation = false # parallel parser config # 是否开启binlog并行解析模式 canal.instance.parser.parallel = true ## concurrent thread number, default 60% available processors, suggest not to exceed Runtime.getRuntime().availableProcessors() #canal.instance.parser.parallelThreadSize = 16 ## disruptor ringbuffer size, must be power of 2 # binlog并行解析的异步ringbuffer队列(必须为2的指数) canal.instance.parser.parallelBufferSize = 256 # table meta tsdb info # 是否开启tablemeta的tsdb能力 canal.instance.tsdb.enable = true canal.instance.tsdb.dir = ${canal.file.data.dir:../conf}/${canal.instance.destination:} # tsdb的数据库连接地址 canal.instance.tsdb.url = jdbc:mysql://192.168.31.204:3306/canal_config?useSSL=false&useUnicode=true&characterEncoding=UTF-8 # tsdb的数据库用户名 canal.instance.tsdb.dbUsername = canal_admin # tsdb的数据库密码 canal.instance.tsdb.dbPassword = 123qweQWE!@# # dump snapshot interval, default 24 hour canal.instance.tsdb.snapshot.interval = 24 # purge snapshot expire , default 360 hour(15 days) canal.instance.tsdb.snapshot.expire = 360 ################################################# ######### destinations ############# ################################################# # 当前server上部署的instance列表,多个使用逗号分隔 canal.destinations = # conf root dir # conf/目录所在的路径 canal.conf.dir = ../conf # auto scan instance dir add/remove and start/stop instance # 开启instance自动扫描 # 如果配置为true,canal.conf.dir目录下的instance配置变化会自动触发 canal.auto.scan = true # instance自动扫描的间隔时间,单位秒 canal.auto.scan.interval = 5 # set this value to 'true' means that when binlog pos not found, skip to latest. # WARN: pls keep 'false' in production env, or if you know what you want. canal.auto.reset.latest.pos.mode = false # v1.0.25版本新增,全局的tsdb配置方式的组件文件 #canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml canal.instance.tsdb.spring.xml = classpath:spring/tsdb/mysql-tsdb.xml # 全局配置加载方式 canal.instance.global.mode = manager # 全局lazy模式 canal.instance.global.lazy = false # 全局的manager配置方式的链接信息 canal.instance.global.manager.address = ${canal.admin.manager} # 全局的spring配置方式的组件文件 # 所有组件的数据都选择内存模式,速度快,但无数据存储,重启后又会回到初始位点进行解析 #canal.instance.global.spring.xml = classpath:spring/memory-instance.xml # 基于file的持久化模式,支持单点canal,无HA,简单易用,会将位点信息写到meta.dat文件中 #canal.instance.global.spring.xml = classpath:spring/file-instance.xml # store选择了内存模式,其余的parser/sink依赖的位点管理选择了持久化模式,目前持久化的方式主要是写入zookeeper,保证数据集群共享 canal.instance.global.spring.xml = classpath:spring/default-instance.xml ################################################## ######### MQ Properties ############# ################################################## # aliyun ak/sk , support rds/mq canal.aliyun.accessKey = canal.aliyun.secretKey = canal.aliyun.uid= canal.mq.flatMessage = true canal.mq.canalBatchSize = 50 canal.mq.canalGetTimeout = 100 # Set this value to "cloud", if you want open message trace feature in aliyun. canal.mq.accessChannel = local canal.mq.database.hash = true canal.mq.send.thread.size = 30 canal.mq.build.thread.size = 8 ################################################## ######### Kafka ############# ################################################## kafka.bootstrap.servers = 127.0.0.1:6667 kafka.acks = all kafka.compression.type = none kafka.batch.size = 16384 kafka.linger.ms = 1 kafka.max.request.size = 1048576 kafka.buffer.memory = 33554432 kafka.max.in.flight.requests.per.connection = 1 kafka.retries = 0 kafka.kerberos.enable = false kafka.kerberos.krb5.file = "../conf/kerberos/krb5.conf" kafka.kerberos.jaas.file = "../conf/kerberos/jaas.conf" ################################################## ######### RocketMQ ############# ################################################## rocketmq.producer.group = test rocketmq.enable.message.trace = false rocketmq.customized.trace.topic = rocketmq.namespace = rocketmq.namesrv.addr = 127.0.0.1:9876 rocketmq.retry.times.when.send.failed = 0 rocketmq.vip.channel.enabled = false rocketmq.tag = ################################################## ######### RabbitMQ ############# ################################################## rabbitmq.host = rabbitmq.virtual.host = rabbitmq.exchange = rabbitmq.username = rabbitmq.password = rabbitmq.deliveryMode =
二、部署canal-server
官方提供了canal-server的镜像,可以直接使用官方镜像进行部署
容器重启后pod的IP会变化,自动注册到canal-admin上后,使用旧IP注册的server节点还是存在,并不会自动删除,会造成canadl-admin上有很多过期无用的server节点,所以需要使用StatefulSet方式进行部署
2.1、部署canal-server
部署时需要使用ENV的方式定义一些acnal-server中的参数
- env: # 取StatefulSet中的字段 - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name # 取StatefulSet中的字段 - name: SERVICE_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: 'metadata.labels[''app'']' # 取StatefulSet中的字段 - name: STS_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace # 使用#取到的StatefulSet中的字段,定义为canal-server的IP,用来连接canal-admin - name: canal.register.ip value: $(POD_NAME).$(SERVICE_NAME)-headless-svc.$(STS_NAMESPACE) # canal-admin的连接地址(配置该值后,canal-server会自动选择sh startup.sh local进行启动) - name: canal.admin.manager value: 'canal-admin-svc.mid:8089' # canal-admin服务的通信端口 - name: canal.admin.port value: '11110' # canal-admin用户名(用来与canal-admin双向验证) - name: canal.admin.user value: admin # canal-admin密码 密文形式,与canal-admin的canal.adminPasswd的值相同(用来与canal-admin双向验证) - name: canal.admin.passwd value: 4ACFE3202A5FF5CF467898FC58AAB1D615029441 # 自动加入canal-admin集群 - name: canal.admin.register.auto value: 'true' # 取StatefulSet中的字段,用作在canal-admin中显示的名字 - name: canal.admin.register.name valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name # 加入canal-admin中的哪个集群 - name: canal.admin.register.cluster value: canal-server-beta # 开启instance自动扫描 - name: canal.auto.scan value: 'true'
三、canal在zookeeper中的数据结构
-
使用canal-admin集群模式的部署,canal的消费位点等信息会被记录在zookeeper中
-
修改canal消费位点数据时,应该先停止对应的instance
-
使用zookeeper自带的zkCli.sh工具,操作zk的数据
-
canal默认在zookeeper中存储的数据位置为:/otter/canal
canal在zk中的具体数据结构如下
# canal的根目录 /otter/canal #整个canal server的集群列表(服务端节点信息) /otter/canal/cluster # destination的根目录(instance列表) /otter/canal/destinations # 针对某个instance的服务端节点列表 /otter/canal/destinations/{instance}/cluster # 某个instance正在运行的节点信息 /otter/canal/destinations/{instance}/running # 客户端信息目录 /otter/canal/destinations/{instance}/1001 # 客户端binlog同步信息(包含消费位点) /otter/canal/destinations/{instance}/1001/cursor # 客户端拦截器配置信息 /otter/canal/destinations/{instance}/1001/filter
本文作者:大胡萝卜没有须
本文链接:https://www.cnblogs.com/c-moon/p/16789870.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步