对于Apache Flink的使用,我试图从Microsoft SQL数据库中给出的数据创建一个DataSet。 test_table有两列,“数字”和“字符串”,分别包含INT和VARCHAR。
// supply row type info
TypeInformation<?>[] fieldTypes = new TypeInformation<?>[] {
BasicTypeInfo.INT_TYPE_INFO,
BasicTypeInfo.CHAR_TYPE_INFO,
};
RowTypeInfo rowTypeInfo = new RowTypeInfo(fieldTypes);
// create and configure input format
JDBCInputFormat inputFormat = JDBCInputFormat.buildJDBCInputFormat()
.setDrivername("com.microsoft.sqlserver.jdbc.SQLServerDriver")
.setDBUrl(serverurl)
.setUsername(username)
.setPassword(password)
.setQuery("SELECT numbers, strings FROM test_table")
.setRowTypeInfo(rowTypeInfo)
.finish();
// create and configure type information for DataSet
TupleTypeInfo typeInformation = new TupleTypeInfo(Tuple2.class, BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO);
// Read data from a relational database using the JDBC input format
DataSet<Tuple2<Integer, String>> dbData = environment.createInput(inputFormat, typeInformation);
// write to sink
dbData.print();
执行时,会发生以下错误,并且不会创建输出。
Exception in thread "main" org.apache.flink.runtime.client.JobExecutionException: Job execution failed.
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply$mcV$sp(JobManager.scala:714)
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply(JobManager.scala:660)
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply(JobManager.scala:660)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:401)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.NullPointerException
at org.apache.flink.api.java.io.jdbc.JDBCInputFormat.open(JDBCInputFormat.java:231)
at org.apache.flink.runtime.operators.DataSourceTask.invoke(DataSourceTask.java:147)
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:559)
at java.lang.Thread.run(Thread.java:745)
这让我没有真正的线索在哪里以及如何寻找解决方案。奇怪的是,在我将Flink JDBC版本从0.10.2更改为1.1.3之前,这段代码工作正常。旧版本不需要RowTypeInfo部分,这意味着它可能检查了类型本身?但除了将其添加到代码之外,没有任何改变。
然后,它可能与RowTypeInfo有关。我尝试过改变它们,例如使用BasicTypeInfo.CHAR_TYPE_INFO
而不是BasicTypeInfo.STRING_TYPE_INFO
(因为列是VARCHAR列),但错误仍然存在。
理想情况下,我想修复NullPointer问题并继续使用包含数据库信息的DataSet。考虑到缺少文档/教程和(工作)示例,我还提出了一个更普遍的问题:尝试在Flink中处理SQL数据是一个好主意,还是仅仅意味着它?截至目前,我开始认为创建一个从数据库读取的例程,并在启动Flink作业之前将其内容保存到CSV文件中,虽然没有其他任何其他方法,但可能更容易。