无法使用相同标识符对表进行分区时,如何在 Flink 中组织数据流
How to organize the flow of data in Flink when tables can't be partitioned using the same identifier
我确信 Flink 是解决我的事件处理问题的完美方案。我什至设法制作了一个工作原型,但我不相信它甚至接近最佳。
这是我的场景:
- 我有两个运动流
- 一个流包含
Event1
并存储为 JSON
- 另一个流包含
Event2
、Event3
和 Event4
,但存储为 Gzip'd Base64(最终也是 JSON
)。我必须使用 RAW
格式处理它,然后使用自定义 UDF process_events234
提取事件数据 - 通过在 Scala class.[=62= 中实现 TableFunction[Row]
创建]
- 我想检测 4 个相应事件何时到达,但没有一个值可以用来连接事件代表的所有 4 种数据类型。见下文:
Data Type
Has key1
Has key2
Event1
Yes
No
Event2
Yes
Yes
Event3
No
Yes
Event4
No
Yes
我的原型笔记本有以下内容:
为event_1s
定义一个table
CREATE TABLE event_1 (
key1,
...
)
WITH (
'connector' = 'kinesis',
'stream' = 'stream_of_event_1s',
...
'format' = 'json'
)
为event_1,2,3s
定义一个table
CREATE TABLE events_234 (
Data BYTES
)
WITH (
'connector' = 'kinesis',
'stream' = 'stream_of_event_1_2_3s',
...
'format' = 'raw'
)
创建一个视图来分隔每个事件 2,3,4
CREATE VIEW event_N // Where N is 2,3,4
AS
SELECT
p.*
FROM
events_234 e
JOIN LATERAL table(process_events234(e.Data)) as p ON TRUE
WHERE
p.eventType = 'eventN' // Where N is 2,3,4
将数据合并在一起得到我的结果
/*INSERT INTO my_downstream_sink */
SELECT
e1.*, e2.*, e3.*, e4.*
FROM
event_1 e1
INNER JOIN event_2 e2 ON e1.key1 = e2.key1
INNER JOIN event_3 e3 ON e2.key2 = e3.key2
INNER JOIN event_4 e4 ON e2.key2 = e4.key2
我当前的原型可以在 10 分钟内处理数百条记录,但我怀疑它是否能够扩展。让我担心的是,我无法 partition
/keyBy
数据,以至于我认为它会存在于同一个工人身上。我是Flink新手,但是这个好像特别重要
我想到的是扩展步数和运动流,这样:
- 我加入了 Event1 和 Event2,然后将其插入到新的流
Event1+Event2
中,由 key2
分区
- 然后加入
Event1+Event2
和 Event3
, Event4
不过,我只是在猜测,希望得到专家的建议和意见。谢谢!
我不会担心; Flink 的 SQL planner/optimizer 应该可以很好地处理这个问题。
您可能会发现使用 EXPLAIN and/or 在 Flink Web 仪表板中查看生成的作业图以更清楚地了解查询的执行方式很有用。我相信您会发现它完全按照您的建议进行(创建 Event1+Event2
流,通过 key2
对其进行键控,然后与其他流连接)而无需编写 Event1+Event2
流出到 Kinesis 并再次读入。
我确信 Flink 是解决我的事件处理问题的完美方案。我什至设法制作了一个工作原型,但我不相信它甚至接近最佳。
这是我的场景:
- 我有两个运动流
- 一个流包含
Event1
并存储为JSON
- 另一个流包含
Event2
、Event3
和Event4
,但存储为 Gzip'd Base64(最终也是JSON
)。我必须使用RAW
格式处理它,然后使用自定义 UDFprocess_events234
提取事件数据 - 通过在 Scala class.[=62= 中实现TableFunction[Row]
创建]
- 一个流包含
- 我想检测 4 个相应事件何时到达,但没有一个值可以用来连接事件代表的所有 4 种数据类型。见下文:
Data Type | Has key1 | Has key2 |
---|---|---|
Event1 | Yes | No |
Event2 | Yes | Yes |
Event3 | No | Yes |
Event4 | No | Yes |
我的原型笔记本有以下内容:
为event_1s
定义一个tableCREATE TABLE event_1 (
key1,
...
)
WITH (
'connector' = 'kinesis',
'stream' = 'stream_of_event_1s',
...
'format' = 'json'
)
为event_1,2,3s
定义一个tableCREATE TABLE events_234 (
Data BYTES
)
WITH (
'connector' = 'kinesis',
'stream' = 'stream_of_event_1_2_3s',
...
'format' = 'raw'
)
创建一个视图来分隔每个事件 2,3,4
CREATE VIEW event_N // Where N is 2,3,4
AS
SELECT
p.*
FROM
events_234 e
JOIN LATERAL table(process_events234(e.Data)) as p ON TRUE
WHERE
p.eventType = 'eventN' // Where N is 2,3,4
将数据合并在一起得到我的结果
/*INSERT INTO my_downstream_sink */
SELECT
e1.*, e2.*, e3.*, e4.*
FROM
event_1 e1
INNER JOIN event_2 e2 ON e1.key1 = e2.key1
INNER JOIN event_3 e3 ON e2.key2 = e3.key2
INNER JOIN event_4 e4 ON e2.key2 = e4.key2
我当前的原型可以在 10 分钟内处理数百条记录,但我怀疑它是否能够扩展。让我担心的是,我无法 partition
/keyBy
数据,以至于我认为它会存在于同一个工人身上。我是Flink新手,但是这个好像特别重要
我想到的是扩展步数和运动流,这样:
- 我加入了 Event1 和 Event2,然后将其插入到新的流
Event1+Event2
中,由key2
分区
- 然后加入
Event1+Event2
和Event3
,Event4
不过,我只是在猜测,希望得到专家的建议和意见。谢谢!
我不会担心; Flink 的 SQL planner/optimizer 应该可以很好地处理这个问题。
您可能会发现使用 EXPLAIN and/or 在 Flink Web 仪表板中查看生成的作业图以更清楚地了解查询的执行方式很有用。我相信您会发现它完全按照您的建议进行(创建 Event1+Event2
流,通过 key2
对其进行键控,然后与其他流连接)而无需编写 Event1+Event2
流出到 Kinesis 并再次读入。