Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在dataflow runner中运行管道时,有时会获取IllegalStateException_Java_Google Cloud Platform_Google Cloud Dataflow_Illegalstateexception - Fatal编程技术网

Java 在dataflow runner中运行管道时,有时会获取IllegalStateException

Java 在dataflow runner中运行管道时,有时会获取IllegalStateException,java,google-cloud-platform,google-cloud-dataflow,illegalstateexception,Java,Google Cloud Platform,Google Cloud Dataflow,Illegalstateexception,(5d8e3f411b5a4ccb):java.lang.IllegalStateException:TimestampCombiner将窗口的元素从2017-09-25T13:53:08.725Z移动到更早的2017-09-25T13:53:08.718Z[2017-09-25T13:53:08.088Z..2017-09-25T13:53:08.719Z) 预期的原因是什么 WindowFn代码很简单: public class BQTablePartitionWindowFn extend

(5d8e3f411b5a4ccb):java.lang.IllegalStateException:TimestampCombiner将窗口的元素从2017-09-25T13:53:08.725Z移动到更早的2017-09-25T13:53:08.718Z[2017-09-25T13:53:08.088Z..2017-09-25T13:53:08.719Z)

预期的原因是什么

WindowFn代码很简单:

public class BQTablePartitionWindowFn extends NonMergingWindowFn<Object, IntervalWindow> {

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

private IntervalWindow assignWindow(AssignContext context) {
    TableRow tableRow = (TableRow) context.element();
    String timestamp = tableRow.get(BQConstants.LOG_TIME).toString();
    String currentTime = DateUtil.getFormatedDate(new Date());
    DateTimeFormatter formatter = DateTimeFormat.forPattern(CommonConstants.DATE_FORMAT_YYYYMMDD_HHMMSS_SSS)
            .withZoneUTC();
    Instant start_point = Instant.parse(timestamp, formatter);
    Instant end_point = Instant.parse(currentTime, formatter);

    return new IntervalWindow(start_point, end_point);
};

@Override
public Coder<IntervalWindow> windowCoder() {
    return IntervalWindow.getCoder();
}

@Override
public Collection<IntervalWindow> assignWindows(AssignContext c) throws Exception {
    return Arrays.asList(assignWindow(c));
}

@Override
public boolean isCompatible(WindowFn<?, ?> other) {
    return false;
}

@Override
public WindowMappingFn<IntervalWindow> getDefaultWindowMappingFn() {
    throw new IllegalArgumentException(
            "Attempted to get side input window for GlobalWindow from non-global WindowFn");
}
公共类BQTablePartitionWindowFn扩展了非合并窗口fn{
/**
* 
*/
私有静态最终长serialVersionUID=1L;
专用IntervalWindow assignWindow(AssignContext上下文){
TableRow=(TableRow)context.element();
String timestamp=tableRow.get(BQConstants.LOG_TIME).toString();
字符串currentTime=DateUtil.getFormattedDate(新日期());
DateTimeFormatter formatter=DateTimeFormat.forPattern(CommonConstants.DATE\u FORMAT\u YYYYMMDD\u HHMMSS\u SSS)
.withZoneUTC();
Instant start_point=Instant.parse(时间戳、格式化程序);
即时结束点=Instant.parse(currentTime,格式化程序);
返回新的间隔窗口(起点、终点);
};
@凌驾
公共编码器windowCoder(){
返回IntervalWindow.getCoder();
}
@凌驾
公共集合assignWindows(AssignContext c)引发异常{
返回数组.asList(assignWindow(c));
}
@凌驾
公共布尔值不可计算(WindowFn其他){
返回false;
}
@凌驾
公共窗口映射Fn getDefaultWindowMappingFn(){
抛出新的IllegalArgumentException(
“试图从非全局窗口fn获取全局窗口的侧面输入窗口”);
}

}

GroupByKey的默认行为是输出带有时间戳的iterables,该时间戳是窗口中允许的最大时间戳。对于您的窗口,这是时间戳
13:53:08.718Z

元素具有时间戳
13:53:08.725Z
,该时间戳不会从
13:53:08.088Z
13:53:08.719Z
落在窗口中

您是否可以共享您的
窗口fn
以及任何调整时间戳的
ParDo

更新:感谢分享您的
窗口fn
。关于它,有几件事会给您带来问题

1.指定窗口的开始时间不基于元素的时间戳。

您提取元素的一列并根据
context.element().get(BQConstants.LOG\u TIME)
(忽略强制转换和解析)的值分配窗口。从错误消息中,这似乎不是
context.timestamp()
的实际值,后者是元素的事件时间戳

相反,您应该编写
窗口fn
以使用
上下文.timestamp()
。您可以根据数据是否有边界,以不同的方式确保时间戳是您想要的:

  • 如果数据是有界的,则可以使用
    with timestamps
    通过提取该字段来分配时间戳
  • 如果您的数据是无边界的,则源需要了解更多信息,以便管理水印,因此配置取决于源。例如,
    PubsubIO
    从您可以指定的属性读取时间戳
2.指定窗口的结束时间基于系统日期

有几个问题:

  • 结束时间向下舍入,可能早于开始时间,导致窗口无效
  • 结束时间是不确定的。Beam中的一般期望是,您将主要基于元素的时间戳(必须在窗口结束之前)确定地分配一个窗口一个不确定的窗口,例如这个,可能有不可预见的缺点。一个已知的问题是,你的结果是不可复制的,如果你需要修复一个数据处理错误或者在存档的数据上运行实验,这可能是麻烦的。这取决于你的用例,但是你可以考虑一些MOR。e未来证明

这里的目标是什么?您设置它只是为了提取动态目标的端点吗?如果是这样,我建议您根据数据发生的时间而不是处理的时间对数据进行分区。

谢谢!我相应地扩展了我的答案。谢谢您的解释。我可以进行更改以避免占用系统时间-----------------------是的,我设置它只是为了提取动态目标的端点。我需要根据logtime设置partion like。感谢添加的详细信息。我已经扩展了我的答案来讨论您的
窗口fn