Re: [讨论] Flink Connector 并行写入数据方案

2021-03-31 文章 Shengkai Fang
Hi jie.

User mail list 更多是用来讨论使用中的问题,请将关于dev相关的问题转发到d...@flink.apache.org

详情可以参考[1]

[1] https://flink.apache.org/community.html

jie mei  于2021年3月31日周三 下午3:03写道:

> Hi, Community
>
> 我想发起一个初步的讨论,关于如何扩大 Flink 写入数据的并行度,并且能够分表,可选事务支持的方案。
>
> 该方案应该支持三种场景:
>
> 1) 至少一次: 不支持或者有限支持 update 的存储,通常通过查询去重。 例如 ClickHouse
> 2) 相同主键或分区内有序: 支持 Upsert,但不支持事务或者跨行事务的存储,例如 ElasticSearch, MongoDB
> 3) 事务:支持跨行事务的存储,例如 MySQL。
>
> 另外说一下,第二种情况和第三种情况的一个重要区别是,当 CheckPoint 失败,第二种情况会从上一个快照重新执行,
> 那么会存在旧的数据可能覆盖新的数据的情况。举个例子: 假设正常情况下记录A在某个快照区间取值为
> A1, A2, A3。假如在写入 A2 后快照失败,当重新执行的时候,会短暂的存在这种情况,A1 覆盖了 A2 的值。
>
> 下面是不同场景扩大并行度的方案
> 1) 至少一次:
> 在这种场景下,数据乱顺是可容忍的,只要保证最少一次,就能达到最终一致性。可以考虑多线程异步写入数据,
> 当异步任务过多,则等待有异步任务完成,再执行新的异步写入任务。CheckPoint需要保证所有异步任务完成
>
> 2) 相同主键或分区内有序,最少一次:
> 在这种场景下,如果指定了分区字段,可以将相同分区的数据放到一个 Buffer 里,相同 Buffer 的数据有序,
> 不同 Buffer的数据并行写入,CheckPoint的时候需要保证所有数据写入;如果没有分区,单指定了主键,可以
> 根据主键的 Hash Code 对 Sink 并行读取模,得到的值用于决定数据缓存到哪一个 Buffer,同样相同的 Buffer
> 内有序,不同的 Buffer 并行。
>
> 3) 事务:
> 由于已经有了通用的 Sink API,可以考虑把数据缓存到 Buffer, 在 CheckPoint 的时候,开启事务,完成写入数据,并提交。
> [FLIP-143]
>
> https://cwiki.apache.org/confluence/display/FLINK/FLIP-143%3A+Unified+Sink+API
>
> 分表:
> 对于 MySQL, MongoDB 这类存储,可以通过分区键来定义分表规则,假如表 A 定义了分区键 B,B 有 B1, B2 两个取值,
> 那么得到两个分表 A_B1, A_B2.
>
>
> --
>
> *Best Regards*
> *Jeremy Mei*
>


[讨论] Flink Connector 并行写入数据方案

2021-03-31 文章 jie mei
Hi, Community

我想发起一个初步的讨论,关于如何扩大 Flink 写入数据的并行度,并且能够分表,可选事务支持的方案。

该方案应该支持三种场景:

1) 至少一次: 不支持或者有限支持 update 的存储,通常通过查询去重。 例如 ClickHouse
2) 相同主键或分区内有序: 支持 Upsert,但不支持事务或者跨行事务的存储,例如 ElasticSearch, MongoDB
3) 事务:支持跨行事务的存储,例如 MySQL。

另外说一下,第二种情况和第三种情况的一个重要区别是,当 CheckPoint 失败,第二种情况会从上一个快照重新执行,
那么会存在旧的数据可能覆盖新的数据的情况。举个例子: 假设正常情况下记录A在某个快照区间取值为
A1, A2, A3。假如在写入 A2 后快照失败,当重新执行的时候,会短暂的存在这种情况,A1 覆盖了 A2 的值。

下面是不同场景扩大并行度的方案
1) 至少一次:
在这种场景下,数据乱顺是可容忍的,只要保证最少一次,就能达到最终一致性。可以考虑多线程异步写入数据,
当异步任务过多,则等待有异步任务完成,再执行新的异步写入任务。CheckPoint需要保证所有异步任务完成

2) 相同主键或分区内有序,最少一次:
在这种场景下,如果指定了分区字段,可以将相同分区的数据放到一个 Buffer 里,相同 Buffer 的数据有序,
不同 Buffer的数据并行写入,CheckPoint的时候需要保证所有数据写入;如果没有分区,单指定了主键,可以
根据主键的 Hash Code 对 Sink 并行读取模,得到的值用于决定数据缓存到哪一个 Buffer,同样相同的 Buffer
内有序,不同的 Buffer 并行。

3) 事务:
由于已经有了通用的 Sink API,可以考虑把数据缓存到 Buffer, 在 CheckPoint 的时候,开启事务,完成写入数据,并提交。
[FLIP-143]
https://cwiki.apache.org/confluence/display/FLINK/FLIP-143%3A+Unified+Sink+API

分表:
对于 MySQL, MongoDB 这类存储,可以通过分区键来定义分表规则,假如表 A 定义了分区键 B,B 有 B1, B2 两个取值,
那么得到两个分表 A_B1, A_B2.


-- 

*Best Regards*
*Jeremy Mei*