Apache Flink:将DataStream写入Postgres表

时间:2017-07-19 10:10:21

标签: apache-flink flink-streaming

我正在尝试编写一个将数据流汇入postgres表的流式作业。为了提供完整的信息,我的工作基于文章:https://tech.signavio.com/2017/postgres-flink-sink,它建议使用JDBCOutputFormat。

我的代码如下所示:

98     ... 
99     String strQuery = "INSERT INTO public.alarm (entity, duration, first, type, windowsize) VALUES (?, ?, ?, 'dur', 6)";
100
101     JDBCOutputFormat jdbcOutput = JDBCOutputFormat.buildJDBCOutputFormat()
102      .setDrivername("org.postgresql.Driver")
103      .setDBUrl("jdbc:postgresql://localhost:5432/postgres?user=michel&password=polnareff")
104      .setQuery(strQuery)
105      .setSqlTypes(new int[] { Types.VARCHAR, Types.INTEGER, Types.VARCHAR}) //set the types
106      .finish();
107
108     DataStream<Row> rows = FilterStream
109                 .map((tuple)-> {
110                    Row row = new Row(3);                  // our prepared statement has 3 parameters
111                    row.setField(0, tuple.f0);             // first parameter is case ID
112                    row.setField(1, tuple.f1);             // second paramater is tracehash
113                    row.setField(2, f.format(tuple.f2));   // third paramater is tracehash
114                    return row;
115                 });
116
117     rows.writeUsingOutputFormat(jdbcOutput);
118
119     env.execute();
120
121     }
122 }

我现在的问题是,只有当我的作业停止时才会插入值(确切地说,当我从apache flink仪表板取消作业时)。

所以我的问题如下:我错过了什么吗?我应该在某处插入我插入的行吗?

祝你好运, 伊格

2 个答案:

答案 0 :(得分:2)

正如Chesnay在his comment中所说,你必须调整批处理间隔。

然而,这不是完整的故事。如果要实现至少一次结果,则必须使用Flink的检查点同步批量写入。基本上,您必须将JdbcOutputFormat包装在同样实现SinkFunction接口的CheckpointedFunction中。调用snapshotState()时,您已将批处理写入数据库。您可以查看将在下一版本中提供此功能的pull request

答案 1 :(得分:1)

Fabian的答案是实现至少一次语义的一种方法;通过将写入与Flink的检查点同步。但是,这样做的缺点是,您的Sink的数据新鲜度现在已经严格到您的检查点间隔周期。

作为替代方案,您可以在Flink自己的托管状态中存储具有(实体,持续时间,第一)字段的元组或行,以便Flink负责检查点(换句话说,使您的Sink的状态容错)。为此,您实现了CheckpointedFunction和CheckpointedRestoring接口(无需将您的写入与检查点同步。如果您不必使用JDBCOutputFormat,您甚至可以单独执行SQL插入)。见:https://ci.apache.org/projects/flink/flink-docs-release-1.3/dev/stream/state.html#using-managed-operator-state。另一个解决方案是仅实现ListCheckpointed接口(可以使用与已弃用的CheckpointedRestoring接口类似的方式,并支持列表式状态重新分配)。