TiCDC 应用场景解析
作者: 代晓磊 _Mars 原文来源:https://tidb.net/blog/2fa9cf6a
【是否原创】是
【首发渠道】微信公众号:晓磊聊 DB
【首发渠道链接】https://mp.weixin.qq.com/s/Cq8LMLAvlyi6wexE5v2-Lw
【正文】
TiCDC 应用场景解析
TiCDC 是一款通过拉取 TiKV 变更日志实现的 TiDB 增量数据同步工具,具有将数据还原到与上游任意 TSO 一致状态的能力,同时提供开放数据协议 (TiCDC Open Protocol),支持其他系统订阅数据变更。
TiCDC 业务使用场景描述
(1)增量数据抽取需求
数仓 ETL 每天凌晨基于 table(create_date or update_date) 增量或者全量的数据抽取:
目前离线报表业务为了凌晨产出报表,数仓团队凌晨需要从我们核心的物料 TiDB 集群 (70+ 节点) 中抽取维度基本信息数据,这些多张维度的基本信息表都是大表 (200 亿 / 表,5T+/ 表),每天凌晨的数仓抽取任务会对全实例 (20T) 做全量抽取。导致凌晨 CPU 跑满 / 内存 oom/ 网卡跑满等各种负载问题,并且平均 1~2 个月出现数仓抽取失败,从而影响离线报表的定时产出,导致广告主不能及时看到昨天广告的消费情况,最严重的后果就是由此产生的广告停止投放,影响广告收入;另外凌晨除了数仓还有其他的计算任务存在,这种全量的抽取也会对其他正常凌晨任务的执行造成影响;凌晨的各种报警,我们 DBA 来说也苦不堪言。 所以使用 TiCDC 写入 kafka 这种增量数仓需求是我们紧要的需求。
(2)同城双集群热备
目前我们的核心 tidb 都放在同一个机房。如果机房孤岛或者其他灾害问题。业务无法及时恢复。TiDB 集群的同城双中心需求是重要的需求。
我们想利用 TiCDC 做同城双集群数据同步,一是可以将部分不需要太实时的读取流量切到备用集群,来缓解主 TIDB 集群的读取压力。二是一旦核心机房有问题,备用集群就可以立即接管服务。
(3)流处理需求
之前业务就是用 maxwell/canal 等工具将 MySQL 的变更 binlog 解析处理后写入 kafka, 供实时 JOB 消费或者映射成 flink table 作为 flink sql 的维表 join。现在随着 MySQL 迁移到 TiDB,我们也需要 TiCDC 高效 / 稳定的支持该需求,否则业务无法完全的迁移到 TiDB(只能长期保持 MySQL->DM->TiDB)这种架构,无法实现真正的 TiDB 替代 MySQL,另外就是 DM 还需要处理上游分库分表 DDL 的兼容和同步中断的处理,所以 TiCDC 在流处理中扮演重要的角色。
ticdc 架构
从上图的架构来看可以细分 4 个大模块分别为:TiKV cluster、PD、Ticdc Cluseter、Sink 下游组件。
下面来详细介绍下各个组件:
1、最核心的 TiCDC cluster
可以看出集群里有多个 ticdc 进程,专业名词可以叫做 capture,capture 有几大作用:
puller 负责拉取 TiKV 的 change log,对拉取的 change log 排序(基于单表维度)。
基于 processor 这个内部逻辑线程,每个 processot 负责同步一张或者多张表的数据变更,一个 capture 节点可以运行多个 processor 线程,向下游输出。
高可用:多个 capture 组成一个 ticdc 集群,并且 capture 有不同的角色,分为 owner/ 非 owner 角色,owner 节点负责集群的调度,并且所有的 capture 都会注册到 PD,一旦 ticdc onwer 异常,会触发选举新 owner,并且 owner 会在其他 processor 节点异常时,将 processor 管理的同步任务调度到其他 capture 节点。
可以使用 tiup 来查看各个 capture 进程的状态
tiup ctl cdc capture list --pd=http://xxxxx:2379
同步任务 changefeed。一个同步任务可以同步一个 tidb 实例,也可以设定过滤规则,只同步某些 DB or Table。
创建同步任务:
tiup ctl:v4.0.14 cdc changefeed create --pd=http://pd-ip:2379 --sink-uri="mysql://User:password@vip:4000/" --changefeed-id="sync-name" --start-ts=0 --config=./ticdc.yaml
查看同步任务:
tiup ctl:v4.0.14 cdc changefeed list --pd=http://pd-ip:2379
详情可以下图的抽取逻辑
2、TiKV Cluster
用户写入的键值对会先写入磁盘上的 WAL (Write Ahead Log),又可以理解为 KV 变更日志(KV Change Logs)。一旦同步任务创建,TiCDC 集群就会拉取这些 row changed events。
3、PD cluster
TIDB 集群的大脑,除了分配全局 TSO、管理集群元数据和调度外,在 TiCDC 层面:负责存储 changefeed 的配置和状态、capture 节点元信息、owner 选举信息以及 processor 的同步状态等。
4、Sink 组件
TiCDC 的下游
MySQL 协议兼容的数据库(MySQL、TiDB)
Kafka/Pulsar,然后 Flink 等第三方流处理组件订阅数据变更来使用。
增量备份,比如存放在 S3 这种分布式文件存储系统上。
早期版本的问题
之前存在的问题(大部分已经修复):
TiCDC 正常同步进行中,上游 TiDB 突增大写入量的情况下经常 OOM,稳定性不足
当 TiCDC 因为某些原因同步中断时,并且中断期间上游 TiDB 写入了大量数据,重新启动同步导致 TiCDC 出现 OOM 问题
ticdc 的下游是 tidb 的情况下,上游 tidb 集群出现大量对同一行记录进行更新时,下游 tidb 出现写写冲突导致 ticdc 同步停止(官方已经对这个问题有解决方案)
sort-dir 路径问题:之前版本的 sort 目录是默认跟 deploy 放同一目录,如果按照默认 deploy 是 /home/tidb/deploy 的话,sort 目录就是默认使用系统盘 (一般空间较小),当遇到突增写入或者又较大多的 change log 需要同步时,可能会把系统盘写满,另外 ticdc 同步也会因为 sort 目录写满而中断。目前 sort 目录已经修改成 TiCDC 的 data 目录
早期版本的 TiCDC 在拉取 change log 时并发度没有上限,导致 TiKV 节点的网卡、硬盘 IO、CPU 等飙升,影响了集群正常业务的运行。
在执行大的 DDL 操作时 (比如对亿级别的表添加索引),TiCDC 同步会等待 DDL 执行完毕后才继续同步 change log。(4.0.14+ 版本解决)
最佳实践:
强烈建议使用 4.0.14⁄5.1.1 最新版本的 ticdc,高版本修复了不少 bug。
及时观察 ticdc 相关的监控。ticdc 有专门的监控 dashboard,从里面可以看出抽取 changelog 的速度,写下游 Sink 的情况,对 tikv 集群的影响等等,官网有对各个监控项的详细说明,如下。
https://docs.pingcap.com/zh/tidb/stable/monitor-ticdc
如果数据写入 kafka,除了提供默认的开放数据协议 (TiCDC Open Protocol) 外,还有多种 kafka 消息协议可选择比如 canal、canal-json、avro、maxwell 等方式,兼容之前 MySQL 的 cdc,可以无缝迁移。
在上游 TiDB 写入量比较大时,拆分多个 changefeed 进行同步,可以从 STATEMENTS_SUMMARY_HISTORY 系统表来看 table 写入分布,按照写入表拆分成多个 changefeed,SQL 如下:
select digest,DIGEST_TEXT,TABLE_NAMES,sum(EXEC_COUNT),min(SUMMARY_BEGIN_TIME),max(SUMMARY_END_TIME) from STATEMENTS_SUMMARY_HISTORY where stmt_type='insert' and schema_name='ad_monitor' group by digest order by sum(exec_count) desc limit 20;
PS:dashboard->SQL 语句分析,过滤 insert 找出 table 写入情况。kafka 的 partition-num 参数要设定为 1,因为基于表的同步虽然是 sort 后执行,如果输出到多个 kafka partition,kafka 保证每个 partition 是有序的,但是消费者从多个 kafka partition 拿数据向下游应用时可能事务顺序会被打乱,导致数据不一致的情况产生。
为了防止因为 sort 信息过多 导致 ticdc 节点的 gorouting 异常,需要 ticdc 配置 per-table-memory-quota 到 6M 来缓解稳定,注意这个参数的 values 是数值类型,按照下面的方式修改:
TiKV 网络限速,避免 TiCDC 的拉取对 tikv 集群造成影响,比如你的 tikv 都是千兆网卡,正常的集群就已经使用到 30~50M,可以将 ticdc 的拉取限速我 20M(因为担心 ticdc 的拉取把千兆网卡跑满影响集群正常业务),修改方式如下:
TiCDC 的 gc-ttl:Ticdc 默认可以 hold 24 小时的 changlog,超过 24 自动释放 gc。所以中断 24 小时以上的同步任务重启会报错,启动 TiCDC server 时可以通过 gc-ttl 指定 GC safepoint 的 TTL。
虽然 gc-ttl 可以为中断的同步 hold 24 小时的 KV 数据变更,但是从另外一个方面来看,累积多过的 MVCC 版本,肯定会对查询造成影响,需要根据业务评估影响,如果需要删除同步任务可以用下面的命令:
使用 ticdc 增量拉取时,提前调整 gc lifetime。比如要用 cdc 做跨机房数据同步,比如:用 br 恢复今天凌晨备份,记得提前调整 gc lifetime 时间,避免 BR 恢复完数据创建 changefeed 的时候发现 change log 已经被 gc 了。
TiCDC 对大事务(大小超过 5 GB)提供部分支持,所以对于上游 TIDB 集群最大支持 10G 的事务来说,大事务可能触发 TiCDC 的 oom。
出现同步中断时,可以先使用以下命令查看同步报错的原因,另外就是从 TiCDC 的日志里面查看报错的具体详情。
总结:
其实我想说的是:目前 ticdc 在大部分场景下是可用的。
这里要提到一件事情,就是关于 ticdc 稳定性和可用性立项: TiCDC 在早期版本确定是出现过各种 OOM 以及对 Tikv 集群负载影响等问题,从今年年初 360 就提出了本文开头的 3 个应用场景,并且跟 PingCAP 的 TiCDC 研发团队一起合作立项,中间在线和线下沟通了 10 多次,基于 360 的高写入环境来验证 TiCDC 的稳定和可用性,直到现在 TiCDC 终于可以在各个场景下稳定运行,希望有类似需求的可以尝试使用起来,有问题可以及时跟官方沟通反馈,目的就是让 TiCDC 这个同步工具更加高效和稳定运行。
最后:欢迎大家关注我的微信公众号
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/346b0bf1c6e8214f0f1d1f95f】。文章转载请联系作者。
评论