// This example implements the asynchronous request and callback with Futures that have the
  
  // interface of Java 8's futures (which is the same one followed by Flink's Future)
  
  /**
  
  * An implementation of the 'AsyncFunction' that sends requests and sets the callback.
  
  */
  
  class AsyncDatabaseRequest extends RichAsyncFunction<String, Tuple2<String, String>> {
  
  /** The database specific client that can issue concurrent requests with callbacks */
  
  private transient DatabaseClient client;
  
  @Override
  
  public void open(Configuration parameters) throws Exception {
  
  client = new DatabaseClient(host, post, credentials);
  
  }
  
  @Override
  
  public void close() throws Exception {
  
  client.close();
  
  }
  
  @Override
  
  public void asyncInvoke(String key, final ResultFuture<Tuple2<String, String>> resultFuture) throws Exception {
  
  // issue the asynchronous request, receive a future for result
  
  final Future<String> result = client.query(key);
  
  // set the callback to be executed once the request by the client is complete
  
  // the callback simply forwards the result to the result future
  
  CompletableFuture.supplyAsync(new Supplier<String>() {
  
  @Override
  
  public String get() {
  
  try {
  
  return result.get();
  
  } catch (InterruptedException | ExecutionException e) {
  
  // Normally handled explicitly.
  
  return null;
  
  }
  
  }
  
  }).thenAccept( (String dbResult) -> {
  
  resultFuture.complete(Collections.singleton(new Tuple2<>(key, dbResult)));
  
  });
  
  }
  
  }
  
  // create the original stream
  
  DataStream<String> stream = ...;
  
  // apply the async I/O transformation
  
  DataStream<Tuple2<String, String>> resultStream =
  
  AsyncDataStream.unorderedWait(stream, new AsyncDatabaseRequest(), 1000, TimeUnit.MILLISECONDS, 100);
  
  本实例展示了flink Async I/O的基本用法,首先是实现AsyncFunction接口,用于编写异步请求逻辑及将结果或异常设置到resultFuture,然后就是使用AsyncDataStream的unorderedWait或orderedWait方法将AsyncFunction作用到DataStream作为transformation;AsyncDataStream的unorderedWait或orderedWait有两个关于async operation的参数,一个是timeout参数用于设置async的超时时间,一个是capacity参数用于指定同一时刻最大允许多少个(并发)async request在执行
  
  AsyncFunction
  
  flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/functions/async/AsyncFunction.java
  
  /**
  
  * A function to trigger Async I/O operation.
  
  *
  
  * <p>For each #asyncInvoke, an async io operation can be triggered, and once it has been done,
  
  * the result can be collected by calling {@link ResultFuture#complete}. For each async
  
  * operation, its context is stored in the operator immediately after invoking
  
  * #asyncInvoke, avoiding blocking for each stream input as long as the internal buffer is not full.
  
  *
  
  * <p>{@link ResultFuture} can be passed into callbacks or futures to collect the result data.
  
  * An error can also be propagate to the async IO operator by
  
  * {@link ResultFuture#completeExceptionally(Throwable)}.
  
  *
  
  * <p>Callback www.michenggw.com example usage:
  
  *
  
  * <pre>{@code
  
  * public class HBaseAsyncFunc implements AsyncFunction<String, String> {
  
  *
  
  * public void asyncInvoke(String row, ResultFuture<String> result) throws Exception {
  
  * HBaseCallback cb = new HBaseCallback(result);
  
  * Get get = new Get(Bytes.toBytes(row));
  
  * hbase.asyncGet(get, cb);
  
  * }
  
  * }
  
  * }</pre>
  
  *
  
  * <p>Future example www.mcyllpt.com usage:
  
  *
  
  * <pre>{@code
  
  * public class HBaseAsyncFunc implements AsyncFunction<String, String> {
  
  *
  
  * public void asyncInvoke(String row, final ResultFuture<String> result) throws Exception {
  
  * Get get = new Get(Bytes.toBytes(row));
  
  * ListenableFuture<Result>www.gcyl158.com future = hbase.asyncGet(get);
  
  * Futures.addCallback(future, new FutureCallback<Result>() {
  
  * public void onSuccess(Result result) {
  
  * List<String> ret = process(result);
  
  * result.complete(ret);
  
  * }
  
  * public void onFailure(Throwable thrown) {
  
  * result.completeExceptionally(thrown);
  
  * }
  
  * });
  
  * }
  
  * }
  
  * }</pre>
  
  *
  
  * @param <IN> The type of the www.haitianguo.cn input elements.
  
  * @param <OUT> The type of the returned elements.
  
  */
  
  @PublicEvolving
  
  public interface AsyncFunction<IN, OUT> extends Function, Serializable {
  
  /**
  
   * Trigger async operation for each stream input.
  
   *
  
   * @param input element coming from an upstream task
  
   * @param resultFuture to be completed with the result data
  
   * @exception Exception in case of a user code error. An exception will make the task fail and
  
   * trigger fail-over process.
  
   */
  
  void asyncInvoke(IN input, ResultFuture<www.fenghuang1999.com> resultFuture) throws Exception;
  
  /**
  
   * {@link AsyncFunction#asyncInvoke} timeout occurred.
  
   * By default, the result future is exceptionally completed with a timeout exception.
  
   *
  
   * @param input element coming from an upstream task
  
   * @param resultFuture to be completed with the result data
  
   */
  
  default void timeout(IN input, ResultFuture<OUT> resultFuture) throws Exception {
  
  resultFuture.completeExceptionally(
  
  new TimeoutException("Async function call has timed out."));
  
  }
  
  }
  
  AsyncFunction接口继承了Function,它定义了asyncInvoke方法以及一个default的timeout方法;asyncInvoke方法执行异步逻辑,然后通过ResultFuture.complete将结果设置到ResultFuture,如果异常则通过ResultFuture.completeExceptionally(Throwable)来传递到ResultFuture
  
  RichAsyncFunction
  
  flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/functions/async/RichAsyncFunction.java
  
  @PublicEvolving
  
  public abstract class RichAsyncFunction<IN, OUT> extends AbstractRichFunction implements AsyncFunction<IN, OUT> {
  
  private static final long serialVersionUID = 3858030061138121840L;
  
  @Override
  
  public void setRuntimeContext(RuntimeContext runtimeContext) {
  
  Preconditions.checkNotNull(runtimeContext);
  
  if (runtimeContext instanceof IterationRuntimeContext) {
  
  super.setRuntimeContext(
  
  new RichAsyncFunctionIterationRuntimeContext(
  
  (IterationRuntimeContext) runtimeContext));
  
  } else {
  
  super.setRuntimeContext(new RichAsyncFunctionRuntimeContext(runtimeContext));
  
  }
  
  }
  
  @Override
  
  public abstract void asyncInvoke(IN input, ResultFuture<OUT> resultFuture) throws Exception;
  
  //......
  
  }
  
  RichAsyncFunction继承了AbstractRichFunction,同时声明实现AsyncFunction接口,它不没有实现asyncInvoke,交由子类实现;它覆盖了setRuntimeContext方法,这里使用RichAsyncFunctionRuntimeContext或者RichAsyncFunctionIterationRuntimeContext进行包装
  
  RichAsyncFunctionRuntimeContext
  
  flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/functions/async/RichAsyncFunction.java
  
  /**
  
   * A wrapper class for async function's {@link RuntimeContext}. The async function runtime
  
   * context only supports basic operations which are thread safe. Consequently, state access,
  
   * accumulators, broadcast variables and the distributed cache are disabled.
  
   */
  
  private static class RichAsyncFunctionRuntimeContext implements RuntimeContext {
  
  private final RuntimeContext runtimeContext;
  
  RichAsyncFunctionRuntimeContext(RuntimeContext context) {
  
  runtimeContext = Preconditions.checkNotNull(context);
  
  }
  
  @Override
  
  public String getTaskName() {
  
  return runtimeContext.getTaskName();
  
  }
  
  @Override
  
  public MetricGroup getMetricGroup() {
  
  return runtimeContext.getMetricGroup();
  
  }
  
  @Override
  
  public int getNumberOfParallelSubtasks() {
  
  return runtimeContext.getNumberOfParallelSubtasks();
  
  }
  
  @Override
  
  public int getMaxNumberOfParallelSubtasks() {
  
  return runtimeContext.getMaxNumberOfParallelSubtasks();
  
  }
  
  @Override
  
  public int getIndexOfThisSubtask() {
  
  return runtimeContext.getIndexOfThisSubtask();
  
  }
  
  @Override
  
  public int getAttemptNumber() {
  
  return runtimeContext.getAttemptNumber();
  
  }
  
  @Override
  
  public String getTaskNameWithSubtasks() {
  
  return runtimeContext.getTaskNameWithSubtasks();
  
  }
  
  @Override
  
  public ExecutionConfig getExecutionConfig() {
  
  return runtimeContext.getExecutionConfig();
  
  }
  
  @Override
  
  public ClassLoader getUserCodeClassLoader() {
  
  return runtimeContext.getUserCodeClassLoader();
  
  }
  
  // -----------------------------------------------------------------------------------
  
  // Unsupported operations
  
  // -----------------------------------------------------------------------------------
  
  @Override
  
  public DistributedCache getDistributedCache() {
  
  throw new UnsupportedOperationException("Distributed cache is not supported in rich async functions.");
  
  }
  
  @Override
  
  public <T> ValueState<T> getState(ValueStateDescriptor<T> stateProperties) {
  
  throw new UnsupportedOperationException("State is not supported in rich async functions.");
  
  }
  
  @Override
  
  public <T> ListState<T> getListState(ListStateDescriptor<T> stateProperties) {
  
  throw new UnsupportedOperationException("State is not supported in rich async functions.");
  
  }
  
  @Override
  
  public <T> ReducingState<T> getReducingState(ReducingStateDescriptor<T> stateProperties) {
  
  throw new UnsupportedOperationException("State is not supported in rich async functions.");
  
  }
  
  @Override
  
  public <IN, ACC, OUT> AggregatingState<IN, OUT> getAggregatingState(AggregatingStateDescriptor<IN, ACC, OUT> stateProperties) {
  
  throw new UnsupportedOperationException("State is not supported in rich async functions.");
  
  }
  
  @Override
  
  public <T, ACC> FoldingState<T, ACC> getFoldingState(FoldingStateDescriptor<T, ACC> stateProperties) {
  
  throw new UnsupportedOperationException("State is not supported in rich async functions.");
  
  }
  
  @Override
  
  public <UK, UV> MapState<UK, UV> getMapState(MapStateDescriptor<UK, UV> stateProperties) {
  
  throw new UnsupportedOperationException("State is not supported in rich async functions.");
  
  }
  
  @Override
  
  public <V, A extends Serializable> void addAccumulator(String name, Accumulator<V, A> accumulator) {
  
  throw new UnsupportedOperationException("Accumulators are not supported in rich async functions.");
  
  }
  
  @Override
  
  public <V, A extends Serializable> Accumulator<V, A> getAccumulator(String name) {
  
  throw new UnsupportedOperationException("Accumulators are not supported in rich async functions.");
  
  }
  
  @Override
  
  public Map<String, Accumulator<?, ?>> getAllAccumulators() {
  
  throw new UnsupportedOperationException("Accumulators are not supported in rich async functions.");
  
  }
  
  @Override
  
  public IntCounter getIntCounter(String name) {
  
  throw new UnsupportedOperationException("Int counters are not supported in rich async functions.");
  
  }
  
  @Override
  
  public LongCounter getLongCounter(String name) {
  
  throw new UnsupportedOperationException("Long counters are not supported in rich async functions.");
  
  }
  
  @Override
  
  public DoubleCounter getDoubleCounter(String name) {
  
  throw new UnsupportedOperationException("Long counters are not supported in rich async functions.");
  
  }
  
  @Override
  
  public Histogram getHistogram(String name) {
  
  throw new UnsupportedOperationException("Histograms are not supported in rich async functions.");
  
  }
  
  @Override
  
  public boolean hasBroadcastVariable(String name) {
  
  throw new UnsupportedOperationException("Broadcast variables are not supported in rich async functions.");
  
  }
  
  @Override
  
  public <RT> List<RT> getBroadcastVariable(String name) {
  
  throw new UnsupportedOperationException("Broadcast variables are not supported in rich async functions.");
  
  }
  
  @Override
  
  public <T, C> C getBroadcastVariableWithInitializer(String name, BroadcastVariableInitializer<T, C> initializer) {
  
  throw new UnsupportedOperationException("Broadcast variables are not supported in rich async functions.");
  
  }
  
  }
  
  RichAsyncFunctionRuntimeContext实现了RuntimeContext接口,它将一些方法代理给RuntimeContext,其余的Unsupported的方法都覆盖抛出UnsupportedOperationException
  
  RichAsyncFunctionIterationRuntimeContext
  
  flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/functions/async/RichAsyncFunction.java
  
  private static class RichAsyncFunctionIterationRuntimeContext extends RichAsyncFunctionRuntimeContext implements IterationRuntimeContext {
  
  private final IterationRuntimeContext iterationRuntimeContext;
  
  RichAsyncFunctionIterationRuntimeContext(IterationRuntimeContext iterationRuntimeContext) {
  
  super(iterationRuntimeContext);
  
  this.iterationRuntimeContext = Preconditions.checkNotNull(iterationRuntimeContext);
  
  }
  
  @Override
  
  public int getSuperstepNumber() {
  
  return iterationRuntimeContext.getSuperstepNumber();
  
  }
  
  // -----------------------------------------------------------------------------------
  
  // Unsupported operations
  
  // -----------------------------------------------------------------------------------
  
  @Override
  
  public <T extends Aggregator<?>> T getIterationAggregator(String name) {
  
  throw new UnsupportedOperationException("Iteration aggregators are not supported in rich async functions.");
  
  }
  
  @Override
  
  public <T extends Value> T getPreviousIterationAggregate(String name) {
  
  throw new UnsupportedOperationException("Iteration aggregators are not supported in rich async functions.");
  
  }
  
  }
  
  RichAsyncFunctionIterationRuntimeContext继承了RichAsyncFunctionRuntimeContext,实现了IterationRuntimeContext接口,它将getSuperstepNumber方法交由IterationRuntimeContext处理,然后覆盖getIterationAggregator、getPreviousIterationAggregate方法抛出UnsupportedOperationException
  
  AsyncDataStream
  
  flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/datastream/AsyncDataStream.java
  
  @PublicEvolving
  
  public class AsyncDataStream {
  
  /**
  
   * Output mode for asynchronous operations.
  
   */
  
  public enum OutputMode { ORDERED, UNORDERED }
  
  private static final int DEFAULT_QUEUE_CAPACITY = 100;
  
  private static <IN, OUT> SingleOutputStreamOperator<OUT> addOperator(
  
  DataStream<IN> in,
  
  AsyncFunction<IN, OUT> func,
  
  long timeout,
  
  int bufSize,
  
  OutputMode mode) {
  
  TypeInformation<OUT> outTypeInfo = TypeExtractor.getUnaryOperatorReturnType(
  
  func,
  
  AsyncFunction.class,
  
  0,
  
  1,
  
  new int[]{1, 0},
  
  in.getType(),
  
  Utils.getCallLocationName(),
  
  true);
  
  // create transform
  
  AsyncWaitOperator<IN, OUT> operator = new AsyncWaitOperator<>(
  
  in.getExecutionEnvironment().clean(func),
  
  timeout,
  
  bufSize,
  
  mode);
  
  return in.transform("async wait operator", outTypeInfo, operator);
  
  }
  
  public static <IN, OUT> SingleOutputStreamOperator<OUT> unorderedWait(
  
  DataStream<IN> in,
  
  AsyncFunction<IN, OUT> func,
  
  long timeout,
  
  TimeUnit timeUnit,
  
  int capacity) {
  
  return addOperator(in, func, timeUnit.toMillis(timeout), capacity, OutputMode.UNORDERED);
  
  }
  
  public static <IN, OUT> SingleOutputStreamOperator<OUT> unorderedWait(
  
  DataStream<IN> in,
  
  AsyncFunction<IN, OUT> func,
  
  long timeout,
  
  TimeUnit timeUnit) {
  
  return addOperator(
  
  in,
  
  func,
  
  timeUnit.toMillis(timeout),
  
  DEFAULT_QUEUE_CAPACITY,
  
  OutputMode.UNORDERED);
  
  }
  
  public static <IN, OUT> SingleOutputStreamOperator<OUT> orderedWait(
  
  DataStream<IN> in,
  
  AsyncFunction<IN, OUT> func,
  
  long timeout,
  
  TimeUnit timeUnit,
  
  int capacity) {
  
  return addOperator(in, func, timeUnit.toMillis(timeout), capacity, OutputMode.ORDERED);
  
  }
  
  public static <IN, OUT> SingleOutputStreamOperator<OUT> orderedWait(
  
  DataStream<IN> in,
  
  AsyncFunction<IN, OUT> func,
  
  long timeout,
  
  TimeUnit timeUnit) {
  
  return addOperator(
  
  in,
  
  func,
  
  timeUnit.toMillis(timeout),
  
  DEFAULT_QUEUE_CAPACITY,
  
  OutputMode.ORDERED);
  
  }
  
  }
  
  AsyncDataStream提供了unorderedWait、orderedWait两类方法来将AsyncFunction作用于DataStream
  
  unorderedWait、orderedWait方法有带capacity参数的也有不带capacity参数的,不带capacity参数即默认使用DEFAULT_QUEUE_CAPACITY,即100;这些方法最后都是调用addOperator私有方法来实现,它使用的是AsyncWaitOperator;unorderedWait、orderedWait方法都带了timeout参数,用于指定等待async操作完成的超时时间
  
  AsyncDataStream提供了两种OutputMode,其中UNORDERED是无序的,即一旦async操作完成就emit结果,当使用TimeCharacteristic.ProcessingTime的时候这种模式延迟最低、负载最低;ORDERED是有序的,即按element的输入顺序emit结果,为了保证有序operator需要缓冲数据,因而会造成一定的延迟及负载
  
  小结
  
  flink给外部数据访问提供了Asynchronous I/O的API,用于提升streaming的吞吐量,其基本使用就是定义一个实现AsyncFunction接口的function,然后使用AsyncDataStream的unorderedWait或orderedWait方法将AsyncFunction作用到DataStream作为transformation
  
  AsyncFunction接口继承了Function,它定义了asyncInvoke方法以及一个default的timeout方法;asyncInvoke方法执行异步逻辑,然后通过ResultFuture.complete将结果或异常设置到ResultFuture,如果异常则通过ResultFuture.completeExceptionally(Throwable)来传递到ResultFuture;RichAsyncFunction继承了AbstractRichFunction,同时声明实现AsyncFunction接口,它不没有实现asyncInvoke,交由子类实现;它覆盖了setRuntimeContext方法,这里使用RichAsyncFunctionRuntimeContext或者RichAsyncFunctionIterationRuntimeContext进行包装
  
  AsyncDataStream的unorderedWait或orderedWait有两个关于async operation的参数,一个是timeout参数用于设置async的超时时间,一个是capacity参数用于指定同一时刻最大允许多少个(并发)async request在执行;AsyncDataStream提供了两种OutputMode,其中UNORDERED是无序的,即一旦async操作完成就emit结果,当使用TimeCharacteristic.ProcessingTime的时候这种模式延迟最低、负载最低;ORDERED是有序的,即按element的输入顺序emit结果,为了保证有序operator需要缓冲数据,因而会造成一定的延迟及负载

聊聊flink的Async I/O的更多相关文章

  1. 聊聊flink的NetworkEnvironmentConfiguration

    本文主要研究一下flink的NetworkEnvironmentConfiguration NetworkEnvironmentConfiguration flink-1.7.2/flink-runt ...

  2. 聊聊flink的AsyncWaitOperator

    序本文主要研究一下flink的AsyncWaitOperator AsyncWaitOperatorflink-streaming-java_2.11-1.7.0-sources.jar!/org/a ...

  3. 简单聊聊ES6-Promise和Async

    前言 本篇博文出至于我的github仓库:web-study,如果你觉得对你有帮助欢迎star,你们的点赞是我持续更新的动力,谢谢! 异步编程在前端开发中尤为常见,从最早的XHR,到后来的各种封装aj ...

  4. [case49]聊聊flink的checkpoint配置

    序 本文主要研究下flink的checkpoint配置 实例 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecut ...

  5. 聊聊flink的CsvTableSource

    序 本文主要研究一下flink的CsvTableSource TableSource flink-table_2.11-1.7.1-sources.jar!/org/apache/flink/tabl ...

  6. 聊聊flink Table的groupBy操作

    本文主要研究一下flink Table的groupBy操作 Table.groupBy flink-table_2.11-1.7.0-sources.jar!/org/apache/flink/tab ...

  7. 聊聊flink的log.file配置

    本文主要研究一下flink的log.file配置 log4j.properties flink-release-1.6.2/flink-dist/src/main/flink-bin/conf/log ...

  8. 聊聊flink的BlobStoreService

    序 本文主要研究一下flink的BlobStoreService BlobView flink-release-1.7.2/flink-runtime/src/main/java/org/apache ...

  9. [源码分析] 从源码入手看 Flink Watermark 之传播过程

    [源码分析] 从源码入手看 Flink Watermark 之传播过程 0x00 摘要 本文将通过源码分析,带领大家熟悉Flink Watermark 之传播过程,顺便也可以对Flink整体逻辑有一个 ...

随机推荐

  1. asp.net 问题:Web 服务器上的请求筛选模块被配置为 拒绝包含的查询字符串过长的请求

    发现问题: post请求,在发送一个图片base64编码的字符串时,服务端报这个错误. 报错信息中给出了解决办法: 最可能的原因: Web 服务器上的请求筛选被配置为拒绝该请求,因为查询字符串过长. ...

  2. php缩放处理png和jpg图片

    本例子介绍使用php自带的GD库对png和jpg图片进行放大和缩小处理 <?php$target_width = 120; //目标图片宽度 $target_height = 150; //目标 ...

  3. Linux中如何安装Apache服务器

    Linux中如何安装Apache服务器 由于学习的需要,所有手动安装了一下Apache源码包,安装过程中的问题千奇百怪,但是如果弄清楚了问题出在哪里,那么也不是太难.如果有学习者出现安装中的问题,可仔 ...

  4. JY播放器【喜马拉雅FM电脑端,附带下载功能】

    今天给大家带来一款神器----JY播放器.可以不用打开网页就在电脑端听喜马拉雅FM的节目,而且可以直接下载,对于我这种强迫症患者来说真的是神器.我是真的不喜欢电脑任务栏上面密密麻麻的. 目前已经支持平 ...

  5. Facebook190亿美元收购WhatsApp

    Facebook收购WhatsApp,前后只花费10天时间.这是Facebook迄今规模最大的一笔收购,可能也是史上最昂贵的一笔针对靠私人风投起家的企业的收购案. 2月9日,马克•扎克伯格(Mark ...

  6. 互评Alpha版本——基于spec评论作品

    组名:可以低头,但没必要 组长:付佳 组员:张俊余  李文涛  孙赛佳  田良  于洋  刘欣  段晓睿 一.二次元梦之队----I DO 在测评该项目时,我们组索要了该组的apk程序,安装之后我就开 ...

  7. Scrum立会报告+燃尽图(十月十八日总第九次):功能细化与数据库设计

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246 项目地址:https://git.coding.net/zhang ...

  8. 效能检测 psp

    1.本周psp: 2.本周进度条: 3.累计进度图(折线图) 4.psp饼状图:

  9. YQCB冲刺周第一天

    团队讨论的照片 任务看板为 今天小组成员讨论了每个页面的排版,每个页面的跳转,以及页面的排版. 今天准备编写登录界面的.注册界面的代码. 遇到的困难是用户记账时选择的分类标准很多,最后将其整合,删减.

  10. int 和 Integer的区别

    int是基本类型,默认值为0,int a=5;a只能用来计算,一般作为数值参数. Integer是引用类型,默认值为null, Integer b=5;b是一个对象,它可以有很多方法,一般做数值转换, ...