写在前面

  好久没更新Blog了,从CRUD Boy转型大数据开发,拉宽了不少的知识面,从今年年初开始筹备、组建、招兵买马,到现在稳定开搞中,期间踏过无数的火坑,也许除了这篇还很写上三四篇。

  进入主题,通常企业为了实现数据统计、数据分析、数据挖掘、解决信息孤岛等全局数据的系统化运作管理 ,为BI、经营分析、决策支持系统等深度开发应用奠定基础,挖掘数据价值 ,企业会开始着手建立数据仓库,数据中台。而这些数据来源则来自于企业的各个业务系统的数据或爬取外部的数据,从业务系统数据到数据仓库的过程就是一个ETL(Extract-Transform-Load)行为,包括了采集、清洗、数据转换等主要过程,通常异构数据抽取转换使用Sqoop、DataX等,日志采集Flume、Logstash、Filebeat等。

  数据抽取分为全量抽取和增量抽取,全量抽取类似于数据迁移或数据复制,全量抽取很好理解;增量抽取在全量的基础上做增量,只监听、捕捉动态变化的数据。如何捕捉数据的变化是增量抽取的关键,一是准确性,必须保证准确的捕捉到数据的动态变化,二是性能,不能对业务系统造成太大的压力。

增量抽取方式

  通常增量抽取有几种方式,各有优缺点。

1. 触发器

  在源数据库上的目标表创建触发器,监听增、删、改操作,捕捉到数据的变更写入临时表。

优点:操作简单、规则清晰,对源表不影响;

缺点:对源数据库有侵入,对业务系统有一定的影响;

2. 全表比对

  在ETL过程中,抽取方建立临时表待全量抽取存储,然后在进行比对数据。

优点:对源数据库、源表都无需改动,完全交付ETL过程处理,统一管理;

缺点:ETL效率低、设计复杂,数据量越大,速度越慢,时效性不确定;

3. 全表删除后再插入

  在抽取数据之前,先将表中数据清空,然后全量抽取。

优点:ETL 操作简单,速度快。

缺点:全量抽取一般采取T+1的形式,抽取数据量大的表容易对数据库造成压力;

4. 时间戳

  时间戳的方式即在源表上增加时间戳列,对发生变更的表进行更新,然后根据时间戳进行提取。

优点:操作简单,ELT逻辑清晰,性能比较好;

缺点:对业务系统有侵入,数据库表也需要额外增加字段。对于老的业务系统可能不容易做变更。

5. CDC方式

  变更数据捕获Change Data Capture(简称CDC),SQLServer为实时更新数据同步提供了CDC机制,类似于Mysql的binlog,将数据更新操作维护到一张CDC表中。开启CDC的源表在插入INSERT、更新UPDATE和删除DELETE活动时会插入数据到日志表中。cdc通过捕获进程将变更数据捕获到变更表中,通过cdc提供的查询函数,可以捕获这部分数据。详情可以查看官方介绍:关于变更数据捕获 (SQL Server)

优点:提供易于使用的API 来设置CDC 环境,缩短ETL 的时间,无需修改业务系统表结构。

缺点:受数据库版本的限制,实现过程相对复杂。

CDC增量抽取

先决条件

1. 已搭建好Kafka集群,Zookeeper集群;

2. 源数据库支持CDC,版本采用开发版或企业版。

案例环境:

Ubuntu 20.04

Kafka 2.13-2.7.0

Zookeeper  3.6.2

SQL Server 2012

步骤

  除了数据库开启CDC支持以外,主要还是要将变更的数据通过Kafka Connect传输数据,Debezium是目前官方推荐的连接器,它支持绝大多数主流数据库:MySQL、PostgreSQL、SQL Server、Oracle等等,详情查看Connectors。

1. 数据库步骤

开启数据库CDC支持

  在源数据库执行以下命令:

EXEC sys.sp_cdc_enable_db GO

  附上关闭语句:

exec sys.sp_cdc_disable_db

查询是否启用

select * from sys.databases where is_cdc_enabled = 1

创建测试数据表:(已有表则跳过此步骤)

create  table T_LioCDC
(
ID int identity(1,1) primary key ,
Name nvarchar(16),
Sex bit,
CreateTime datetime,
UpdateTime datetime
);

对源表开启CDC支持:

exec sp_cdc_enable_table
@source_schema='dbo',
@source_name='T_LioCDC',
@role_name=null,
@supports_net_changes = 1;

确认是否有权限访问CDC Table:

EXEC sys.sp_cdc_help_change_data_capture

确认SQL Server Agent已开启:

EXEC master.dbo.xp_servicecontrol N'QUERYSTATE',N'SQLSERVERAGENT'

  以上则完成对数据库的CDC操作。

2. Kafka步骤

  Kafka Connect的工作模式分为两种,分别是standalone模式和distributed模式。standalone用于单机测试,本文用distributed模式,用于生产环境。(Kafka必须先运行启动,再进行以下步骤进行配置。)

下载Sql Server Connector

  下载连接器后,创建一个文件夹来存放,解压到该目录下即可,例子路径: /usr/soft/kafka/kafka_2.13_2.7.0/plugins (记住这个路径,配置中要用到)

下载地址:debezium-connector-sqlserver-1.5.0.Final-plugin.tar.gz

编辑connect-distributed.properties配置

  修改Kafka connect配置文件,$KAFKA_HOME/config/connect-distributed.properties,变更内容如下:

//kafka集群ip+port
bootstrap.servers=172.192.10.210:9092,172.192.10.211:9092,172.192.10.212:9092 key.converter.schemas.enable=false
value.converter.schemas.enable=false offset.storage.topic=connect-offsets
offset.storage.replication.factor=1
offset.storage.partitions=3
offset.storage.cleanup.policy=compact config.storage.topic=connect-configs
config.storage.replication.factor=1 status.storage.topic=connect-status
status.storage.replication.factor=1
status.storage.partitions=3
//刚刚下载连接器解压的路径
plugin.path=/usr/soft/kafka/kafka_2.13_2.7.0/plugins

看到配置中有三个Topic,分别是

config.storage.topic:用以保存connector和task的配置信息,需要注意的是这个主题的分区数只能是1,而且是有多副本的。
offset.storage.topic:用以保存offset信息。
status.storage.topic:用以保存connetor的状态信息。

这些Topic可以不用创建,启动后会默认创建。

启动Kafka集群

  保存配置之后,将connect-distributed.properties分发到集群中,然后启动:

bin/connect-distributed.sh config/connect-distributed.properties

检查是否启动

  connector支持REST API的方式进行管理,所以用Post man或者Fiddler可以调用相关接口进行管理。检查是否启动:

不用奇怪,上面配置集群的IP是172段,这里的192.168.1.177仍是我的集群中的一个服务器,因为服务器都使用了双网卡。因为还没有连接器相关配置,所以接口返回是一个空数组,接下来将新增一个连接器。

编写sqlserver-cdc-source.json

{
"name": "sqlserver-cdc-source",
"config": {
"connector.class" : "io.debezium.connector.sqlserver.SqlServerConnector",
"database.server.name" : "JnServer",
"database.hostname" : "172.192.20.2", --目标数据库的ip
"database.port" : "1433", --目标数据库的端口
"database.user" : "sa", --目标数据库的账号
"database.password" : "123456", --密码
"database.dbname" : "Dis", --目标数据库的数据库名称
"table.whitelist": "dbo.T_LioCDC", --监听表名
"schemas.enable" : "false",
"mode":"incrementing", --增量模式
"incrementing.column.name": "ID", --增量列名
"database.history.kafka.bootstrap.servers" : "172.192.10.210:9092,172.192.10.211:9092,172.192.10.212", --kafka集群
"database.history.kafka.topic": "TopicTLioCDC", --kafka topic内部使用,不是由消费者使用
"value.converter.schemas.enable":"false",
"value.converter":"org.apache.kafka.connect.json.JsonConverter"
}
}
//源文地址: https://www.cnblogs.com/EminemJK/p/14688907.html

还有其他额外的配置,可以参考官方文档。然后执行

继续执行检查,就发现连接器已经成功配置了:

其他API

GET /connectors – 返回所有正在运行的connector名。
POST /connectors – 新建一个connector; 请求体必须是json格式并且需要包含name字段和config字段,name是connector的名字,config是json格式,必须包含你的connector的配置信息。
GET /connectors/{name} – 获取指定connetor的信息。
GET /connectors/{name}/config – 获取指定connector的配置信息。
PUT /connectors/{name}/config – 更新指定connector的配置信息。
GET /connectors/{name}/status – 获取指定connector的状态,包括它是否在运行、停止、或者失败,如果发生错误,还会列出错误的具体信息。
GET /connectors/{name}/tasks – 获取指定connector正在运行的task。
GET /connectors/{name}/tasks/{taskid}/status – 获取指定connector的task的状态信息。
PUT /connectors/{name}/pause – 暂停connector和它的task,停止数据处理知道它被恢复。
PUT /connectors/{name}/resume – 恢复一个被暂停的connector。
POST /connectors/{name}/restart – 重启一个connector,尤其是在一个connector运行失败的情况下比较常用
POST /connectors/{name}/tasks/{taskId}/restart – 重启一个task,一般是因为它运行失败才这样做。
DELETE /connectors/{name} – 删除一个connector,停止它的所有task并删除配置。

//源文地址: https://www.cnblogs.com/EminemJK/p/14688907.html

查看Topic

/usr/soft/kafka/kafka_2.13_2.7.0# bin/kafka-topics.sh --list --zookeeper localhost:2000

Topic JnServer.dbo.T_LioCDC 则是供我们消费的主题,启动一个消费者进行监听测试:

bin/kafka-console-consumer.sh --bootstrap-server 172.192.10.210:9092  --consumer-property group.id=group1 --consumer-property client.id=consumer-1  --topic JnServer.dbo.T_LioCDC

然后再源表进行一些列增删改操作,

--测试代码
insert into T_LioCDC(name, sex, createtime,UpdateTime) values ('A',1,getdate(),getdate())
insert into T_LioCDC(name, sex, createtime,UpdateTime) values ('B',0,getdate(),getdate())
insert into T_LioCDC(name, sex, createtime,UpdateTime) values ('C',1,getdate(),getdate())
insert into T_LioCDC(name, sex, createtime,UpdateTime) values ('D',0,getdate(),getdate())
insert into T_LioCDC(name, sex, createtime,UpdateTime) values ('E',1,getdate(),getdate())
insert into T_LioCDC(name, sex, createtime,UpdateTime) values ('F',1,getdate(),getdate())
insert into T_LioCDC(name, sex, createtime,UpdateTime) values ('G',0,getdate(),getdate()) update T_LioCDC
set Name='Lio.Huang',UpdateTime=getdate()
where ID=7

已经成功捕捉到数据的变更,对比几个操作Json,依次是insert、update、delete:

最后

  下班!

SQL Server CDC配合Kafka Connect监听数据变化的更多相关文章

  1. vue.js之过滤器,自定义指令,自定义键盘信息以及监听数据变化

    一.监听数据变化 1.监听数据变化有两种,深度和浅度,形式如下: vm.$watch(name,fnCb); //浅度 vm.$watch(name,fnCb,{deep:true}); //深度监视 ...

  2. $scope.$watch()——监听数据变化

    $scope.$watch(watchFn, watchAction, [deepWatch]):监听数据变化,三个参数 --watchFn:监听的对象,一个带有Angular 表达式或者函数的字符串 ...

  3. vue教程2-08 自定义键盘信息、监听数据变化vm.$watch

    vue教程2-08 自定义键盘信息 @keydown.up @keydown.enter @keydown.a/b/c.... 自定义键盘信息: Vue.directive('on').keyCode ...

  4. 关于微信小程序使用watch监听数据变化的方法

    众所周知,Vue中,可以使用监听属性 watch来观察和响应 Vue 实例上的数据变化,那么小程序能不能实现这一点呢? 监听器的原理,是将data中需监听的数据写在watch对象中,并给其提供一个方法 ...

  5. mvc 缓存 sqlCacheDependency 监听数据变化

    mvc 缓存   对于MVC有Control缓存和Action缓存. 一.Control缓存 Control缓存即是把缓存应用到整个Control上,该Control下的所有Action都会被缓存起来 ...

  6. $watch监听数据变化和run方法

    angular中$watch方法可以监听数据的变化. $scope.$watch('phone',function(){ $scope.phone.fre = $scope.phone.num> ...

  7. sql server 警报管理,实时监听数据库动向,运筹帷幄之中

    工作这么多年了,无论是身边的同学还是同事,发现只要搞程序员的都有一个通病---懒.懒到谁都不愿意加班,尤其是"义务"加班.即使大家都不愿意加班,但是很多时候项目赶着上线或者上线之后 ...

  8. ZooKeeper 笔记(2) 监听数据变化

    ZK中的每个节点都可以存储一些轻量级的数据,这些数据的变化会同步到集群中的其它机器.在应用中程序员可以添加watcher来监听这些数据的变化,watcher只会触发一次,所以触发过后想要继续监听,必须 ...

  9. Vue中使用watch来监听数据变化

    写法一: methods:{ //监听isMD upProp(){ if(this.isMD){//如果isMD等于true 就把storeManagerName赋值给isStoreManagerNa ...

随机推荐

  1. [C语言学习笔记五]复合语句和操作符的区分

    复合语句的概念和用法 在部分时候,语句必须要与其他语句相结合才能实现应有的功能.放在花括号 {} 里的代码叫做复合语句. 例如: int a,b; if (a == b) ... ... /* 这一部 ...

  2. 谁手握账本?趣讲 ZK 的内存模型

    本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源.有趣.入门级的 ZooKeeper 教程,面向有编程基础的新手. 本 ...

  3. 腾讯云Centos7.6开放端口及配置腾讯云安全组

    1:防火墙的开启.关闭.状态查询.设置开机自启.开机禁用命令 检查状态(1):firewall-cmd --state 检查状态(2):systemctl status firewalld.servi ...

  4. 使用Reactor完成类似的Flink的操作

    一.背景 Flink在处理流式任务的时候有很大的优势,其中windows等操作符可以很方便的完成聚合任务,但是Flink是一套独立的服务,业务流程中如果想使用需要将数据发到kafka,用Flink处理 ...

  5. Newbe.Claptrap 框架入门,第一步 —— 开发环境准备

    Newbe.Claptrap 框架依托于一些关键性的基础组件和一些可选的辅助组件.本篇我们来介绍一下如何准备一个开发环境. Newbe.Claptrap 是一个用于轻松应对并发问题的分布式开发框架.如 ...

  6. MySQL确认注入点

    目录 WHERE子句后面的注入点 逻辑符号AND.OR other order by union limit table WEB渗透测试流程中,初期工作是进行信息收集,完成信息收集之后,就会进行漏洞测 ...

  7. k8s自定义controller设计与实现

    k8s自定义controller设计与实现 创建CRD 登录可以执行kubectl命令的机器,创建student.yaml apiVersion: apiextensions.k8s.io/v1bet ...

  8. Python3基础-目录

    Python3基础-目录(Tips:长期更新Python3目录) 第一章 初识Python3  1.1 Python3基础-前言  1.2 Python3基础-规范 第二章 Python3内置函数&a ...

  9. C# 应用 - 使用 WebClient 发起 Http 请求

    1. 需要的库类 \Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.dll System.Net.WebCli ...

  10. python的迭代

    迭代 1:并行迭代 程序可以同时迭代两个序列 names["zhangsan","lisi","zhaosi"] age[12,13,14] ...