本文来自官网翻译: Asynchronous I/O for External Data Access

本页介绍了Flink API与外部数据存储的异步I / O的使用。对于不熟悉异步或事件驱动编程的用户,有关Futures和事件驱动编程可能是有用的准备。

注:有关异步I / O实用程序的设计和实现的详细信息,请参阅提议和设计文档 FLIP-12:异步I / O设计和实现

需要异步I / O操作

当与外部系统交互时(例如,当使用存储在数据库中的数据来丰富流事件时),需要注意与外部系统的通信延迟不会主导流应用程序的工作。

访问外部数据库中的数据,例如在 MapFunction中,通常意味着同步交互:将请求发送到数据库并MapFunction等待直到收到响应。在许多情况下,这种等待构成了功能的绝大部分时间。

与数据库的异步交互意味着单个并行函数实例可以同时处理许多请求并同时接收响应。这样,等待时间可以覆盖发送其他请求和接收响应。至少,等待时间是在多个请求上分摊的。可以使大多数情况下流量吞吐量更高。

注意:MapFunction在某些情况下,仅通过扩展到非常高的并行度来提高吞吐量,但通常会产生非常高的资源成本:拥有更多并行MapFunction实例意味着更多任务,线程,Flink内部网络连接,网络与数据库,缓冲区和一般内部数据开销。

先决条件

如上一节所示,对数据库(或键/值存储)实现适当的异步I / O需要客户端访问支持异步请求的数据库。许多流行的数据库提供这样的客户端

在没有这样的客户端的情况下,可以通过创建多个客户端并使用线程池处理同步调用来尝试将同步客户端转变为有限的并发客户端。但是,这种方法通常比适当的异步客户端效率低。

异步I / O API

Flink的Async I / O API允许用户将异步请求客户端与数据流一起使用。API处理与数据流的集成,以及处理顺序,事件时间,容错等。

假设有一个目标数据库的异步客户端,需要三个部分来实现对数据库的异步I / O流转换:

  • 实现AsyncFunction分派请求
  • 一个callback,它接收操作的结果并将其交给ResultFuture
  • 在DataStream上应用异步I / O操作作为转换

以下代码示例说明了基本模式:

Java

// 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);

scala

/**
* An implementation of the 'AsyncFunction' that sends requests and sets the callback.
*/
class AsyncDatabaseRequest extends AsyncFunction[String, (String, String)] { /** The database specific client that can issue concurrent requests with callbacks */
lazy val client: DatabaseClient = new DatabaseClient(host, post, credentials) /** The context used for the future callbacks */
implicit lazy val executor: ExecutionContext = ExecutionContext.fromExecutor(Executors.directExecutor()) override def asyncInvoke(str: String, resultFuture: ResultFuture[(String, String)]): Unit = { // issue the asynchronous request, receive a future for the result
val resultFutureRequested: Future[String] = client.query(str) // set the callback to be executed once the request by the client is complete
// the callback simply forwards the result to the result future
resultFutureRequested.onSuccess {
case result: String => resultFuture.complete(Iterable((str, result)))
}
}
} // create the original stream
val stream: DataStream[String] = ... // apply the async I/O transformation
val resultStream: DataStream[(String, String)] =
AsyncDataStream.unorderedWait(stream, new AsyncDatabaseRequest(), 1000, TimeUnit.MILLISECONDS, 100)

重要提示:ResultFuture在第一次通话时完成ResultFuture.complete。所有后续complete调用都将被忽略。

以下两个参数控制异步操作​​:

  • Timeout:超时定义异步请求在被视为失败之前可能需要多长时间。此参数可防止死亡/失败请求。

  • Capacity:此参数定义可以同时进行的异步请求数。尽管异步I / O方法通常会带来更好的吞吐量,但异步I / O 的操作仍然可能成为流应用程序的瓶颈。限制并发请求的数量可确保操作不会不断累积,积压增加的待处理请求,一旦容量耗尽,它将触发反压。

超时处理

当异步I / O请求超时时,默认情况下会引发异常并重新启动作业。如果要处理超时,可以覆盖该AsyncFunction#timeout方法。

结果顺序

AsyncFunction一些未定义的顺序经常完成的并发请求,基于哪个请求首先完成。为了控制发出结果记录的顺序,Flink提供了两种模式:

  • 无序:异步请求完成后立即发出结果记录。在异步I / O运算符之后,流中记录的顺序与以前不同。当使用处理时间作为基本时间特性时,此模式具有最低延迟和最低开销。使用AsyncDataStream.unorderedWait(...)此模式。

  • 有序:在这种情况下,保留流顺序。结果记录的发出顺序与触发异步请求的顺序相同(运算符输入记录的顺序)。为此,运算符缓冲结果记录,直到其所有先前记录被发出(或超时)。这通常会在检查点中引入一些额外的延迟和一些开销,因为与无序模式相比,记录或结果在检查点状态下保持更长的时间。使用AsyncDataStream.orderedWait(...)此模式。

活动时间

当流应用程序与事件时间一起工作,异步I / O操作符将正确处理水印。这意味着两种订单模式具体如下:

  • Unordered:水印不会超过记录,反之亦然,这意味着水印建立了一个顺序边界。记录仅在水印之间无序发出。只有在发出水印后才会发出某个水印后发生的记录。反过来,只有在发出水印之前输入的所有结果记录之后才会发出水印。

    这意味着,在水印的存在,将无序的方式介绍了一些相同的延迟和管理开销的顺序模式一样。开销量取决于水印频率。

  • Ordered:保留记录的水印顺序,就像保留记录之间的顺序一样。与处理时间相比,开销没有显着变化。

请记住,摄取时间事件时间的特殊情况,其中自动生成的水印基于源处理时间。

容错保证

异步I / O运算符提供精确一次的容错保证。它在检查点中存储正在进行的异步请求的记录,并在从故障中恢复时恢复/重新触发请求。

实施技巧

对于使用Executor(或Scala中的ExecutionContext)进行回调的Futures实现,我们建议使用DirectExecutor,因为回调通常只做最小的工作,而DirectExecutor避免了额外的线程到线程的切换开销。 回调通常只将结果传递给ResultFuture,后者将其添加到输出缓冲区。 从那里开始,包括记录发射和与检查点簿记交互的重要逻辑无论如何都发生在专用线程池中。

警告

AsyncFunction不是为多线程

我们想在这里明确指出的常见混淆AsyncFunction是以多线程方式调用。只存在一个实例,AsyncFunction并且对于流的相应分区中的每个记录顺序调用它。除非该asyncInvoke(...)方法快速返回并依赖于回调(由客户端),否则它将不会导致适当的异步I / O.

例如,以下模式会导致阻塞asyncInvoke(...)函数,从而使异步行为无效:

  • 使用其查找/查询方法调用阻塞的数据库客户端,直到收到结果为止

  • 阻止/等待asyncInvoke(...)方法内异步客户端返回的future-type对象

实例:Flink 异步IO访问外部数据(mysql篇)

【翻译】Flink 异步I / O访问外部数据的更多相关文章

  1. Flink学习笔记:异步I/O访问外部数据

    本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...

  2. Flink 异步IO访问外部数据(mysql篇)

    接上篇:[翻译]Flink 异步I / O访问外部数据 最近看了大佬的博客,突然想起Async I/O方式是Blink 推给社区的一大重要功能,可以使用异步的方式获取外部数据,想着自己实现以下,项目上 ...

  3. salesforce 零基础学习(三十三)通过REST方式访问外部数据以及JAVA通过rest方式访问salesforce

    本篇参考Trail教程: https://developer.salesforce.com/trailhead/force_com_dev_intermediate/apex_integration_ ...

  4. Flink 中定时加载外部数据

    社区中有好几个同学问过这样的场景: flink 任务中,source 进来的数据,需要连接数据库里面的字段,再做后面的处理 这里假设一个 ETL 的场景,输入数据包含两个字段 “type, useri ...

  5. Microsoft EDP(enterprise database protection)选择应用程序在哪里可以访问企业数据

    在配置策略时,对Rule template设置完成后,添加corporate identity.关于corporate identity, 目前没有什么好的理解,翻译过来就是“公司标识”,我也理解不了 ...

  6. BPM配置故事之案例10-获取外部数据

    老李:Hi,小明,我又来了 小明:--这次又怎么了. 老李:之前的物资管理方式太混乱了,这段时间我整理了采购物资清单,现在都录入到我们的ERP中了,以后申请物资改成从ERP数据选择吧.物资明细表我也做 ...

  7. Android4.4访问外部存储

    在Android 4.4系统中,外置存储卡(SD卡)被称为二级外部存储设备(secondary storage),应用程序已无法往外置存储卡(SD卡)写入数据,并且WRITE_EXTERNAL_STO ...

  8. jquery的ajax异步请求接收返回json数据

    http://www.jb51.net/article/51122.htm jquery的ajax异步请求接收返回json数据方法设置简单,一个是服务器处理程序是返回json数据,另一种就是ajax发 ...

  9. ArcGIS for WPF 访问外部资源【进阶之构造URL】

    原文 http://www.cnblogs.com/wdysunflower/archive/2013/05/29/3039645.html 呵呵~好久没逛园子,没写博客了. 最近刚好又在弄GIS这块 ...

随机推荐

  1. Web开发技术---简单的登录验证

    制作一个APP或系统最基础的是登录界面,下面通过一个简单的登录注册界面的程序,来熟练掌握Web开发的技术. 一.知识点: 1.在网页界面获取用户的输入信息 2.标签的基本应用 3.用户输入结果的错误提 ...

  2. PHP项目部署 Linux 服务器

    一.运行环境 Centos7 x64 lnmp (Linux , Nginx , Mysql , PHP/Python) 二.安装依赖和修改配置 安装Lnmp环境集成包:https://lnmp.or ...

  3. Tensorflow细节-P160-迁移学习

    这是一个完整的程序,值得保存 1.对图片进行预处理并保存 import glob import os.path import numpy as np import tensorflow as tf f ...

  4. php流程控制 之循环语句的使用

    循环语句的使用 王同学需要反复往返于北京和大连,就是典型的循环结构.假设王思总投资这个项目需要往返大连100次,每次往返都王同学都会计数一次.难道我们写一百遍同样的代码?显然对于智商极高的程序员来说不 ...

  5. NoSql数据库使用半年后在设计上面的一些心得 (转载)

    NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚.但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题? 这个疑惑非常大,为此我看了很多分析文章, ...

  6. A tow-day exam

    D1 T1l \(des:\) 给出一棵树,判断树上两条路径是否相交 \(sol:\) 判断其中一条路径的两个端点以及两端点的 \(lca\) 是否存在于另一条链上 由于这是一棵树,任一点为根后这样判 ...

  7. 生活中需要一台mac本子

    用了好多年的windows系统,各种快捷键玩得飞起.当时对mac笔记本的印象就是. mac本子好高大上,搞设计的人才会去用的.(这个也是我听其他人说的) 在当时公司搞IOS开发的人中,面对这个高大上的 ...

  8. linux系统下常用的打包/解压缩包命令

    此处大概列了常用的解压和打包命令,详细信息需要百度一一对比他们的区别,比如我们在下载软件时就是最好的实践. 用zip举例说明,使用命令压缩时有点是,压缩文件.目录会非常快:如图,我压缩了一个progr ...

  9. Large-Scale Oil Palm Tree Detection from High-Resolution Satellite Images Using Two-Stage Convolutional Neural Networks(worldview油棕树检测)

    不是目标检测也不是语义分割,两步CNN指的是,采集的数据是一堆点,以点为中心的65*65和17*17图像范围大小来判断这个点是否是油棕树.第一步就是判断65*65的范围是否为(油棕树植被群,其他植被/ ...

  10. WSL2(Ubuntu)安装Postgres

    原文链接:https://www.xu.ci/2019/12/wsl2ubuntupostgres.html 原文作者:博客园--曲高终和寡 *******************如果你看到这一行,说 ...