From e436aad72e004323478590c107621c45243b433b Mon Sep 17 00:00:00 2001 From: xuyang Date: Tue, 28 Oct 2025 13:35:23 +0800 Subject: [PATCH 1/5] [doc] Add docs for delta join support with Flink 2.1 --- website/docs/engine-flink/datastream.mdx | 2 +- website/docs/engine-flink/deltajoins.md | 126 +++++++++++++++++++++++ website/docs/engine-flink/options.md | 2 +- 3 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 website/docs/engine-flink/deltajoins.md diff --git a/website/docs/engine-flink/datastream.mdx b/website/docs/engine-flink/datastream.mdx index 0ef721a9da..c9aaa3798a 100644 --- a/website/docs/engine-flink/datastream.mdx +++ b/website/docs/engine-flink/datastream.mdx @@ -1,6 +1,6 @@ --- title: "DataStream API" -sidebar_position: 6 +sidebar_position: 7 --- # DataStream API diff --git a/website/docs/engine-flink/deltajoins.md b/website/docs/engine-flink/deltajoins.md new file mode 100644 index 0000000000..68232e5791 --- /dev/null +++ b/website/docs/engine-flink/deltajoins.md @@ -0,0 +1,126 @@ +--- +sidebar_label: DeltaJoins +title: Flink Delta Joins +sidebar_position: 6 +--- + +# Delta Join +Begin with Flink 2.1, a new delta join operator was introduced. Compared to traditional streaming join, delta join significantly reduces the required state, effectively alleviating issues associated with large state, such as resource bottlenecks, lengthy checkpoint execution times, and long recovery times during job restarts. + +Starting from Fluss version 0.8, streaming join jobs running on Flink 2.1 or higher will be automatically optimized to delta join in applicable scenarios. + +## Examples + +Here is an example of delta join currently supported in Flink 2.1. + +1. Create two source tables and one sink tables + +```sql title="Flink SQL" +USE CATALOG fluss_catalog; +``` + +```sql title="Flink SQL" +CREATE DATABASE my_db; +``` + +```sql title="Flink SQL" +USE my_db; +``` + +```sql title="Flink SQL" +CREATE TABLE `fluss_catalog`.`my_db`.`left_src` ( + `city_id` INT NOT NULL, + `order_id` INT NOT NULL, + `content` VARCHAR NOT NULL, + PRIMARY KEY (city_id, order_id) NOT ENFORCED +) WITH ( + -- prefix lookup key + 'bucket.key' = 'city_id', + -- in Flink 2.1, delta join only support append-only source + 'table.merge-engine' = 'first_row' + ...) +; +``` + +```sql title="Flink SQL" +CREATE TABLE `fluss_catalog`.`my_db`.`right_src` ( + `city_id` INT NOT NULL, + `city_name` VARCHAR NOT NULL, + PRIMARY KEY (city_id) NOT ENFORCED +) WITH ( + -- in Flink 2.1, delta join only support append-only source + 'table.merge-engine' = 'first_row' + ...) +; +``` + +```sql title="Flink SQL" +CREATE TABLE `fluss_catalog`.`my_db`.`snk` ( + `city_id` INT NOT NULL, + `order_id` INT NOT NULL, + `content` VARCHAR NOT NULL, + `city_name` VARCHAR NOT NULL, + PRIMARY KEY (city_id, order_id) NOT ENFORCED +) WITH (...) +; +``` + +2. Explain DML about streaming join + +```sql title="Flink SQL" +EXPLAIN +INSERT INTO `fluss_catalog`.`my_db`.`snk` +SELECT T1.`city_id`, T1.`order_id`, T1.`content`, T2.`city_name` +FROM `fluss_catalog`.`my_db`.`left_src` T1 +Join `fluss_catalog`.`my_db`.`right_src` T2 +ON T1.`city_id` = T2.`city_id` +; +``` + +If you see the plan that includes DeltaJoin as following, it indicates that the optimization has been effective, and the streaming join has been successfully optimized into a delta join. + +```title="Flink Plan" +== Abstract Syntax Tree == +LogicalSink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_name]) ++- LogicalProject(city_id=[$0], order_id=[$1], content=[$2], city_name=[$4]) + +- LogicalJoin(condition=[=($0, $3)], joinType=[inner]) + :- LogicalTableScan(table=[[fluss_catalog, my_db, left_src]]) + +- LogicalTableScan(table=[[fluss_catalog, my_db, right_src]]) + +== Optimized Physical Plan == +Sink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_name]) ++- Calc(select=[city_id, order_id, content, city_name]) + +- DeltaJoin(joinType=[InnerJoin], where=[=(city_id, city_id0)], select=[city_id, order_id, content, city_id0, city_name]) + :- Exchange(distribution=[hash[city_id]]) + : +- TableSourceScan(table=[[fluss_catalog, my_db, left_src]], fields=[city_id, order_id, content]) + +- Exchange(distribution=[hash[city_id]]) + +- TableSourceScan(table=[[fluss_catalog, my_db, right_src]], fields=[city_id, city_name]) + +== Optimized Execution Plan == +Sink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_name]) ++- Calc(select=[city_id, order_id, content, city_name]) + +- DeltaJoin(joinType=[InnerJoin], where=[(city_id = city_id0)], select=[city_id, order_id, content, city_id0, city_name]) + :- Exchange(distribution=[hash[city_id]]) + : +- TableSourceScan(table=[[fluss_catalog, my_db, left_src]], fields=[city_id, order_id, content]) + +- Exchange(distribution=[hash[city_id]]) + +- TableSourceScan(table=[[fluss_catalog, my_db, right_src]], fields=[city_id, city_name]) +``` + +## Flink Version Support + +The work on Delta Join is still ongoing, so the support for more sql patterns that can be optimized into delta join varies across different versions of Flink. More details can be found at [Delta Join](https://issues.apache.org/jira/browse/FLINK-37836). + +### Flink 2.1 + +#### Supported Features + +- Support for optimizing a dual-stream join in the straightforward pattern of "insert only source -> join -> upsert sink" into a delta join. + +#### Limitations + +- The primary key or the prefix lookup key of the tables must be included as part of the equivalence conditions in the join. +- The join must be a INNER join. +- The downstream nodes of the join can accept duplicate changes, such as a sink that provides UPSERT mode. +- All join inputs should be INSERT-ONLY streams. + - This is why the option `'table.merge-engine' = 'first_row'` is added to the source table DDL. +- All upstream nodes of the join should be `TableSourceScan` or `Exchange`. diff --git a/website/docs/engine-flink/options.md b/website/docs/engine-flink/options.md index 9c71e70778..3cf7490e44 100644 --- a/website/docs/engine-flink/options.md +++ b/website/docs/engine-flink/options.md @@ -1,6 +1,6 @@ --- title: Connector Options -sidebar_position: 7 +sidebar_position: 8 --- # Connector Options From e7a22059d9d728cbf9a9da054eee3817696150f8 Mon Sep 17 00:00:00 2001 From: ipolyzos Date: Wed, 29 Oct 2025 15:17:08 +0200 Subject: [PATCH 2/5] add small impovements --- website/docs/engine-flink/deltajoins.md | 64 +++++++++++++++++-------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/website/docs/engine-flink/deltajoins.md b/website/docs/engine-flink/deltajoins.md index 68232e5791..29ba830c69 100644 --- a/website/docs/engine-flink/deltajoins.md +++ b/website/docs/engine-flink/deltajoins.md @@ -1,19 +1,27 @@ --- -sidebar_label: DeltaJoins +sidebar_label: Delta Joins title: Flink Delta Joins sidebar_position: 6 --- -# Delta Join -Begin with Flink 2.1, a new delta join operator was introduced. Compared to traditional streaming join, delta join significantly reduces the required state, effectively alleviating issues associated with large state, such as resource bottlenecks, lengthy checkpoint execution times, and long recovery times during job restarts. +# The Delta Join +Beginning with **Apache Flink 2.1**, a new operator called **Delta Join** was introduced. +Compared to traditional streaming joins, the delta join operator significantly reduces the amount of state that needs to be maintained during execution. This improvement helps mitigate several common issues associated with large state sizes, including: -Starting from Fluss version 0.8, streaming join jobs running on Flink 2.1 or higher will be automatically optimized to delta join in applicable scenarios. +- Excessive memory and storage consumption +- Long checkpointing durations +- Extended recovery times after failures or restarts -## Examples +Starting with **Apache Fluss 0.8**, streaming join jobs running on **Flink 2.1 or later** will be automatically optimized into **delta joins** whenever applicable. This optimization happens transparently at query planning time, requiring no manual configuration. -Here is an example of delta join currently supported in Flink 2.1. +## How Delta Join Works +Traditional streaming joins in Flink require maintaining both input sides entirely in state to match updates across streams. Delta join, by contrast, uses a **prefix-based lookup mechanism** that only retains *relevant subsets* of one table’s data in state. This drastically reduces memory pressure and improves performance for many streaming analytics and enrichment workloads. -1. Create two source tables and one sink tables +## Example: Delta Join in Flink 2.1 + +Below is an example demonstrating a delta join query supported by Flink 2.1. + +#### Create Source and Sink Tables ```sql title="Flink SQL" USE CATALOG fluss_catalog; @@ -27,6 +35,7 @@ CREATE DATABASE my_db; USE my_db; ``` +#### Create Left Source Table ```sql title="Flink SQL" CREATE TABLE `fluss_catalog`.`my_db`.`left_src` ( `city_id` INT NOT NULL, @@ -38,10 +47,10 @@ CREATE TABLE `fluss_catalog`.`my_db`.`left_src` ( 'bucket.key' = 'city_id', -- in Flink 2.1, delta join only support append-only source 'table.merge-engine' = 'first_row' - ...) -; +); ``` +#### Create Right Source Table ```sql title="Flink SQL" CREATE TABLE `fluss_catalog`.`my_db`.`right_src` ( `city_id` INT NOT NULL, @@ -50,10 +59,10 @@ CREATE TABLE `fluss_catalog`.`my_db`.`right_src` ( ) WITH ( -- in Flink 2.1, delta join only support append-only source 'table.merge-engine' = 'first_row' - ...) -; +); ``` +#### Create Sink Table ```sql title="Flink SQL" CREATE TABLE `fluss_catalog`.`my_db`.`snk` ( `city_id` INT NOT NULL, @@ -61,24 +70,22 @@ CREATE TABLE `fluss_catalog`.`my_db`.`snk` ( `content` VARCHAR NOT NULL, `city_name` VARCHAR NOT NULL, PRIMARY KEY (city_id, order_id) NOT ENFORCED -) WITH (...) -; +) WITH (...); ``` -2. Explain DML about streaming join - +#### Explain the Join Query ```sql title="Flink SQL" EXPLAIN INSERT INTO `fluss_catalog`.`my_db`.`snk` SELECT T1.`city_id`, T1.`order_id`, T1.`content`, T2.`city_name` FROM `fluss_catalog`.`my_db`.`left_src` T1 Join `fluss_catalog`.`my_db`.`right_src` T2 -ON T1.`city_id` = T2.`city_id` -; +ON T1.`city_id` = T2.`city_id`; ``` -If you see the plan that includes DeltaJoin as following, it indicates that the optimization has been effective, and the streaming join has been successfully optimized into a delta join. +If the physical plan includes `DeltaJoin`, it indicates that the optimizer has successfully transformed the traditional streaming join into a delta join. +### Example Optimized Execution Plan ```title="Flink Plan" == Abstract Syntax Tree == LogicalSink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_name]) @@ -105,10 +112,29 @@ Sink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_n +- Exchange(distribution=[hash[city_id]]) +- TableSourceScan(table=[[fluss_catalog, my_db, right_src]], fields=[city_id, city_name]) ``` +This confirms that the delta join optimization is active. + +## Understanding Prefix Keys +A prefix key defines the portion of a table’s primary key that can be used for efficient key-based lookups or index pruning. + +In Fluss, the option `'bucket.key' = 'city_id'` specifies that data is organized (or bucketed) by `city_id`. When performing a delta join, this allows Flink to quickly locate and read only the subset of records corresponding to the specific prefix key value, rather than scanning or caching the entire table state. + +For example: +- Full primary key: `(city_id, order_id)` +- Prefix key: `city_id` + +In this setup: +* The delta join operator uses the prefix key (`city_id`) to retrieve only relevant right-side records matching each left-side event. +* This eliminates the need to hold all records for every city in memory, significantly reducing state size. + +Prefix keys thus form the foundation for state-efficient lookups in delta joins, enabling Flink to scale join workloads efficiently even under high throughput. ## Flink Version Support -The work on Delta Join is still ongoing, so the support for more sql patterns that can be optimized into delta join varies across different versions of Flink. More details can be found at [Delta Join](https://issues.apache.org/jira/browse/FLINK-37836). +The delta join feature is still evolving, and its optimization capabilities vary across Flink versions. + +Refer to the [Delta Join](https://issues.apache.org/jira/browse/FLINK-37836) for the most up-to-date information. + ### Flink 2.1 From 3445f9ad6dc13da3ce1aa9b8c4277a9ce8f02689 Mon Sep 17 00:00:00 2001 From: xuyang Date: Thu, 30 Oct 2025 14:26:59 +0800 Subject: [PATCH 3/5] a few minor adjustments --- website/docs/engine-flink/deltajoins.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/website/docs/engine-flink/deltajoins.md b/website/docs/engine-flink/deltajoins.md index 29ba830c69..7c175d405b 100644 --- a/website/docs/engine-flink/deltajoins.md +++ b/website/docs/engine-flink/deltajoins.md @@ -8,14 +8,14 @@ sidebar_position: 6 Beginning with **Apache Flink 2.1**, a new operator called **Delta Join** was introduced. Compared to traditional streaming joins, the delta join operator significantly reduces the amount of state that needs to be maintained during execution. This improvement helps mitigate several common issues associated with large state sizes, including: -- Excessive memory and storage consumption +- Excessive computing resource and storage consumption - Long checkpointing durations - Extended recovery times after failures or restarts Starting with **Apache Fluss 0.8**, streaming join jobs running on **Flink 2.1 or later** will be automatically optimized into **delta joins** whenever applicable. This optimization happens transparently at query planning time, requiring no manual configuration. ## How Delta Join Works -Traditional streaming joins in Flink require maintaining both input sides entirely in state to match updates across streams. Delta join, by contrast, uses a **prefix-based lookup mechanism** that only retains *relevant subsets* of one table’s data in state. This drastically reduces memory pressure and improves performance for many streaming analytics and enrichment workloads. +Traditional streaming joins in Flink require maintaining both input sides entirely in state to match records across streams. Delta join, by contrast, uses a **prefix-based lookup mechanism** to transform the behavior of querying data from the state into querying data from the Fluss source table, thereby avoiding redundant storage of the same data in both the Fluss source table and the state. This drastically reduces state size and improves performance for many streaming analytics and enrichment workloads. ## Example: Delta Join in Flink 2.1 @@ -43,7 +43,7 @@ CREATE TABLE `fluss_catalog`.`my_db`.`left_src` ( `content` VARCHAR NOT NULL, PRIMARY KEY (city_id, order_id) NOT ENFORCED ) WITH ( - -- prefix lookup key + -- prefix key 'bucket.key' = 'city_id', -- in Flink 2.1, delta join only support append-only source 'table.merge-engine' = 'first_row' @@ -83,9 +83,8 @@ Join `fluss_catalog`.`my_db`.`right_src` T2 ON T1.`city_id` = T2.`city_id`; ``` -If the physical plan includes `DeltaJoin`, it indicates that the optimizer has successfully transformed the traditional streaming join into a delta join. +If the printed plan includes `DeltaJoin` as shown below, it indicates that the optimizer has successfully transformed the traditional streaming join into a delta join. -### Example Optimized Execution Plan ```title="Flink Plan" == Abstract Syntax Tree == LogicalSink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_name]) @@ -112,7 +111,6 @@ Sink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_n +- Exchange(distribution=[hash[city_id]]) +- TableSourceScan(table=[[fluss_catalog, my_db, right_src]], fields=[city_id, city_name]) ``` -This confirms that the delta join optimization is active. ## Understanding Prefix Keys A prefix key defines the portion of a table’s primary key that can be used for efficient key-based lookups or index pruning. @@ -125,9 +123,9 @@ For example: In this setup: * The delta join operator uses the prefix key (`city_id`) to retrieve only relevant right-side records matching each left-side event. -* This eliminates the need to hold all records for every city in memory, significantly reducing state size. +* This eliminates the need to hold all records for every city in Flink state, significantly reducing state size. -Prefix keys thus form the foundation for state-efficient lookups in delta joins, enabling Flink to scale join workloads efficiently even under high throughput. +Prefix keys thus form the foundation for efficient lookups in delta joins, enabling Flink to scale join workloads efficiently even under high throughput. ## Flink Version Support @@ -144,9 +142,9 @@ Refer to the [Delta Join](https://issues.apache.org/jira/browse/FLINK-37836) for #### Limitations -- The primary key or the prefix lookup key of the tables must be included as part of the equivalence conditions in the join. +- The primary key or the prefix key of the tables must be included as part of the equivalence conditions in the join. - The join must be a INNER join. -- The downstream nodes of the join can accept duplicate changes, such as a sink that provides UPSERT mode. +- The downstream nodes of the join can accept duplicate changes, such as a sink that provides UPSERT mode without `upsertMaterialize`. - All join inputs should be INSERT-ONLY streams. - This is why the option `'table.merge-engine' = 'first_row'` is added to the source table DDL. - All upstream nodes of the join should be `TableSourceScan` or `Exchange`. From 72c08887806f1bfc9ae4e816ea1bf76113eca16f Mon Sep 17 00:00:00 2001 From: Jark Wu Date: Sun, 2 Nov 2025 19:47:33 +0800 Subject: [PATCH 4/5] improve by Jark --- website/docs/assets/delta_join.jpg | Bin 0 -> 85431 bytes .../{deltajoins.md => delta-joins.md} | 33 ++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 website/docs/assets/delta_join.jpg rename website/docs/engine-flink/{deltajoins.md => delta-joins.md} (73%) diff --git a/website/docs/assets/delta_join.jpg b/website/docs/assets/delta_join.jpg new file mode 100644 index 0000000000000000000000000000000000000000..baa460880f4b87ba9dbcbb90b31111f7683647a1 GIT binary patch literal 85431 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�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

hU@X8k-?Oaf`4miZTG8Hc!{!u~6 zl#k*E@Z&%&=-Vgn*WBe!+qN7>0hdYl^H5x$^OT2-^n&VfTqTaPw9cb@y`>= z`@Qh=S7f*3x6+L@7A{uy4Pfj6!)#_jBa~Z%Rpx3jpMDYx5j}-#GHrtPVp~Rsa0BCB z^e)FwERr$6j>;EnXf>vv$j#)Z@-YAFf!q=MSw0?o5`k$^z&luA;MW2&7dC^kyM(Np zThcqBVrGwYWGg4s^r`BwZ52ApevwC1ib&)jD*M}fsj(FplnT+Apg2sGNYjy zFUi$65}?yjSn=PV+sC*=?U@;Vy#tpDUfpy*kfYGg<0RVixzqx`@3hHTuBUX!ZZ*Hp zk!g;0${0x9ZPeCY6fiX!u~6y|)}uS6TLE_s6RaVOu!p!s;(ek75k67THnA2+d8(`0 z(u)7PHTD{qR-mfAb`d}facgNnGLgc%NYIOleo-IiHKozBO3p2MwXt{2a~@T~g@$4N z*vpBUbv*f6?Aq{^qLUHRsUHw+_`Sz7X~U6NA8UoA7kV|Z(tN+idzTN#V`vI4wzceVig&&9eo#ZhFGx$ytz~@GVZ!|aHFJ>Dq zkLCT=iQL$8y(TYlt@qdOfhE!FQFZ}K6xL~YH>%#N=W<#j-Xk6_vG)&17o+gN=k8~T z)Wchu_WXsbOF4*O@E>Q;i+GH-ZO(Yt!`^JGQ`sK->y{ZEz_7GZw1d1b+FNU({|ISuB-pu9ewXtrB)kt5IFMfV=FMZKpgY# zkz%Q&xvnt|s->D8O;}H~0s6Q~LnWZXDd>?>0b-hygGP@!ij;OHGd{Khqg1`ZN>Rw~ z6d-YeBCcNM9gqFALn@`xso*!RD$MVV*aE~iY9X$705+3y!G#n6p|UrcFb;a7EN{P| z?y`Y2)j2Mp78uVB1ZZzef@;9}>R4eF%%MRIL`Tg7x~-QaJ=_sbVefmvX6oN94a1P; z#z(q^YH35gkU(8*Ys5?n*OrA*`DZB?Ras{mVONPld?MDF#QODIOyF?oA5c7NKxgvp z{60Vs*D|;=E zq56V%(xr7&amy&nfW@dip@H*ZNic#P0}JNP=*&o()Er}QQ2%`zx~z9o-@iet)wRlTZn{>6a5vA2@rPg z)YH^9BE<#gjx!Pn;hgvSMG3AzxiE>fD+WFIBS5@qL3tiLIRN2r;TG#oT6p+tt?)ij zG5>Nuake3cLY&lHzh(x=Zyi1|;H+(Hi5C+B-+uWrMhAAWS7)+i|1nS{JHQ7U+AGRu z{^saX-?8gON90h>>6O*hWoFedBO~~PYC`@Z`?*|ySv%XgbPuIuZ5!r{5hWy$OSN;b|#+&i+|WY*|OWHy^?4HoJN)Fd2Z0Ib(B3F96mI-G{Eio}kz@ zz}1lyj8^`$HNae|S%T;s!%+eL=1yNqcRtB51gO@Sb8wsB12ZWU&MKb-&!F(DF7Ka< zoATKsU*PZ_XT{$}=ZxXsF9Q$31=a&(yE&u-A-ypqSRD!pqg<)^6 zv>{9+{;EO=H&5Sv>}w-Lg^1fP={yJau1&Hifhkf*5HErt4C#CleHq2IldLb7uJtN5 zaE0N;3#C(qc#>0yG6Khq$SQ(q*dc-d!QtT-uY|nI(WD;>216RplHd@z*q%lLxe&=Q z^W*^0ww>Sa2d|n!blibBOQ?l>0aAWAr|cKoTEl#3H6E{7i-3{pK^8@T7!YTSnl{jr zxS4k)#l#Op+cYlC<$RIV{NMcjMInk^6e7f`$G0mqLx4G?@@hg zL)08aKmP|*SuNj+nxP52|$0_*zt-&;Pg=(cDfA^HWJkRYx~{&nk`+7Y(03L*7BW8 zmR1J?DNlzBQa`29$o7tC@yj8gi`#PHgapL~H^O4yE4U+|LfslH@FBz{4VtMqL{u~5 zQ%w9Pr*RPhzoUhp8(x{zQxti&-qB2gJ>mQ1su2Q1>Y*9G;@>Ag@?B4$&mxKRQ-Hz=8P)@L`PSsbDSfLNUl_Xfm@SKaFl4qET(>_$snsF54>|mAo?KF zJzbR%U*LSF*(fa^v9;ME)Ar&b{y>#SL!2Aj~KhXFZ>|W_{n^xy;3Cp2YaaC|ozIAl=pDrP(Fb zm+vt%$N*=oPB-*@p28@c69#LHcvg+)>&0{}NY%Zwei-Z*-v7MJ8u@n*$*m=$=6K&b zoZTVml_1zW#H9o9-0nd|DHG7zf&7~FjO7r{P6}U24@DhM`Ap7O-n%aRj5RnhNi9Wx z?xyKkOylWoS#y7t&=4CXb@vs(pFd_xNLhwVLwgsb3C765<>4zXCLI9{cP=hW;s?T) zsa5L7R@3b*n9@K3h5_2h6%;{ixa(atem@p=eQB6)v&Ke?een~f?u(2&y9iFm^ZfAqTAdH8gcQ8XPV+m=)1)4Ok5XUp&n%mD8iMXqojGl6 z%!+A0&*4kfl+oY?@C}HU!yK+q<~JS&y>EwCpuAnhop1V|73VIEd!;J`ybKuWVeZQ; zTUY_>ml2;(W)&A}{JT*susad$4FWBA2)|o!{ zvSDHo9isAy%q|dSm^W_UY~+Xt<%cQa6(}D|?a=P5c82t?dPfI12kdWJ7McvaE(I;w z11&+v<0I8p>UJm-%4Pn>;_!Ie)qu(_6SX&Wc~7M10ev-=*L!Oa6rzetd`d2XUB_+o z=4p^iHb(XpE(ZttsWQoFSv;u@U!Y4iaJ}i*UnPFWUoRp@h6@nyPB&m#cFo#o^H0*r z)h!Q;2#Z)`qO`P>6987@wahRMmxvJzUr<+Ob&7hO2z&W}*TIp&TnExt-=Lxx*P_a_ zN+VsH>p9_gpLEUI2K|wsqPPQ%TD+78P{oRY@An!(afPMxXa1D{jekHU$){ay%A@k7 zUQ#O!Nuc_M$IorwimxKGTA|)g0_LBAba0e0%L#;gJ`Kr*9NTs|;8RB)L$fzPajT#1 z`m%YRkS|f{x@VtkD)8c-BSYrgW~OFOLx?xgfuxV0Ov59W6WgUDEYdY-@D@E@wLO8@ zGY_CmU+A6o@hFgz9o2ne&vEfiyqMW+#t_h)LjaSrCxVY4-HD(&g0jQz5?nuTd%HCQ z!EZ>l!5i*V1!gp9C24}rth9om8_DI{-|`jb!L`P_eYl?|Ik>^7D2mX1U$%4gj^;5x zehsf0=(8d1%Ux1jzM=Zn)ydzy)675+;6Qr?p8CF&(PbPugNbRe#DcGqbO{xe3YA&Q zI~Bg>*$3x4Pk-jgKdX@Z_z@~tCE9tfEG1b};YfPd9f&EtOD=_jtSN(V!Nw*H`7t$- zTOYBi5^+u84nlXA)wIhdsLQlz+&BJ~{28L4Ipskx9QxWwJT zk^se%FZhx@$>N>S?}SBz`mud^?+fJu9*yrG_GJVL|Lz3wYVzhJ>#b~419XCMs(wOT z`@&_s-(*?{c8~#W**H?Efhp+=_TcZbvY`r-zxB{dN^3gf;#-CB!;w*DRs4UX+wl=i z0J&)-7P~M>*VLT$JW?jz|GK$OnFz=tj!<|KPf%VqR*+WHVcNwrM!&jmD<=Rq`9sa+ zsm$2LkMHqck}Wq9w`p`U`*dJP(YY(as~x*up}@Yr8yp~1aSI_%knVvraHLQrgJ}pp z?v;0Hpt{$&J2v_g1BH|zFjl$IHh*A#0mWx@8}+-Fp})-jc)m8(S^9b!y?>KMP>|2* z*&8};z$^ZnBsk>F;U`#z+=u+JC7)Ntlk0Y|UO$}+WAoc%wv8|TMv>dIWDhAf^t##^j%AS-vW$(UJ% zJ?#~Ds4|5${iyIC_O_FPDFXPn&D`l4`NAe-0M;fETYBW6_hgKpc>b zM-s2W=f3e{abA&ex8Qny^sjYS%1xc;5amZ2Ux3f1xTlUU?C#Z_we=96AD7OskMnBy zs{e~B^;+US`3|#0=dL{YzIl_iy40j~e-yE*Gg1fg&_s{)eGVoAxGkOWdKR|ywT)cY z*0&iYtI(j{>5RO5-vk1(uB3BLIrX7Y`E||(55X5Q)#XwK1G6&Xx$koOn0gjMf0wtN zdUbBRycSx+Fq~anxP45LCgdk&8@;b|KZU*+c|-i5y^=UTd+!he*)6!$de{Z6j_O5R z1&z6SyWpzJSfP)qHk4Kz;f|r9K0bw?`2&y`e#J*)^1dkaxFHPROn3K$| z$(Qf;b3dE3FOMJQRxRhh)Zw4vgZM%k{@xMbaZd$Py0-O&jJUs)f0@#iZKGk+CX2t> zaM8Z@uIX(9(#=F!!|ucuxmtm!gtSG%%E?ngpa*WzVyuPbOFEumHnP4k`DuEf@Q1V$ z3clOT@$!!)QBV%U`C>L5CYB&h5pq^=zgPF@{;AblD@p#{(K<}o(Kx|a`n~ew55nK- zPJ>Q7Pt+8bARU8>%Zl%oBcGX)v|zF4@7vE}e1FC8R*M*^2YJ$u|6+)<%+a;*uVhgK@^J2zcqZ+{ai@4rz@T`v|`aB-DKpUx-9 zEFNg2oA!0-)(qND3L`Y>j|=H?4s9UaNHEYNTvns6fN9|`%FVgXus1d4shaC#C0)4_ zHqDk7{No%GPZ@^RC3Ycao*r6P0oc87QyLL`tVVvK_R)75r8u2a)TRYL4|&g4yt#kb z?8&@2*w1sI*h*ZVX?wUNiVn~zrbf&i7rfRRW*>6nQXV$dR!#ZWw>+!{q_*bx>LqlB z%S`5oQfai9j;7GDwP8aU6LQ@TMNTZqEo#<8P13Ulf?s)n6(AnY9$jA@zBu|b0(6m4 zkxLml_IwXIgdtsXpcuXFha6o-0eW+eR#FMQ(N}?%^-647OM}{+M__M-XwT*XDvZo( zHsUISnQ5UO~0{3x1K1ns){ee>+No9|snM1QgH+ z^oD5_B3A$-q~N?-W_o4dg79sW7V`HM3ykM% zWcL@d->lUB#5Hnngju>vG4Nt?p|@5s<}_`a^vevh<~ z3)LOpJx#!kw3Fv+5DTK>ca=Lc4HpaY1w7&vsyl|~IkC{*&@0S=TSi+)Y*~c@N1zeq z-hdLvpixKDgj$df%VQXi*M*Ho1(1XP_r1pkqSk>2nW(HF`NEWZtG6`3Vjcjfo-?pi@Nez`|Dl80h$wZeCLoyz@>@?4sBK)C3>z`I zz-;7eFsttB3S6|aFv2!sMVe#{?2H^y=jKo?K8xXe{%QnJi*W!cQ`6FvG>Z}K|DjBN*?fQAGW>$*RsU67&_qNx=+%rTGv{x&IvwSY5aIqCpGFlBM2EY z=*!n>`K8@{gA3_AH1}ogq{*Y`<5A}ATdYbVvEAB+hd!I5TkwHI8*(OGGQj^K3UjO~ z;Z!qbpS=E}L9|2~nh4G5<(SqZU6zd2BKmOxD- zKCwY>kWFtTDWR_~ts_#|>~>p#lRmav{7s=~@2KaV;+s#loDM5(Vs~_`c1cW2EbJtm z38xX#^_S9Kf?<{Xj30ZV)6(b%;tThcxQ5&l?SJ*~?u&IGk&(A@zUikr<`lYr-$vG9 z45p`W!rE@)9xf*#{0-L<#^?Bw-Rnm*zyUSg6!4_l<1f=ONAom_3%X7p7~N~@-`3E2 zQV|OM}DVmyz(H&0mEIfqg&z%q_06<>BjsW*Wr99+{ zW#4mzoA*uG_&dLTorf!5e61sh;jqoOukv}_IT=4Qe=GkeA;-=lrXcnEV{hZ;s+8j$ zU6qZ=*2lm$rvnk4&x%bx>}>WVie?tt4D7I}qRko6x3vQqm{qa$Fb|>{$qdJwe!fuk zwPGk2G>|g$tLC-?ae$Ufx^0em{R`}2=m*5N-!0~bO@V3qGxMYdKA)T?Wx-B{2d6bv zSj+XWj-70|upO4UB!U)zaKW7*O2i#NC8YtyJ(5K%7fFR}P;M%s&hIXu3Wh5XSG=J_Odt5q znKTaW+z$a&pg(8`!b}MhWr-?(53QSU_1U_^(?|Kt`jZuWj;o1x2{yk8?XOBspSHP? z3sEmn(TLi_c*=D`3AQArw|Kc#LbtgAM;qbZth9Gbznejp-DRZx=&2|k{_IDGFxy3l zA$(Bw1MMmB01{C^``u-CXTs}&^LNXD$j9Gj^;!IGt?M3=H?xdyw0#EKUPYzfb?(oqegfh^xJoU`J z%kM2y_n)i4Dt+~13a+vNd)f)1CixJ8zr$n*aSkVYES8$p;`MzFZ|w2?*AC1c*mE1# zUlL5x)Zho#M3LAoVCS6^Pby-5nT(|2>LSr}NtPL<8jYS3qktW2afTX=642lcNCwBO zPXdNk8qB`@<-vPB_h#H^=Oh4f3YGSK`#sPVYLKFRpf<41x_Cs0D%mVsqDQ$J^D2fu z*YeDM!kAIZ zEHY2k@oMj*;MLi842^U1DwwbNR;qty`CUN0fdwXX?7cgXD=^OG{S1pqN$hJQQ|rMb z|23hxu7irw=ikgTBt@Gb!oDhLpJ@VrO3PJmVX_|uVFrQrbx(3Rn9UIwEqu^6ZKO@P zqV1i-M;Zu3^XdqYETRGuPf`gHrQaVGT@JY+8z7^zu1jmoTQsL~^_S_G5c~18Kj>vZ zTyW0!mRuAQbSdCjrD(?}(E<*gNF3qt(;U_9FxS>o2mRGU%HTPB^WQJ9OA1tAB^<;f zGM8?xb?`^O(-<4pMkDn}BY4Glm^IcxiE!kui zaa_=+njVbTZ}G)A)GDlAG10O1voR3z(Pw?Afd{&g&&zSb)5{(VJ0>unQ=|H=oP;pg zXuz7ZZvi07Wn*Clq*E;46`{Uz_3he7B6=5J}w0eamB6# zuy8c?_87;R*l)X!(6zF4tJByPV{BmCAFQq2{*x4C+HL1gUSokuB$;O-$kq_RVl)-p zV{sD|2h(ybDNqysqR{^_VjPu9r?mAm@qSOp)#d!@%S(UXDQ-V)P}yzl-TBw-8F-l` zU4_p#FN;gz84!R}eVZ>Nm)m!?NT_6Cw{88l;>Go6QG=#Fi{<$wRmd%my-Lpw19#oL zz#^q54{r~IfT(Y^<^%0yO$m@@q^8~9l`^e$ojaSzQTh!L$GZ0x{I^Ua9A*CoOdnv~ ziLce*`Llae?8LC>6n1@%PEbaZel=y-*OpmZ;&5&ZZFSJxu{?U1f?BFLtJ!{S$1`Sy z6>nHgLvbSdz&UyBIU$`9c`%FhCu5ea`WZ(?Et#3lq|bu(tfin$8LKHFq`oq`LiARf zRI#2Bzy@(1(Pj|;^Hfu2CWTH!zKxQ~{7~y&gdrdH#qGF--(E@|MSj!9)+?#)j>-* zWc@YvM|G~gFVvYrwJ(&CGkP*?Wo2xIA6gm`Rod6q0VF|XW5Co z?_w<7g`^N)O=e1MUX#2%kEaXO-1(^QWCj=5=qMAQqoL(@;i;MJ#|6MwJB8P&Dr_p; z(xe+P331uidF59?&AlF`$!A6l1fq-~MQ-M)}?LFG_$D`HTZ zyMTH!J)274s0IE8lsC>8W{{KQ8Z<(8NQIwrK555$8X>Ud|87~nZ%WZ4^WiER6kh5c z)X807n^A0jbV;C&9K4)J%xQyuB9;BvCr#GL0 zTpx}tVW;bRVOb0+6OR%;0s z4d;&$n+pkRomc0 z8q6&x*={#IMi|%sDXwWX0G{ zdnJW+FeL=B-Z2`lI=Yj!AhPq=ti8K!(0T14#YM1EVgNMa^Ymi`dQ`8 zBFu0Z@i`sA2$%li{&m?K^Y)>a%oG)`r|EUf=qPubZ9gl&E5Y*VN!h@bzQMB!k3RN+ zpUArD3O{w%KNZ@Qv{xHcj6;wENAM7Jqv0NCO#>Rpiq7Z>lI+0qwnPRT^GZ~0)EnJj zo`(8Yds0^^tmkvXg0U#x9V?iI!k-MiNqKkk+RR!n{_bv&zdkrDCEbLLs_{Tu;!D&r zVvl`^$*Fem0{UtAga6gun?@zsy>G)8Qc&j5V5NpbSq|0hkW`=|Sa;%(W7D0PR$4;c zWr`yXU^Z!l7M4X06r!1_4Vqexl~aWvnwI8>sYr?g4mtH~|G($|{NFF{TJOi_!~4;- zT)?%jz0ZA~=W(3J!CJM4J^qM{+Z5?{u4%Cow*nPEY0`H8cvDrH!mF{^{U*0Xhzl(V z{txuF!&F~0y)&&(R!xnuWtIJVYI{z*2T8pj+PaF|Jc}-7wEYYza8-7}`(-0sFSTS@tosmtS-~GjBhq|S zmSDZAvNcple0{9&_^ltS5;tyxuep6YJ?YfF?UkDH^zThBGZVa-0ux3>!No{}W#$Wo z!Do7P-)-`{Z_pPxvo&wyrN9dxKK2eazCUx)BJrLv8SDPE#E&1+=7ejX@!v4jEYEh$ zb}w6x`D9+;p0fLPE|;8}+}2utqiU_4*7vUph^^N&-p79PGl2hSvTSt`lhJXdXY*Zp zy0dxpw7{0f2sOf4AMHj-k@{4g4<`Tn=pe-$nm&>l`5dvIlQ@wLym=O5P}^&@I~GLG%9(kaM)PgD1zy~op@(cW+C zeM;Y`i6}=rdbV#sPeCI-j)mJ6lM(keC#AJKba(wsQKi@NvB{fFR-rw>yDY>96YKu^ z`uOIwimji->Ac8BsgCZv-Kc-13o^QiiXW!*R>a-+Qg24{*B6AN`-|WFGr69{SNyU{ zBO{DsKOfuVyy^AV(TEn?$Gyty90cvMCs*@F zlQ&h!?g%8__@Ol2R{!h9{=VC7mLL9gDE(~Z!j79Io~^>}nM02}Ue8tJ3&(Q??$78= zrwu=gJT>|=(f7sm3$4g28$a)}&Yhr%3xB>9)Kskdv4hC_pd6nDhxHdrI?BDhd-8Fq zE3AN4@(H}+%#Gtfgz8-S?n;00VN1O1^|gfyQqxErom2Ac03M5%L?dt9x_~$cNTklXbuzKh0L-G5-rPam-zfEsm@_LS2Ge_9_iw) zulxB2s+9`S`QInrA8q$OR#M#TI|5r>L!I(`F+6{=LUHmB)bgWfmG(dN)B`lfF%0d+ z%X=Mtw)7{DHr1wW)g7GGYOd?p>O0QG+iz`4&y7wTEMGC2eB+IELdJ;` zbyx2t+A48U{y?8?KTqRk@^TUyN*TxEnHHy?&i8@t-J)NVwxWy2S8Le>tuIpf$>Jw3 z<7TZBA2sjgJzUua44C60)~R5df~4~*>qC^e@7oVQq`UG~uC4$1w_Q!N zT_vW@YJ(MuQk9=cxvOmA@!K=>CblpNSG0X`B%KKc1%`Wyz2Pq2exU>T^KjPabWEvM z&jFhrzGjn)ulp6d$48Q486&Js?HG-%cLVsrK}tg4rgl5>fWxbSZ2hi~5kUx$sSd0< z9*)ce_O$zBMKO0;3(x$+)r+@D_wZN_=}r$j#yeA5^%I(f5N3!>X}GY;a}0ld-pqfh zV$J#cZ+$Th(ua3-iEqZuXO0Ovw=d*buMYE%+_RA-ea+GND}{K@MK}EJzh3jh9n93Q ze4m{?^C7$ci#_bz6!l-kLa{Bk&biD^S;JAb&i(4E5T^TF1njIa>PT0qIjlX)+iUflsdbSg|G&*|S^_S2%~m)>kr* zC)wFaZ&vLLxRau?W58wYVjErwooN;p-7@VN9qr3F0VeUAi)r(L<&mSZUnj>5JQ6#? zULPqCEz2!gJoherYv0|C=huP!0Sk&CvpJ2(osFOP`A*@WP}yQ{b<-KQVdvgf;|tlo zKaA*qAnM0YrO9?XOaN$5WVR?2nBl9QWE+on&4RyO9!1*E`9-?4d^-{5Rnv4pbv*m; zy@y78Vqy*IB2I-z(YC)F{iNFFS8Z)AwDQh5F*H53;h0;!K|8AbM1jV~cY296SCh6X zKMSwrMaPF-sMKCLN?kr$bHgw5&iv)~Ih$weZ`Y3PZk3C(p9gqtJ}W0XTtA-t-YBz# zm-D)*6$r$fOTrx6=pK;GsJ1VVoqf_YI=@_?7McOYv?ODIaZ-sUwi^susyJzX6e_^( zI96*(%-VoU*Z@zxYKmLJIpqoyoJZIqJuHH_28B@gbhZDD7TS8iZSGPjTvf93uR^KM z#jRt8evGv$hxaZU>n!!33S3}W!RO5R&pX2`4>wQlxJ||Q6z`R-(%tauSDHt)ny*gE z0A)`=&5og^aA>rzQxI#~Yw*+IQ+=5&PY;MSu+MP@A3HT$eZzuq9!+jxbiWg1 z@q?!ZP$J{9bzy$MRE)pD_dRh_MadPGd&NIHm;q_U{T1l~HCokP+WAemqv9j49yzq; zoqd=&F`UnEw|tE-j-2WJ;CnZ`J2tin_wbV9?Mr8mKDlvWa-Lxp7S~j?6`L@qhb%K` zVlPsB7SbyGLDQ<(;z&YV(3I0tmDK0R%C->t#k>TVJ?gS~!ujd0@3-t1iqPo^UK?-p zvSvQHta{itN1M9G@8G8iUe_Ipuzc$i?sX&2T=Y)ryPAO#dl`Qk*lqR6*}?b`ahM}v z^rzO^IKj0pB#reye0ISaF}C6M6T8Oq$7X|nY!GbvH#qH|<38KJd#?U?YD9ff>%zd3 zJQ2=TZt-v{Q!Si#TGMuwxmhKo1Uezh!wurgt>@Q{T6~H;BF@!(|Igk_*YZ!3$73ll zMRPkltt+g%NcSD1&lf-9-y}2DJ;NRm)11DjK74k5YJ89Vzb_HtD4(qif8LN>r+x1YH!$Rsr=wyV(C2rKYp;|~!aaW+qY&FBu|^+gCF(v$%@RKPRwjE9`d3}tra z%y6FU4)E*)#T0NQC1Hb5SkT!ri2#!N{Jo%*%|$Hj8m=YP(P06x*3B;cwQO zbx-$zY??Iqmdq<`goP-ky$sTlKzjLTl?PU$F*XFSEY2F4W9}ITr)zyc)=ldLki^*0|5UrG zFQwkC<$&Z<^7-d)ovQ)qbMJpIo{422T+@Zl=w&erXOE9ncUZbN2i^Ksh|?cBv8hgF zupbzGuanrrGC_`)NGp2GkJD6Rp_UQW*81fEh{aNf%eQTB3>5IMmzxQ!T zh>$a!AlRdwc(_-@(;<)Rx#7l-pZ)k89*phS`r6W7Pv_{lt?VaA)HJUi-dQsGJ6fBO zl6}a{KjiMQx!dP^hngMCACW^ZKI+sN!^cG$g!q^4ejRx%a%@A&&4>K@T9-0dKX zKTx&H%|)YE7cD

y?!iMqawse|nS8TwSs9On>oOWwfft_Osu@n~!8UVU2TvSm0H& zU>{XKjY93#khyEt1*Mw)ga}dV=>~({kDePX)>a7qQ;6)&y1Qd9XrLzIrWYf-b3);PFmk6Bx-a>MI zugVT^MgP{D#cx|w{bJswMv)S_DMaK_k+35ANImx1x|4Rdt^yRR|4@y+&YD}z2A5vc5?UkRO5bk`}cFKMGc;d3c>l(Ho)o*f-UZr zx>p~{WEwT5Bp9b&Rylt~(ptoS(}GO;1HH;p8WTj zJeGX4pkKD9eZumzv)R%37hmW3aC8|`6nlKb|JxCT5w-hS`D#pw=Ee}%;kEYNkVSuK z`o}*YPOJ;FKX=mSW6O0C!edkD+}|Zzp*;tRV+H$}SP4Jm)T?=0ea{EfOD?aR7H!oT zN4C55=WGMSEUFNjQ3Y=)*Bo;h{?K#FY^$}Z&^TBFq3}6G>aSDMR_>$oxIKNKTeD)= zaqM&Lx;GDd_;3C)`+cVAFSh*~1_R-5_PefLy)Pi9YHq&h{lC3$2eOwtNPe0U=?ZnZk>*r*;X$}Ptr$YFF!0) zuzP78rlmQhpvrJ*=Jh7D-zz5pJczSPMZbBQ09O&babWRvduOS~fY=)h)E)Kl>5=3g zUtxHrak$NNm;GmZbz=s}Q3$0gc=?Q1o z48DsmFYe%#zFB^iN7pS!1;U#Y{F3ILrG;~h)$1a@Yo8e^-a*P|n zWIkR$`tV@-EB~7OjX#tfKMGVHocsB+qS)M-&>i{m_to@sr>mpjJ+yDPs_w(Kjh!nD z&9UR^W7c0hvvmqDMI~@ee7AA$D2&+-n z?l43J4-;G2kVP<-%gl_mGY59O9yYaJ6vw(cwKO?2WK&lqwY7Agu7-Bg%n5uG8#zY^ znG45BdT)#@RpctmArnB=0X``l>h_Bhe3ZsZDX!1^^SB=J=u5 z2T^BIftOITTYHQ>Be*{qOhaiNJmr&T6a^L%Qbxtd2+M-euF(HHFz8ILkr8pTLK}2! zCmlXy^h49%-vjt7tz$!&Dk;&yO+<&a#yeAkc>~%7n$Z6v+Cl2Nfu!2c%z_7)S`VNS zVu(~nM+9*KS_^f&NRXttpJ~BX))fFL7BW%`xbo`hxyBtu$lOw)An0S}K7or;k<8>pp#rhR8j3P5H8 z;zOyBiyQIMa(%N_w&$EHL^cC31W2Qz3?XzNu#^ICo&e4EC(1c0*nUQes{)-^hMJbz zEE55jVb!Num&s*iWSRryOoGJ7TrDG_1BCQ4!b)0_Q>a1`j52KN!qe^cL6=N(RF^EL z23py8MI2}xgSNa+85|>JIT8yY^?GiuZk<{XXzxRQQb&1))daAUt_SlCaPb>jPyYN# z!8{-E4ZtMBvRw#smgkM(j?tWt=__fZN5F=+y{&F`Z(JVh=&QHBKB{f@9cZP6z0c!M zT%x>8YBlLeXK1Un^!(kdzxerGr4lPZ!+`NT)ogL9X*hPPEW#C> z9e58|gEoId1xI`hW9Fknq;^Gmk-W^=jsLj(u7q{JTDtf*6`Q^j$ zmjd+oPF9lo@A=1Tvn^k&5-(fmY8zuO?(B_^|EK6uoZhUS!L7sV!4-tz_&vs=m16iN zg^`k>RV^%?+Xfizf>L0(1;x9r0NZbx2iF>eGyr6jbcmoAFD|_(?oyh^iSUJ`PQiW8 zZ~v@PG`brR=hDGcZ|x7=8Z&5d7rFb5j-q9g(vl8`4UUXp+*Y8Zz+hU58uX9a%L7LuLdb}rH zvHem0+M$-Wo?%Pfm7NUn?T>y<@ox|NxjU?ODr!7`aL9HC+qtf*mWl`f_=hLB7b8Y* z5Oy8NbfM$}%Wlz@mjj*lAxaT>L%*A#CB@=wNS)mB6U$Gyhku<4t3D$1#>C@#f;TdHg8rx7XG& zWoEi@z)yRN-z8eKkd>D#$GnpTIg3pd8jfX;zvk~8*|hl-qCtSfxPJJ|h*@kjXr9h% z|Df{{|53}uw{!c~o$`O$pJht3Z{+P8cKNj58zk$i#l}_AN9WeuI#FX$F#(`|7oCNR z)xGG-9^ck*QpM*n+%%Y4&H8ZB5FL$rS=PEu(8IdgOb!-jQ5nJQ+!p~E=hON@S&}F#P#yp>v$jkYaY8Y-by>9O-A(-JkyWS zaVjmfU-?n%d-4^+%&W#$%$q$qE_u*hu=)vBpkp3WykL)}T^h}UFEp*(E;@PcSNQ`og(tC$-4kA1JqRHm`pL<%m{hl)S#cC`Lu_x14 zMSo!b>cvL-^kR0_9*zH`pIV;g^9vG}w=5RU;%m=)Moi{e`QQ4^N_bWEUd^WsOb+0z z`2nZ0$Y!@QU%)G3$Rp0h~JO{~XdvU75|eb=T+e+`Fm_>>vzlAY_B~D zi~e?;f)-XEGMdrwj7Y(P|OX8GTVC=s)M+K2Y#5V-Y=U z5)CDc32^1KBunhV2MP@(EW*n6JhCkT+@sk6z-JFy(LHeh4X#tKSOk3|^9mi?&y@Ru zI`cv1RF%{|R?4P%HAATwHLg~6sT^H~dkV?e1hX0UQN#i5UOHTWjv|}Y70XnGPZJ(C(ea*m$}mk{VZgep}LF!)d8sg2^)rTt5XL_K(i1wM5a>g1ub-ysBrEm zx2w!R4}jK|LUU#bx*)<8#$a2Blwybn{n!v9x}d^gzW|p_JjjNeJ17pj5Js3`$Astt z2qGfcMqEsvNUn~C{?F^CZeWU7eP{*@rb_$3pSMt<{odzEBmTrbf5iH?-G95U$ zsX^M|z#EZi<_tKfFKREViDgeM##NUHTs4Pg|%mc+WC{5oAFpe3eq zvKn-wMAa^!2S^?3P@)hi0ad|>T+^d-(?hLOeeBJhi@D@O_xy_9GVC5D-#ewc`NlbQ zy_fl)b>eBGj>`IrSiuG%-Y{!UZr z{;U({?_V7mzx3E%+@Lsc;fnbcqVrYe{gs zJdMOO_N-OXd3j>tDm_5h_TZ*f@G|Z4EbG0wpuzbEI?Hz_MkwpKHh#TAf5X1|MU9ye zmGLDoqVJ9*e)g9ML;a@22+wwzf7sp9z1^h8QRdh8wW20L;oxCM3K}~yTBLLGU4=ty zLT^4@e~$fDDJ8P;Q~K;$)rRu<=8Eon-U#3Q3kkja=rDE04cHmZxYOZ((` zdhVb>=rriQHi#CtcTdip80-726rVfyif`QwN4@}ASwv9e*~LrV^9XOQ)liy_aq?W_ zxD{>n{F=?%cjugn>LM)!9HPCC=+2w%$XZzN9?O3+LhEK(JgHlr{PEk_gMq#xP4o1F ztFpvh_-m(sfDyaMz}LIl!hloM{ms+IhxKi(DEE{qDI*u&SerG`KL3GODA|YK;fu)l zbX3@GHM_Q-$=0mLR&xq=Pb+$?M!gph!>S8~;Cs#k>qWQueFAMuu;E8FsTE|9g`|)9 z)HumL?ody+TJdXJqEG8z+bP2dHQ6)Ojs>*wGshs8ck`<088ZppVU!AwB1>E6mcM?V zLM^V}=YPvvwMWC^>80+S?nN$7Xcn{Vrp1-!Pp!wI#w-j2ZkKy8fgrMFUXxC4@O_<8 z`>s{C#HsX;j-O*+!22X)ACkpeFR>4*ltvc{4%OH#qbb{0b-wNJ6q)EA3X?11MTrxNuIx!oXG=lM~XRb^V?LM}=G})i} z@x*=H%_=P{pPCm3o=>)LuOLRXt<;>7W4~Gl*ZDa3{wYeyeT^;qB783W2+7~EM!bzU zTJaX&-_Yiz^C7<%+=uhlr89q^9J>`SM4YP=i!a-3m>qkL9(~j+xb1~2UKEV-cq3eN z#?u=IUy(Bm;F}{0LhI@VDFRVNh8BFvcOfm(T$7j)X(3Gd2p!jd5#R5M)sY$;i%dyL z{f?8i|23RDy!ph1f9|U{Vg7b~wkz;5QtLwh%ku5w?IfN_dDop^r)PGkDtmYb|AEYZ z*N%Gs(wRFnf3W!aoJZrMeQ)kfJxaaQN8CccTwDM7M+Bn=9)gp~cXZ3<*Xi~6UENyL zV!i#mdDv&ynB+(1*!L&KT!05 zuxFgAHtWgDBDX~+oJKs%Xg_e)@86g$*O&d%dmDM+ulqeXy>U!38};JzXMO6_ z5%|t85!b4`hCi} z+x(#us+(;54PO0$_V$&BSfM6vj(%I=l~bBle+eX5;pwjP7ZjPKrX}KMfV0L4+W?;mqn_-5G?bUfblJG3jVJvl^rt4Nw%>^y3)?bIb@GMwqN6EqC zn-vHfM;OZ0F0L1P6y^9E&Yu=cI@|w1ck%A? zZgZ}HQ&{u!;=ku#8`DCw9v3&@wyNI(bya>!smolTXZc{HMh`C`HZK3?&ZyUFCus81 zx&BJgAE>?umO3tH({-qu)UWPeT&yompX)x>2zZRC)+%8x|K9gPT^SD^;Fs~6)=A?W zb@3xl^XsFsR-Ce4Z}oRM7*86mU|A2atUr#3?W1Iq3#x)!=?r`UtvWlpy61O(=Ptzp z>fg$WD)yEcj7um~;7sN0fDd8ePPuv5Gup7~+EPv8qY2AS!9YXj+?k18Q4jA|9N}D9 z^^bdJ%kJx2)ej#~F6ojQQ7t9!#|yu33O7y zWcr&|_h~IG93X>!*Q(!KDfgvxd$Vaaw*`QDZG+8v@07T@bC6x`rObJyP z=m1B;Dv)iUL}|S&lusFC*`@YiKKnoCjk64;2b0CMTLroC0-uAMJ^2nDBA?+Kvx+ox&g+!;m1@un|p)lr;Af)e4~U=FR}V(TI^*jinG?HfEpjDNzB#Hw0q%HkBL&#LE68zY6^X z0LXwDB4(K(Rw{8MtXPTCG>^CR$>uTw0J?NQ=MZQ}{G~1L>@4BFF@%K+&^|b7W36*D z&@H8}78jc6x<)-6kbtg;E7hIC1Ohe{xezKwfQGf_8Ce3PMuGl+*^7lD+`HXZJLxwO zbb#H*>=ajBJp%>nO#bbv5HgU>!vP~zAdY^gStNo2?veyl$Si?E^uX0paiG4C*qJl5 zNyB^ttpi~DSRJw@mYMi_U2zF%1O_2Q=fO2?ZI!zGEM zFLk3RGH`n%M89p}aJuV0+zlxMDphOly)`g{I5#BuGfJ;7(ImR-CvY9mW` zSlBRcD3f_j>Z~{aMxMNtkEvcvw)&K^?!Ke}QtY-S8=GiPeun&wYr za1GbS^_|>@R{Z|Ke(m#&H~1F&^r`D%vpbbkJ52bL97C{?SK#=YJK< z-NnssPPf# z+WpLe2&OzD1{lC6`l(wrwzHir;-S#;uuMh*)vL3B0?r%~)RZ{$eOHj^AW%-|!E?21 zm;s)Q~l7z88{GqfI}J=`FH?*nN*2}R4^G(Z%hh>Z^(fQCo>>sX)jAFyYr!x zu)-V+LUtwwFy$2qXo%_)j~z6^!ka~6E2=95L;0aqNK~!4CnD zQe3F7vMZdYz2F4F_2SLh&Z$PW1h9jU3DjVN9wLnj;SahZkhvN%Fdzc`&$B;;SyGxs zX$7g-prorCB9kFZJ=(7fQm-xH=4y+}04G@iK+83%=#YLE^9fx`mS)7&>r5`nMGb%^ zZWD_jI4I=A@U<*JXseV09&}1@KOIxWS*HDvZ)~LMY`EmtWLPyA&PQpQ0+5wywA2wp zO*j}ravT{T#~9$s5t>OADkv?Gf#5L+$R=Vwr2U|mNmXTK;k%<+cU0B!4=m+#Qw?q(tVdBnI`x&>cPP%H78Y~8= zDEBAuAnj%!xLPcIDYf1XIsceMXXP542ZeW_1>1w5vdc+BMnIU2kfg+78L=32nT-$u zv3#wP4DnMAGGZW}R5#5VmJ+dY4iwZUG;cy1>QcZMDimmH(fErrpcT$hF$MljnPBL2 ze^WeG28iXRRBZ~#x!?fEk0+=YYSdbZ;vt->2VsS@!N{yFRgzW!#o|4HzXDQS<~Rf7 zV=}>Zxxz}sIT@SR@*rqU4TaF3aN4f?1{*pQ?`)*1&rpQ^d|jB;knvG$Y_)E~atN*q zmdyeAa|skMC)x<~8NQ8lAYP7Y6znJB-npx!PzbB!GGdv5)>H7KCb<%T4yZQJ)u?PU zwzFM-G6%S%cs50+O6+m(+`zX2eoaAOAen@Q&e6?eL`)SJqDH8yQO~f7a@9e=0lt9T z-)^-Y5P+4{g8LKP2&-c3$PrZcb94y!u!z~7XCB20g$kfQQdzD2kh|n+_3wnEi1o%r zKgkus_9q5Sa=?9Et<$SHzgcX*4Y_Fu$SK;U< zbkNg^&B|RyA!@yKRRHG&bQmnNJUoR8V7^XU9*g6fP$5Lb1W}(EU}qk))OwLQiei4d zO#=YAoFg*jhA2*eC#k^;syP!h&U^%)a(Kc#Z|qtQ)gAb^^>?XEM$KePG_8 zStorXx+{z74lIxYK&PF0@FFUO?V${5aFik%8%#;vLRf6I_5+Y)*{Y&JLJ$SidILaf zr&M@AE1cWxs?hDO>D8I^kOS$|&@uhV>Y3egG{kMAo0<_bNyFg9v|EYf8N;l49!Pz{ zmuL}sY|OBTt~TbR0Z$`$Scv-Rt0@Ha=?sk#GT^D0cd@Z(O1w>qB7`8+QoWK?KPBXY z&BTmNa{{;q1X@&BZrXKbL`Viub)s*SbS6-pE#1I#NP*!R)}Tb-0J%oE18)~~!Fdk|c~H}A#%;t>6o^oUOe)Uf_}ffCh_&)f zX{_fmjckB$eYbmxd&B^m%TN-+Mhro~*T)Rxf({x977lh*XX0fn7F3}Ph7i6X2_;gr z1etlnnMc2B(Iw(|FAG-%zsU@Ek%w7Kyc z`J|E5tz2QhNcaZEDTHI zl@0KRh@uz}>ijV1Ahn2fZ08P8xXDX(YLdG|ED1r;%)V}#J1Vi4gV0DFCuvAqKr!V7 z5<{pOo(axm3dkBEw?VRnA{ONLi$D`O&C)H6>UPJzg$@Hs{;`fsTsAkRg|5Z+zZ9Mo zk~xY&LpdVg2CChR0$JHK2UMI^Lenq~{F{)Ls$K~$&jGNhd2oozwn?FaJD#wrA)E{H zNkEV}zY&zm&Rs2Z(_;N(Nhf107JQ3TM8`~WCZEt%q6<Yz6u8fG>MJ{9#v`Am#S_eW`GUmC!0-L(NHR=I!|AAGHEK)04-h!-pYdlq&Ct6 z5Nd&Jp`=Y3P`45>n92|!6AWm}BSb*}lvpqvG6kT&jRb^b^-6Tgf|HH|5(xICbT%b9FR1C2ugI45`bh7z?B9E_9$o*04k)C9QV{aj|8)% zc|h;G*&qcnuTce|JKq5kx5T!@L)ckS5U5%jOhG#kq&U{4jSaZL>5M@Tp=aHiPl-CvNKTyLUXgZ#hm4USAw5y&ZMiCNZ6jI0x5Q7WRS=j zJO%9~HSoDSEkoEdoReY0u5gZf`a6Ph4Y(0HFd6tBNASZhhi9OlB!YeqRht|jweK3w zVncr59|B^e_HDq36~=6)Up69v&rns*90w;Tw08t$d{?vp%Ef@#PK`&Rf;p4;Yg&Uab09{<*OfT~KS|WNBzM}zpAMF; zaF9EOT_O!T{&0mkHpSRWX28QZ%juV4JS``!C5o1X8yE!w6Tj7hgJ9)Z>;qtH7{YKi xpkiM7U_%K(*=>ky8^Gc#BrUW-m&|G?&XVfQe;`FKAlt+&NO5bs3&70p{|ovTtbhOj literal 0 HcmV?d00001 diff --git a/website/docs/engine-flink/deltajoins.md b/website/docs/engine-flink/delta-joins.md similarity index 73% rename from website/docs/engine-flink/deltajoins.md rename to website/docs/engine-flink/delta-joins.md index 7c175d405b..1b659dacb2 100644 --- a/website/docs/engine-flink/deltajoins.md +++ b/website/docs/engine-flink/delta-joins.md @@ -5,17 +5,21 @@ sidebar_position: 6 --- # The Delta Join -Beginning with **Apache Flink 2.1**, a new operator called **Delta Join** was introduced. +Beginning with **Apache Flink 2.1**, a new operator called [Delta Join](https://cwiki.apache.org/confluence/display/FLINK/FLIP-486%3A+Introduce+A+New+DeltaJoin) was introduced. Compared to traditional streaming joins, the delta join operator significantly reduces the amount of state that needs to be maintained during execution. This improvement helps mitigate several common issues associated with large state sizes, including: - Excessive computing resource and storage consumption - Long checkpointing durations - Extended recovery times after failures or restarts +- Heavy state bootstrap overhead after changing job logic Starting with **Apache Fluss 0.8**, streaming join jobs running on **Flink 2.1 or later** will be automatically optimized into **delta joins** whenever applicable. This optimization happens transparently at query planning time, requiring no manual configuration. ## How Delta Join Works -Traditional streaming joins in Flink require maintaining both input sides entirely in state to match records across streams. Delta join, by contrast, uses a **prefix-based lookup mechanism** to transform the behavior of querying data from the state into querying data from the Fluss source table, thereby avoiding redundant storage of the same data in both the Fluss source table and the state. This drastically reduces state size and improves performance for many streaming analytics and enrichment workloads. + +Traditional streaming joins in Flink require maintaining both input sides entirely in state to match records across streams. Delta join, by contrast, uses a **index-key lookup mechanism** to transform the behavior of querying data from the state into querying data from the Fluss source table, thereby avoiding redundant storage of the same data in both the Fluss source table and the state. This drastically reduces state size and improves performance for many streaming analytics and enrichment workloads. + +![](../assets/delta_join.jpg) ## Example: Delta Join in Flink 2.1 @@ -70,7 +74,7 @@ CREATE TABLE `fluss_catalog`.`my_db`.`snk` ( `content` VARCHAR NOT NULL, `city_name` VARCHAR NOT NULL, PRIMARY KEY (city_id, order_id) NOT ENFORCED -) WITH (...); +); ``` #### Explain the Join Query @@ -112,14 +116,21 @@ Sink(table=[fluss_catalog.my_db.snk], fields=[city_id, order_id, content, city_n +- TableSourceScan(table=[[fluss_catalog, my_db, right_src]], fields=[city_id, city_name]) ``` -## Understanding Prefix Keys +## Understanding Index Keys + +Delta Join relies on performing lookups by the join key (e.g., the `city_id` in the above example) on the Fluss source tables. This requires that the Fluss source tables are defined with appropriate index on the join key to enable efficient lookups. + +Currently, Fluss only supports to defines a single index key per table, which is also referred to as the **prefix key**. The general secondary index which allows define multiple indexes with arbitrary fields is planned to be supported in the near future releases. + A prefix key defines the portion of a table’s primary key that can be used for efficient key-based lookups or index pruning. In Fluss, the option `'bucket.key' = 'city_id'` specifies that data is organized (or bucketed) by `city_id`. When performing a delta join, this allows Flink to quickly locate and read only the subset of records corresponding to the specific prefix key value, rather than scanning or caching the entire table state. For example: - Full primary key: `(city_id, order_id)` -- Prefix key: `city_id` +- Bucket key: `city_id` + +This yields an **index** on the prefix key `city_id`, so that you can perform [Prefix Key Lookup](/docs/engine-flink/lookups/#prefix-lookup) by the `city_id`. In this setup: * The delta join operator uses the prefix key (`city_id`) to retrieve only relevant right-side records matching each left-side event. @@ -129,9 +140,9 @@ Prefix keys thus form the foundation for efficient lookups in delta joins, enabl ## Flink Version Support -The delta join feature is still evolving, and its optimization capabilities vary across Flink versions. +The delta join feature is introduced since Flink 2.1 and still evolving, and its optimization capabilities vary across Flink versions. -Refer to the [Delta Join](https://issues.apache.org/jira/browse/FLINK-37836) for the most up-to-date information. +Refer to the [Delta Join Issue](https://issues.apache.org/jira/browse/FLINK-37836) for the most up-to-date information. ### Flink 2.1 @@ -148,3 +159,11 @@ Refer to the [Delta Join](https://issues.apache.org/jira/browse/FLINK-37836) for - All join inputs should be INSERT-ONLY streams. - This is why the option `'table.merge-engine' = 'first_row'` is added to the source table DDL. - All upstream nodes of the join should be `TableSourceScan` or `Exchange`. + +## Future Plan + +The Fluss and Flink community are actively working together on enhancing delta join. Planned improvements include: +- Support for additional join types, such as LEFT JOIN and FULL OUTER JOIN. +- Support for multi-way joins involving more than two streams. This also requires Fluss to support defining multiple secondary index keys on a single table. +- Support for more complex query patterns, including Calc and LookupJoin nodes. +- Relaxation of restrictions on input stream types, allowing for changelog streams. \ No newline at end of file From 0d5a7baa3be1beffc617c110d1b3df7d15dfa204 Mon Sep 17 00:00:00 2001 From: Jark Wu Date: Sun, 2 Nov 2025 19:57:22 +0800 Subject: [PATCH 5/5] add Flink 2.2 --- website/docs/engine-flink/delta-joins.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/website/docs/engine-flink/delta-joins.md b/website/docs/engine-flink/delta-joins.md index 1b659dacb2..8304ac39e8 100644 --- a/website/docs/engine-flink/delta-joins.md +++ b/website/docs/engine-flink/delta-joins.md @@ -149,7 +149,7 @@ Refer to the [Delta Join Issue](https://issues.apache.org/jira/browse/FLINK-3783 #### Supported Features -- Support for optimizing a dual-stream join in the straightforward pattern of "insert only source -> join -> upsert sink" into a delta join. +- Support for optimizing a dual-stream join in the straightforward pattern of `insert only source -> join -> upsert sink` into a delta join. #### Limitations @@ -160,10 +160,27 @@ Refer to the [Delta Join Issue](https://issues.apache.org/jira/browse/FLINK-3783 - This is why the option `'table.merge-engine' = 'first_row'` is added to the source table DDL. - All upstream nodes of the join should be `TableSourceScan` or `Exchange`. +### Flink 2.2 (upcoming) + +#### Supported Features + +- Support for optimizing a dual-stream join from CDC sources that do not include delete messages into a delta join. + - Disable delete on the source table to guarantee there is no delete message in the table, by adding the option `'table.delete.behavior' = 'IGNORE'` or `'DISABLE'` on the table. + - The source table is no more required to be a `first_row` merge engine table since this version. +- Support `Project` and `Filter` between source and delta join. +- Support cache in delta join. + +#### Limitations + +- The primary key or the prefix lookup key of the tables must be included as part of the equivalence conditions in the join. +- The join must be a INNER join. +- The downstream nodes of the join can accept duplicate changes, such as a sink that provides UPSERT mode. +- When consuming a CDC stream, the join key used in the delta join must be part of the primary key. +- All filters must be applied on the upsert key, and neither filters nor projections should contain non-deterministic functions. + ## Future Plan The Fluss and Flink community are actively working together on enhancing delta join. Planned improvements include: - Support for additional join types, such as LEFT JOIN and FULL OUTER JOIN. - Support for multi-way joins involving more than two streams. This also requires Fluss to support defining multiple secondary index keys on a single table. -- Support for more complex query patterns, including Calc and LookupJoin nodes. -- Relaxation of restrictions on input stream types, allowing for changelog streams. \ No newline at end of file +- Support for more complex query patterns to optimize a wider range of join scenarios. \ No newline at end of file