a.
2. 删除对应服务,重建mysql
sc delete MySQL80
c.
d.
e. 停止mysql服务(点击停止后会反馈你未安装),新建一个mysql的my.ini文件
f. 由于初始的目的是为了开启binlog,所有就单纯的增加了一些binlog文件
[mysqld]
#设置日志三种格式:STATEMENT、ROW、MIXED 。
binlog_format = mixed
#设置日志路径,注意路经需要mysql用户有权限写,这里可以写绝对路径,也可以直接写mysql-bin(后者默认就是在/var/lib/mysql目录下)
log-bin = mysql-bin
#设置binlog清理时间
expire_logs_days = 7
#binlog每个日志文件大小
max_binlog_size = 100m
#binlog缓存大小
binlog_cache_size = 4m
#最大binlog缓存大小
max_binlog_cache_size = 512m
#配置serverid
server-id=1
后续命令如下,统一代码块里面构建
g.
# data文件重新生成 需等待
mysqld --initialize-insecure --user=mysql
# 重新构建MySQL服务
mysqld --install "MySql80" --defaults-file="C:\\Program Files\\MySQL\\MySQL Server 8.0\\my.ini"
# 服务里面右击启动即可如代码块结束图1 也可使用命令方法,如
net start MySql80
3. mysql服务重新构建
h.
修改mysql登录密码 mysql -u root -p
初次登录无序密码,回车直接登录
i. 修改登录密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '12345678';
4. binlog是否开启验证
双流Join简单描述
写在前面
Flink CDC只是单纯的使用一下哈,非原理性讲解哈,原理性的话,可以看一下雪尽老师的解释哈,个人觉得这篇应该是最好的系统化学习资料了Flink CDC 2.x设计原理 比较难理解的可能如何拉取数据,本质是select binlog语句拉取。
关于双流join更深层次的知识,有需要的同学可以看一下这个文章
这篇文章的博主从数据质量(发的数据应该是什么样子的)和数据时效性(关联到了后还是我想要的数据嘛)来讨论的,那这篇文章从另一个角度出发,各类join产生的各种结果,也会简单的描述一些适用的场景。没有最合适的join,只有适用于场景的join。
先从简单的双流join来说,inner join ,right join,left join
代码构建
双流join 纯SQL版
import org.apache.flink.configuration.Configuration;
import org.apache.flink.configuration.RestOptions;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.TableEnvironment;
import static org.apache.flink.table.api.Expressions.$;
/\*\*
\* @author 划水小苏
\* @date 2024/02/16 19:30
\* @target:
\*\*/
public class TestDemo02 {
public static void main(String[] args) {
//1.使用本地模式
Configuration conf = new Configuration();
//设置WebUI绑定的本地端口
conf.setString(RestOptions.BIND\_PORT,"8081");
// https://nightlies.apache.org/flink/flink-docs-release-1.13/zh/docs/dev/table/config/
// 并行度设置
conf.setString("table.exec.resource.default-parallelism","1");
// pipeline.operator-chaining 拆分算子
conf.setString("pipeline.operator-chaining","false");
EnvironmentSettings settings = EnvironmentSettings
.newInstance()
.inStreamingMode()
.withConfiguration(conf)
.build();
TableEnvironment tabelEnv = TableEnvironment.create(settings);
tabelEnv.executeSql("CREATE TABLE test01 (\n" +
" `a1` VARCHAR(25) ,\n" +
" `a2` VARCHAR(25) NOT NULL,\n" +
" PRIMARY KEY (a2) NOT ENFORCED \n" +
") WITH (\n" +
"'connector' = 'mysql-cdc', \n"+
"'database-name' = 'sk\_db\_test01', \n"+
"'hostname' = '127.0.0.1', \n"+
"'password' = '12345678', \n"+
"'port' = '3306', \n"+
"'table-name' = 'test01', \n"+
"'username' = 'root', \n"+
"'scan.startup.mode' = 'latest-offset' \n"+
")");
tabelEnv.executeSql("CREATE TABLE test02 (\n" +
" `b1` VARCHAR(25) ,\n" +
" `b2` VARCHAR(25) NOT NULL,\n" +
" PRIMARY KEY (b2) NOT ENFORCED \n" +
") WITH (\n" +
"'connector' = 'mysql-cdc', \n"+
"'database-name' = 'sk\_db\_test01', \n"+
"'hostname' = '127.0.0.1', \n"+
"'password' = '12345678', \n"+
"'port' = '3306', \n"+
"'table-name' = 'test02', \n"+
"'username' = 'root', \n"+
"'scan.startup.mode' = 'latest-offset' \n"+
")");
tabelEnv.executeSql("CREATE TABLE PrintSink (\n" +
" `c1` VARCHAR(25), \n" +
" `c2` VARCHAR(25), \n" +
" `c3` VARCHAR(25) \n" +
") WITH (\n" +
" 'connector' = 'print' \n" +
")");
tabelEnv.executeSql("INSERT INTO PrintSink\n" +
"SELECT a.\*,b.b1 FROM test01 AS a\n" +
"RIGHT join test02 AS b\n" +
"ON a.a2 = b.b2\n" +
";");
}
}
pom 文件 (新增mysql connector依赖)
完整版看Flink table api那个pom哈,新增即可
<!-- mysql cdc 相关依赖-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-base</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.ververica/flink-connector-mysql-cdc -->
<dependency>
<groupId>com.ververica</groupId>
<artifactId>flink-connector-mysql-cdc</artifactId>
<version>2.3.0</version>
<!-- <scope>provided</scope>-->
</dependency>
mysql侧sql
-- 建表
DROP TABLE IF EXISTS `test01` ;
CREATE TABLE test01 (
`a1` VARCHAR(25),
`a2` VARCHAR(25) NOT NULL,
PRIMARY KEY (a2)
);
DROP TABLE IF EXISTS `test02` ;
CREATE TABLE test02 (
`b1` VARCHAR(25),
`b2` VARCHAR(25) NOT NULL,
PRIMARY KEY (b2)
);
-- 数据插入与更新
INSERT INTO `test01` values("左1","sk01");
SELECT \* FROM `test01` ;
UPDATE `test01` set `a1` = "左2" where `a2` = "sk01";
INSERT INTO `test01` values("左1","sk02");
INSERT INTO `test02` values("右1","sk01");
SELECT \* FROM `test02` ;
UPDATE `test02` set `b1` = "右2" where `b2` = "sk01";
right join
简单概述
首先进行一个简单的排列组合一下,左流数据有或无,右流数据有或无,展开即为
(有,无) | (有,有) | (无,无) | (无,有)
第三种不在简述里面存在,那就丢掉这种可能,只讨论剩下的三种情况
-- 右流来了数据,左流没这种数据怎么办?
+I[null,b]
-- 那后面左流来了这条数据呢?
-D[null,b]
+I[a,b]
-- 存在一个疑问点就是这个右流的数据是什么情况,为什么还有-D这种?
未关联到数据,不会立即丢弃掉,而是存在记忆里面,但是记忆存多久呢?State的ttl就是记忆时间
在记忆时间里面,左流数据到达后,会重新下发数据,也就常说的回撤。
关于-D操作是因为在实时计算里面,这种动态表概念,详情可以看官网详解哈,这里通过白话来理解哈,
在整体的流计算数据里面,由于存在一些记忆,
让flink理解到之前的数据是脏数据,需要使用-D来把之前的+I数据抵消掉,从而下发一条新的数据
但,至于sink端如何处理这些数据,是依次+I还是进行+U是由sink端处理的,flink侧只负责下发这种逻辑
-- 右流来了数据,关联到左流的数据会下发什么?
+I[a,b]
-- 如果左流不断更新,数据会下发什么?
+I[a1,b]
-D[a1,b]
+I[a2,b]
在记忆时间里面,会一直维护条数据,会出现不断更新
-- 如果左流来了数据,但是右流没数据关联,数据下发会是什么样子呢
示例:
基于阿里云实现结果的截图,上面的demo控制台也是可以一样输出的,强烈推荐阿里云Flink产品,我觉得很nice,最起码写sql很得劲,我是一个快乐的sql boy。
1、新增右流数据
INSERT INTO
test02
values(“右1”,“sk01”);
2、新增左流数据
INSERT INTO
test02
values(“右1”,“sk01”);
3、更新左流数据
UPDATE
test01
seta1
= “左2” wherea2
= “sk01”;
4、更新右流数据
UPDATE
test02
setb1
= “右2” whereb2
= “sk01”;
left join
简单概述
基于上续Java代码只修改right 为 left 即可
简单概述现象
左不等右等 左2右4
示例
1、先来左流数据 ( INSERT INTO test01
values(“左1”,“sk01”); )
+I [左1, sk01, null]
2、先来右流数据( INSERT INTO test02
values(“右1”,“sk01”); )
无数据输出 (相当于首次执行哈,要和上面的顺序执行做区分)
3、join之后的情况
+I [左1, sk01, 右1]
4、更新左流数据 ( UPDATE test01
set a1
= “左2” where a2
= “sk01”; )
-D [左1, sk01, 右1]
+I [左2, sk01, 右1]