/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.apache.flink.streaming.runtime.io; import org.apache.flink.annotation.Internal;
import org.apache.flink.api.common.typeutils.TypeSerializer;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.metrics.Counter;
import org.apache.flink.metrics.SimpleCounter;
import org.apache.flink.runtime.event.AbstractEvent;
import org.apache.flink.runtime.io.disk.iomanager.IOManager;
import org.apache.flink.runtime.io.network.api.EndOfPartitionEvent;
import org.apache.flink.runtime.io.network.api.serialization.RecordDeserializer;
import org.apache.flink.runtime.io.network.api.serialization.RecordDeserializer.DeserializationResult;
import org.apache.flink.runtime.io.network.api.serialization.SpillingAdaptiveSpanningRecordDeserializer;
import org.apache.flink.runtime.io.network.buffer.Buffer;
import org.apache.flink.runtime.io.network.partition.consumer.BufferOrEvent;
import org.apache.flink.runtime.io.network.partition.consumer.InputGate;
import org.apache.flink.runtime.metrics.groups.OperatorMetricGroup;
import org.apache.flink.runtime.metrics.groups.TaskIOMetricGroup;
import org.apache.flink.runtime.plugable.DeserializationDelegate;
import org.apache.flink.runtime.plugable.NonReusingDeserializationDelegate;
import org.apache.flink.streaming.api.CheckpointingMode;
import org.apache.flink.streaming.api.operators.OneInputStreamOperator;
import org.apache.flink.streaming.api.watermark.Watermark;
import org.apache.flink.streaming.runtime.metrics.WatermarkGauge;
import org.apache.flink.streaming.runtime.streamrecord.StreamElement;
import org.apache.flink.streaming.runtime.streamrecord.StreamElementSerializer;
import org.apache.flink.streaming.runtime.streamrecord.StreamRecord;
import org.apache.flink.streaming.runtime.streamstatus.StatusWatermarkValve;
import org.apache.flink.streaming.runtime.streamstatus.StreamStatus;
import org.apache.flink.streaming.runtime.streamstatus.StreamStatusMaintainer;
import org.apache.flink.streaming.runtime.tasks.StreamTask; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.IOException; import static org.apache.flink.util.Preconditions.checkNotNull; /**
* Input reader for {@link org.apache.flink.streaming.runtime.tasks.OneInputStreamTask}.
*
* <p>This internally uses a {@link StatusWatermarkValve} to keep track of {@link Watermark} and
* {@link StreamStatus} events, and forwards them to event subscribers once the
* {@link StatusWatermarkValve} determines the {@link Watermark} from all inputs has advanced, or
* that a {@link StreamStatus} needs to be propagated downstream to denote a status change.
*
* <p>Forwarding elements, watermarks, or status status elements must be protected by synchronizing
* on the given lock object. This ensures that we don't call methods on a
* {@link OneInputStreamOperator} concurrently with the timer callback or other things.
*
* @param <IN> The type of the record that can be read with this record reader.
*/
@Internal
public class StreamInputProcessor<IN> { private static final Logger LOG = LoggerFactory.getLogger(StreamInputProcessor.class); private final RecordDeserializer<DeserializationDelegate<StreamElement>>[] recordDeserializers; private RecordDeserializer<DeserializationDelegate<StreamElement>> currentRecordDeserializer; private final DeserializationDelegate<StreamElement> deserializationDelegate; private final CheckpointBarrierHandler barrierHandler; private final Object lock; // ---------------- Status and Watermark Valve ------------------ /** Valve that controls how watermarks and stream statuses are forwarded. */
private StatusWatermarkValve statusWatermarkValve; /** Number of input channels the valve needs to handle. */
private final int numInputChannels; /**
* The channel from which a buffer came, tracked so that we can appropriately map
* the watermarks and watermark statuses to channel indexes of the valve.
*/
private int currentChannel = -1; private final StreamStatusMaintainer streamStatusMaintainer; private final OneInputStreamOperator<IN, ?> streamOperator; // ---------------- Metrics ------------------ private final WatermarkGauge watermarkGauge;
private Counter numRecordsIn; private boolean isFinished; @SuppressWarnings("unchecked")
public StreamInputProcessor(
InputGate[] inputGates,
TypeSerializer<IN> inputSerializer,
StreamTask<?, ?> checkpointedTask,
CheckpointingMode checkpointMode,
Object lock,
IOManager ioManager,
Configuration taskManagerConfig,
StreamStatusMaintainer streamStatusMaintainer,
OneInputStreamOperator<IN, ?> streamOperator,
TaskIOMetricGroup metrics,
WatermarkGauge watermarkGauge) throws IOException { InputGate inputGate = InputGateUtil.createInputGate(inputGates); this.barrierHandler = InputProcessorUtil.createCheckpointBarrierHandler(
checkpointedTask, checkpointMode, ioManager, inputGate, taskManagerConfig); this.lock = checkNotNull(lock); StreamElementSerializer<IN> ser = new StreamElementSerializer<>(inputSerializer);
this.deserializationDelegate = new NonReusingDeserializationDelegate<>(ser); // Initialize one deserializer per input channel
this.recordDeserializers = new SpillingAdaptiveSpanningRecordDeserializer[inputGate.getNumberOfInputChannels()]; for (int i = 0; i < recordDeserializers.length; i++) {
recordDeserializers[i] = new SpillingAdaptiveSpanningRecordDeserializer<>(
ioManager.getSpillingDirectoriesPaths());
} this.numInputChannels = inputGate.getNumberOfInputChannels(); this.streamStatusMaintainer = checkNotNull(streamStatusMaintainer);
this.streamOperator = checkNotNull(streamOperator); this.statusWatermarkValve = new StatusWatermarkValve(
numInputChannels,
new ForwardingValveOutputHandler(streamOperator, lock)); this.watermarkGauge = watermarkGauge;
metrics.gauge("checkpointAlignmentTime", barrierHandler::getAlignmentDurationNanos);
} public boolean processInput() throws Exception {
if (isFinished) {
return false;
}
if (numRecordsIn == null) {
try {
numRecordsIn = ((OperatorMetricGroup) streamOperator.getMetricGroup()).getIOMetricGroup().getNumRecordsInCounter();
} catch (Exception e) {
LOG.warn("An exception occurred during the metrics setup.", e);
numRecordsIn = new SimpleCounter();
}
} while (true) {
if (currentRecordDeserializer != null) {
DeserializationResult result = currentRecordDeserializer.getNextRecord(deserializationDelegate); if (result.isBufferConsumed()) {
currentRecordDeserializer.getCurrentBuffer().recycleBuffer();
currentRecordDeserializer = null;
} if (result.isFullRecord()) {
StreamElement recordOrMark = deserializationDelegate.getInstance(); if (recordOrMark.isWatermark()) {
// handle watermark
statusWatermarkValve.inputWatermark(recordOrMark.asWatermark(), currentChannel);
continue;
} else if (recordOrMark.isStreamStatus()) {
// handle stream status
statusWatermarkValve.inputStreamStatus(recordOrMark.asStreamStatus(), currentChannel);
continue;
} else if (recordOrMark.isLatencyMarker()) {
// handle latency marker
synchronized (lock) {
streamOperator.processLatencyMarker(recordOrMark.asLatencyMarker());
}
continue;
} else {
// now we can do the actual processing
StreamRecord<IN> record = recordOrMark.asRecord();
synchronized (lock) {
numRecordsIn.inc();
streamOperator.setKeyContextElement1(record);
streamOperator.processElement(record);
}
return true;
}
}
} final BufferOrEvent bufferOrEvent = barrierHandler.getNextNonBlocked();
if (bufferOrEvent != null) {
if (bufferOrEvent.isBuffer()) {
currentChannel = bufferOrEvent.getChannelIndex();
currentRecordDeserializer = recordDeserializers[currentChannel];
currentRecordDeserializer.setNextBuffer(bufferOrEvent.getBuffer());
}
else {
// Event received
final AbstractEvent event = bufferOrEvent.getEvent();
if (event.getClass() != EndOfPartitionEvent.class) {
throw new IOException("Unexpected event: " + event);
}
}
}
else {
isFinished = true;
if (!barrierHandler.isEmpty()) {
throw new IllegalStateException("Trailing data in checkpoint barrier handler.");
}
return false;
}
}
} public void cleanup() throws IOException {
// clear the buffers first. this part should not ever fail
for (RecordDeserializer<?> deserializer : recordDeserializers) {
Buffer buffer = deserializer.getCurrentBuffer();
if (buffer != null && !buffer.isRecycled()) {
buffer.recycleBuffer();
}
deserializer.clear();
} // cleanup the barrier handler resources
barrierHandler.cleanup();
} private class ForwardingValveOutputHandler implements StatusWatermarkValve.ValveOutputHandler {
private final OneInputStreamOperator<IN, ?> operator;
private final Object lock; private ForwardingValveOutputHandler(final OneInputStreamOperator<IN, ?> operator, final Object lock) {
this.operator = checkNotNull(operator);
this.lock = checkNotNull(lock);
} @Override
public void handleWatermark(Watermark watermark) {
try {
synchronized (lock) {
watermarkGauge.setCurrentWatermark(watermark.getTimestamp());
operator.processWatermark(watermark);
}
} catch (Exception e) {
throw new RuntimeException("Exception occurred while processing valve output watermark: ", e);
}
} @SuppressWarnings("unchecked")
@Override
public void handleStreamStatus(StreamStatus streamStatus) {
try {
synchronized (lock) {
streamStatusMaintainer.toggleStreamStatus(streamStatus);
}
} catch (Exception e) {
throw new RuntimeException("Exception occurred while processing valve output stream status: ", e);
}
}
} }

numRecordsIn 在哪里实现?的更多相关文章

  1. flink - accumulator

      读accumlator JobManager 在job finish的时候会汇总accumulator的值, newJobStatus match { case JobStatus.FINISHE ...

  2. 追源索骥:透过源码看懂Flink核心框架的执行流程

    li,ol.inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt, ...

  3. https://stackoverflow.com/questions/51751426/failed-to-run-the-da-platform-trial-vm

    https://stackoverflow.com/questions/51751426/failed-to-run-the-da-platform-trial-vm {  "annotat ...

  4. Flink – Stream Task执行过程

    Task.run if (invokable instanceof StatefulTask) { StatefulTask op = (StatefulTask) invokable; op.set ...

  5. Flink – metrics V1.2

    WebRuntimeMonitor   .GET("/jobs/:jobid/vertices/:vertexid/metrics", handler(new JobVertexM ...

  6. Flink standalone模式作业执行流程

    宏观流程如下图: client端 生成StreamGraph env.addSource(new SocketTextStreamFunction(...)) .flatMap(new FlatMap ...

  7. 【源码解析】Flink 是如何处理迟到数据

    相信会看到这篇文章的都对Flink的时间类型(事件时间.处理时间.摄入时间)和Watermark有些了解,当然不了解可以先看下官网的介绍:https://ci.apache.org/projects/ ...

  8. Apache Flink 进阶(六):Flink 作业执行深度解析

    本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink Contributor.网易云音乐实时计算平台研发工程师岳猛分享.主要分享内容为 Flink Job 执行作业的 ...

  9. 深入了解 Flink 网络栈(二):监控、指标和处理背压

    在之前的文章中,我们从高级抽象到底层细节各个层面全面介绍了 Flink 网络栈的工作机制.作为这一系列的第二篇文章,本文将在第一篇的基础上更进一步,主要探讨如何监视与网络相关的指标,从而识别背压等因素 ...

随机推荐

  1. mysql触发器 学习

    1.       说明: 触发器的定义就是说某个条件成立的时候,你触发器里面所定义的语句就会被自动的执行.因此触发器不需要人为的去调用,也不能调用.然后,触发器的触发条件其实在你定义的时候就已经设定好 ...

  2. Pinpoint - 应用性能管理(APM)平台实践之部署篇

    0.0 前言 国内的APM行业这两年刚刚起步,但是在国外却比较成熟了,并且由于这两年人力成本的快速提高,国内外涌现了几家非常不错的APM企业,例如APPdynamic,Dynamic,NewRelic ...

  3. XML制作RSS源

    什么是RSS源?看到这片文章的人相信都知道.自己博客首页不就是一个吗? 好吧,先来一个简单点的.直接就是死代码:详细如何使用就看RSS使用标准吧! <?xml version = "1 ...

  4. Easyui入门视频教程 第11集---Window的使用

    目录 Easyui入门视频教程 第11集---Window的使用   Easyui入门视频教程 第10集---Messager的使用  Easyui入门视频教程 第09集---登录完善 图标自定义   ...

  5. Vue.js——60分钟快速入门 开发· webpack 中文文档

    转载于:http://www.cnblogs.com/keepfool/p/5619070.html http://www.css88.com/doc/webpack2/guides/get-star ...

  6. angularJS实现无刷新文件下载

    $scope.getExcel = function () { $http.post("/production/statistics/export", { storeId: $sc ...

  7. Zabbix 常见问题处理整理

    zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. 下载: http://www.zabbix.com/download.php 帮助:https://www ...

  8. httpd: Could not reliably determine the server's fully qualified domain name(转)

    ttpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for Ser ...

  9. Fastjson是一个Java语言编写的高性能功能完善的JSON库。

    简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...

  10. Android adjustresize全屏无效问题

    屏模式下,即使将activity的windowSoftInputMode的属性设置为:adjustResize,在键盘显示时它未将Activity的Screen向上推动,所以你Activity的vie ...