Apache Flink 1.3表api rowtime奇怪的行为

时间:2017-06-09 01:43:24

标签: apache-flink

以下代码示例在1.3

中不起作用
public class TumblingWindow {

    public static void main(String[] args) throws Exception {
        List<Content> data = new ArrayList<Content>();
        data.add(new Content(1L, "Hi"));
        data.add(new Content(2L, "Hallo"));
        data.add(new Content(3L, "Hello"));
        data.add(new Content(4L, "Hello"));
        data.add(new Content(7L, "Hello"));
        data.add(new Content(8L, "Hello world"));
        data.add(new Content(16L, "Hello world"));

        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

        final StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env);

        DataStream<Content> stream = env.fromCollection(data);

        DataStream<Content> stream2 = stream.assignTimestampsAndWatermarks(
                new BoundedOutOfOrdernessTimestampExtractor<Content>(Time.milliseconds(1)) {

                    /**
                     * 
                     */
                    private static final long serialVersionUID = 410512296011057717L;

                    @Override
                    public long extractTimestamp(Content element) {
                        return element.getRecordTime();
                    }

                });

        Table table = tableEnv.fromDataStream(stream2,
                "urlKey,httpGetMessageCount,httpPostMessageCount" + ",uplink,downlink,statusCode,statusCodeCount,rowtime.rowtime");
        table.window(Tumble.over("1.hours").on("rowtime").as("w")).groupBy("w, urlKey")
                .select("w.start,urlKey,uplink.sum,downlink.sum,httpGetMessageCount.sum,httpPostMessageCount.sum ");

        env.execute();
    }

    public static class Content implements Serializable {

        private String urlKey;

        private long recordTime;
        // private String recordTimeStr;

        private long httpGetMessageCount;
        private long httpPostMessageCount;
        private long uplink;
        private long downlink;
        private long statusCode;
        private long statusCodeCount;

        public Content() {
            super();
        }

        public Content(long recordTime, String urlKey) {
            super();
            this.recordTime = recordTime;
            this.urlKey = urlKey;
        }

        public String getUrlKey() {
            return urlKey;
        }

        public void setUrlKey(String urlKey) {
            this.urlKey = urlKey;
        }

        public long getRecordTime() {
            return recordTime;
        }

        public void setRecordTime(long recordTime) {
            this.recordTime = recordTime;
        }

        public long getHttpGetMessageCount() {
            return httpGetMessageCount;
        }

        public void setHttpGetMessageCount(long httpGetMessageCount) {
            this.httpGetMessageCount = httpGetMessageCount;
        }

        public long getHttpPostMessageCount() {
            return httpPostMessageCount;
        }

        public void setHttpPostMessageCount(long httpPostMessageCount) {
            this.httpPostMessageCount = httpPostMessageCount;
        }

        public long getUplink() {
            return uplink;
        }

        public void setUplink(long uplink) {
            this.uplink = uplink;
        }

        public long getDownlink() {
            return downlink;
        }

        public void setDownlink(long downlink) {
            this.downlink = downlink;
        }

        public long getStatusCode() {
            return statusCode;
        }

        public void setStatusCode(long statusCode) {
            this.statusCode = statusCode;
        }

        public long getStatusCodeCount() {
            return statusCodeCount;
        }

        public void setStatusCodeCount(long statusCodeCount) {
            this.statusCodeCount = statusCodeCount;
        }

    }

    private class TimestampWithEqualWatermark implements AssignerWithPunctuatedWatermarks<Object[]> {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        @Override
        public long extractTimestamp(Object[] element, long previousElementTimestamp) {
            // TODO Auto-generated method stub
            return (long) element[0];
        }

        @Override
        public Watermark checkAndGetNextWatermark(Object[] lastElement, long extractedTimestamp) {
            return new Watermark(extractedTimestamp);
        }

    }
}

将引发以下异常

Exception in thread "main" org.apache.flink.table.api.TableException: The rowtime attribute can only be replace a field with a valid time type, such as Timestamp or Long.
    at org.apache.flink.table.api.StreamTableEnvironment$$anonfun$validateAndExtractTimeAttributes$1.apply(StreamTableEnvironment.scala:450)
    at org.apache.flink.table.api.StreamTableEnvironment$$anonfun$validateAndExtractTimeAttributes$1.apply(StreamTableEnvironment.scala:440)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
    at org.apache.flink.table.api.StreamTableEnvironment.validateAndExtractTimeAttributes(StreamTableEnvironment.scala:440)
    at org.apache.flink.table.api.StreamTableEnvironment.registerDataStreamInternal(StreamTableEnvironment.scala:401)
    at org.apache.flink.table.api.java.StreamTableEnvironment.fromDataStream(StreamTableEnvironment.scala:88)
    at com.taiwanmobile.cep.noc.TumblingWindow.main(TumblingWindow.java:53)

但是如果我在fromDataStream中删除statusCodeCount,则此示例将成功运行而不会出现Exception。

Table table = tableEnv.fromDataStream(stream2,
                "urlKey,httpGetMessageCount,httpPostMessageCount" + ",uplink,downlink,statusCode,statusCodeCount,rowtime.rowtime");
        table.window(Tumble.over("1.hours").on("rowtime").as("w")).groupBy("w, urlKey")
                .select("w.start,urlKey,uplink.sum,downlink.sum,httpGetMessageCount.sum,httpPostMessageCount.sum ");

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

这是以FLINK-6881提交的错误。作为一种变通方法,您可以定义自己的StreamTableSource来实现DefinedRowtimeAttribute(另请参阅this documentation draft)。表源也很好地隐藏了底层的DataStream API,使表程序更加紧凑。