flink_book/Flink_SQL/双流Join底层原理.md

155 lines
4.4 KiB
Markdown
Raw Normal View History

<a title="Hits" target="_blank" href="https://github.com/zeekling/hits"><img src="https://hits.b3log.org/zeekling/flink_book.svg"></a></p>
# 底层原理简介
![pic](./flinksql_0001.png)
- LState:存储左边数据流中的数据。
- RState存储右边数据流中的数据。
- 当左边数据流数据到达的时候会保存到LState并且到RState中进行Join。将Join生成的结果数据发送到下游。
- 右边数据流中数据到达的时候会保存到RState当中并且到LState中进行Join然后将Join之嚄胡的结果数据发送到下游。
为了保障左右两边流中需要Join的数据出现在相同节点Flink SQL会利用Join中的on的关联条件进行分区把相同关联条件
的数据分发到同一个分区里面。
# 普通双流Join
现有订单表A和支付表B进行关联得到汇总表C。订单表和支付表初始数据如下
表A订单表数据
| order_id | timestamp|
|---|--|
| 1001 | 2023-02-04 10:00:00 |
| 1002 | 2023-01-04 10:01:02 |
表B支付表数据
| order_id | pay_money |
|---|---|
| order_id | pay_money |
| 1001 | 80 |
| 1002 | 100 |
## inner join
当A表中每一条数据到达时都会和B表中的数据进行关联
- 当能够关联到数据时,将结果输出到结果表里面;
- 当不能关联到数据时,不会将结果输出到结果表里面;
所以上述A表和B表的Join结果为
| order_id | timestamp | pay_money |
|--- |--- |--- |
| 1002 | 2023-01-04 10:01:02 | 100 |
当表B中1001新数据到达时新数据如下所示:
| order_id | pay_money |
|---|---|
| order_id | pay_money |
| 1001 | 80 |
此时结果表的数据为:
| order_id | timestamp | pay_money |
|--- |--- |--- |
| 1002 | 2023-01-04 10:01:02 | 100 |
| 1001 | 2023-02-04 10:00:00 | 80 |
***注意***
Inner Join 不会产生回撤流。
## left join
当A表数据到达时会主动和B表中数据进行关联查询没有关联到数据。也会输出结果缺失的字段使用null进行补全。
B表中的数据1002到达之后且A表中的数据1001和1002已经到达关联之后表C的数据如下:
| order_id | timestamp | pay_money |
|--- |--- |--- |
| 1001 | 2023-02-04 10:00:00 | null |
| 1002 | 2023-01-04 10:01:02 | 100 |
当B表中数据1001到达之后也会主动和表A中的数据进行关联如果表中的数据已经输出过结果了且缺失字段为null此时
会产生一个回撤流,将之前输出的数据会撤掉-D在重新输出完整的数据+I。
| order_id | timestamp | pay_money | / |
|--- |--- |--- |---|
| 1001 | 2023-02-04 10:00:00 | null | +I|
| 1002 | 2023-01-04 10:01:02 | 100 | +I |
| 1001 | 2023-02-04 10:00:00 | null | -D |
| 1001 | 2023-02-04 10:00:00 | 80 | +I |
***注意***
left Join会产生回撤流。
## Right Join
当表B中1001到达时A表中的数据没有到达则还是会输出数据缺失字段使用null代替。当表B中数据1002到达时A表中的
数据1002已经到达此时可以关联到数据关联结果如下
| order_id | timestamp | pay_money |
|--- |--- |--- |
| 1001 | null | null |
| 1002 | 2023-01-04 10:01:02 | 100 |
当表A中数据1001到达时会主动到B表中进行关联此时结果中已经输出过关于1001的数据此时会产生一个回撤流。
| order_id | timestamp | pay_money | / |
|--- |--- |--- | ---|
| 1001 | null | null | +I|
| 1002 | 2023-01-04 10:01:02 | 100 | +I |
| 1001 | null | null | -D |
| 1001 | 2023-02-04 10:00:00 | 80 | +I |
***注意***
Right Join会产生回撤流。
## Full Join
当表B中数据1001先到达时会主动到A表中进行关联查询关联不到数据还是会输出结果。
当表A中数据到达时会主动和B表中的数据进行关联查询此时B表中只有1001的数据灌篮不到数据还是会输出结果。
所以此时关联结果如下:
| order_id | timestamp | pay_money |
|--- |--- |--- |
| 1001 | null | null |
| 1002 | 2023-01-04 10:01:02 | null |
当表A中的1001到达时会和B表进行关联查询当表B的1002到达时会和表A进行关联查询此时结果如下
| order_id | timestamp | pay_money | / |
|--- |--- |--- | ---|
| 1001 | null | null | +I |
| 1002 | 2023-01-04 10:01:02 | null | +I |
| 1001 | null | null | -D |
| 1001 | 2023-02-04 10:00:00 | 80 | +I |
| 1002 | 2023-01-04 10:01:02 | null | -D |
| 1002 | 2023-01-04 10:01:02 | 100 | +I |
***注意***
Full Join 会产生回撤流。
# Interval Join
# 维表Join