异步io

Flink异步IO学习记录

荒凉一梦 提交于 2020-01-11 15:52:11
国际惯例,先把 官方文档 介绍一波 加入flink每次IO都要去访问数据库,那么数据库读取都是基于磁盘IO,速度肯定很慢,所以这里会成为流处理的一个性能瓶颈. 那么异步IO就是把原来的同步请求异步化,总的耗时被多次IO分摊掉了. Asynchronous interaction with the database means that a single parallel function instance can handle many requests concurrently and receive the responses concurrently. 这里的异步指的是一个并发度为1的函数可以并发地发起多个请求和并发地接收多个应答 那你可能会问,为什么不干脆把函数的parallelism提高呢? parallelism is in some cases possible as well, but usually comes at a very high resource cost: Having many more parallel MapFunction instances means more tasks, threads, Flink-internal network connections, network connections to the database,

网络编程进阶:并发编程之协程、IO模型

三世轮回 提交于 2020-01-10 06:56:57
协程: 基于单线程实现并发,即只用一个主线程(此时可利用的CPU只有一个)情况下实现并发; 并发的本质:切换+保存状态 CPU正在运行一个任务,会在两种情况下切走去执行其他任务(切换有操作系统强制控制),一种情况是该任务发生了阻塞,另一种是该任务计算的时间过长或有一个优先级更高的程序替代了它 在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 如果多个任务都是纯计算的,上图的情况2并不能提升效率,因为只是让CPU来回切,这样看起来所有任务都被“同时”执行的效果,此时这种切换反而会降低效率; yield本身就是一种在单线程下可以保存任务运行状态的方法,其特点如下:   1. yield可以保存状态,yield的状态保存于操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级   2. send可以把一个函数的结果传递给另外一个函数,以此实现单线程内程序之间的切换;yield并不能实现遇到io切换 在任务1遇到io情况下,切到另外一个任务去执行,这样就可以利用任务1阻塞的时间完成其他任务的计算,效率的提升就在此处 对于单线程下,我们不可避免程序中出现io操作,如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另一个任务去计算

【转】JAVA BIO与NIO、AIO的区别

你。 提交于 2020-01-09 22:23:17
Java中IO的模型分为三种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。 BIO【同步阻塞】 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。 NIO【同步非阻塞】 NIO本身是基于事件驱动思想来完成的,其主要想解决的是BIO的大并发问题: 在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。 NIO基于Reactor,当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。 也就是说,这个时候

协程gevent模块和猴子补丁

亡梦爱人 提交于 2020-01-09 10:35:22
一、协程定义 协程其实可以认为是比线程更小的执行单元。 为啥说他是一个执行单元,因为他自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。 二、协程切换和线程切换对比 线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。 三、协程带来的问题 协程有一个问题,就是系统并不感知,所以操作系统不会帮你做切换。 那么谁来帮你做切换?让需要执行的协程更多的获得CPU时间才是问题的关键。 举个例子如下: 目前的协程框架一般都是设计成 1:N 模式。所谓 1:N 就是一个线程作为一个容器里面放置多个协程。 那么谁来适时的切换这些协程?答案是有协程自己主动让出CPU,也就是每个协程池里面有一个调度器, 这个调度器是被动调度的。意思就是他不会主动调度。而且当一个协程发现自己执行不下去了(比如异步等待网络的数据回来,但是当前还没有数据到), 这个时候就可以由这个协程通知调度器,这个时候执行到调度器的代码,调度器根据事先设计好的调度算法找到当前最需要CPU的协程。

Java IO

我的梦境 提交于 2020-01-08 12:11:07
java IO 1.IO相关概念 1.1什么是IO 所谓IO即input和output的缩写,是对数据的流入和流出的一种抽象,编程中很常见的一个概念。 1.2什么是流 体会一下这几个词:水流(静止的水想必没人会叫水流),物流,人流(此人流非彼人流 = =!),可以发现流的特点:动态的,可转移 的,从一处到另一处的 1.3 java io java为了我们调用方便,而屏蔽输入/输出源和流动细节,抽象出的用于解决数据流动问题的类体系,这就是java的io流 1.4 输入流和输出流 用于读取的流称为输入流,用于写入的流称为输出流。输入输出的概念一般针对内存来说的 1.5 字节流和字符流 输入输出流可操作的最小单位来区分字节流和字符流,最小单位是一个字节(8bit)的为字节流, 最小单位是一个字符(16bit)的为字符流。 1.6 节点流和包装(处理)流 1)节点流偏向实现细节,直接与细节打交道,比如FileInputStream,而包装(处理)流偏功能,以目标功能为抽象,比如PrintStream。 2)区分节点流和包装(处理)流最简单的一个方式:处理流的构造方法中需要另一个流作为参数,而节点流构造方法则是具体的物理节点,如上FileInputStream构造法中需要一个文件路径或者File对象, 而PrintStream构造方法中则需要一个流对象 3)包装流使用了装饰器模式

深入理解libaio 接口

僤鯓⒐⒋嵵緔 提交于 2020-01-07 13:50:19
也许大家都会使用libaio接口,但它和内核是如何交互的呢?内核的机制又是怎样的呢?下面就一起跟踪下主要的流程。 登堂入室:系统调用 依赖的头文件 #include <errno.h> #include <sys/syscall.h> #include <unistd.h> 主要的函数: /* Actual syscalls */ int io_setup(int maxevents, io_context_t *ctxp) { return syscall(__NR_io_setup, maxevents, ctxp); } int io_destroy(io_context_t ctx) { return syscall(__NR_io_destroy, ctx); } int io_submit(io_context_t ctx, long nr, struct iocb *ios[]) { return syscall(__NR_io_submit, ctx, nr, ios); } int io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt) { return syscall(__NR_io_cancel, ctx, iocb, evt); } (待跟踪问题:io_get_events()

Unix IO模型

怎甘沉沦 提交于 2020-01-07 00:45:38
Unix下可用的IO模型有五种 [1] : 阻塞式IO 非阻塞式IO IO复用(select和poll) 信号驱动IO(SIGIO) 异步IO(POSIX的aio_系列函数) 下面介绍自己对前三种IO模型的理解,后面两种模型如果之后有机会接触到,再回来补充! 阻塞式IO 程序执行一个系统调用时,会进行休眠等待返回结果,不在执行之后的代码 比如服务器端以阻塞IO方式调用read()读取客户端发来的数据时,代码和流程如下所示: while(connSocket.read(buf, BUFFER_SZ) > 0){ // 1 // 处理接收到的数据 // 2 } 调用read()函数,由用户态切换到内核态,查看接收缓存区是否有数据,如果有数据,则将数据从内核拷贝到用户空间,否则等待对端发送数据,此时应用进程阻塞在1处,无法继续执行,直到read()返回 可见阻塞IO效率低,因为阻塞等待是在浪费进程所获得的执行机会,所以一般采用非阻塞方式编写服务器程序 注意:read()并不一定是阻塞的,取决于套接字是否是阻塞的 非阻塞式IO 非阻塞IO是系统调用时不会等待数据准备好才返回,而是立即返回,此时可以执行之后的程序,所以程序运行过程中没有进入休眠状态 比如以非阻塞方式调用read()读取对端发来数据的过程: for(;;){ len = connSocket.read(buf, BUFFER

Netty学习笔记

夙愿已清 提交于 2020-01-06 16:16:54
目录 IO模型 NioEventLoop 设计模式 IO模型 IO操作分两步: 1)发起IO请求等待数据准备. 2)实际IO操作. 1. 阻塞与非阻塞 阻塞和非阻塞关注的是: 线程在等待调用结果(消息,返回值)时的状态. 阻塞调用是指调用结果返回之前,当前线程会被挂起。 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。 2.同步与异步 同步和异步关注的是:消息通信机制 所谓同步,就是在发出一个 调用 时,在没有得到结果之前,该 调用 就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是 由 调用者 主动等待这个 调用 的结果。 而异步则是相反, 调用 在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步调用发出后,调用者不会立刻得到结果。而是在 调用 发出后, 被调用者 通过状通知来通知调用者,或通过回调函数处理这个调用。 同步须要主动读写数据,在读写数据的过程中还是会阻塞。 异步仅仅须要I/O操作完毕的通知。并不主动读写数据,由操作系统内核完毕数据的读写。 同步IO和异步IO是针对用户应用程序和内核的交互。 Unix提供了五种IO模式,分别是: 阻塞IO 非阻塞IO IO复用 信号驱动IO 异步IO 前四种IO模型都是同步IO操作,区别在于第一阶段,而他们的第二阶段是一样的:在数据从内核复制到应用缓冲区期间(用户空间)

同步/异步/阻塞/非阻塞/BIO/NIO/AIO

我怕爱的太早我们不能终老 提交于 2020-01-04 04:56:34
转摘自:https://www.cnblogs.com/lixinjie/p/a-post-about-io-clearly.html 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据。 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTTP响应,然后继续往下执行。 这个时候你问别人,刚刚代码发起的这个请求是不是一个同步请求,对方一定回答是。这是对的,它确实是。 但你要问它为什么是呢?对方一定是这样回答的,“因为发起请求后,代码就卡住不动了,直到拿到响应后才可以继续往下执行”。 我相信很多人也都是这样认为的,其实这是不对的,是把因果关系搞反了: 不是因为代码卡住不动了才叫同步请求,而是因为它是同步请求所以代码才卡住不动了。 至于为什么能卡住不动,这是由操作系统和CPU决定的: 因为内核空间里的对应函数会卡住不动,造成用户空间发起的系统调用卡住不动,继而使程序里的用户代码卡住不动了。 因此卡住不动了只是同步请求的一个副作用,并不能用它来定义同步请求,那该如何定义呢? 同步和异步 所谓同步,指的是协同步调。既然叫协同,所以至少要有2个以上的事物存在。协同的结果就是: 多个事物不能同时进行,必须一个一个的来,上一个事物结束后,下一个事物才开始。 那当一个事物正在进行时,其它事物都在干嘛呢?

迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

陌路散爱 提交于 2020-01-04 04:56:09
常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据。 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTTP响应,然后继续往下执行。 这个时候你问别人,刚刚代码发起的这个请求是不是一个同步请求,对方一定回答是。这是对的,它确实是。 但你要问它为什么是呢?对方一定是这样回答的,“因为发起请求后,代码就卡住不动了,直到拿到响应后才可以继续往下执行”。 我相信很多人也都是这样认为的,其实这是不对的,是把因果关系搞反了: 不是因为代码卡住不动了才叫同步请求,而是因为它是同步请求所以代码才卡住不动了。 至于为什么能卡住不动,这是由操作系统和CPU决定的: 因为内核空间里的对应函数会卡住不动,造成用户空间发起的系统调用卡住不动,继而使程序里的用户代码卡住不动了。 因此卡住不动了只是同步请求的一个副作用,并不能用它来定义同步请求,那该如何定义呢? 同步和异步 所谓同步,指的是协同步调。既然叫协同,所以至少要有2个以上的事物存在。协同的结果就是: 多个事物不能同时进行,必须一个一个的来,上一个事物结束后,下一个事物才开始。 那当一个事物正在进行时,其它事物都在干嘛呢? 严格来讲这个并没有要求,但一般都是处于一种“等待”的状态,因为通常后面事物的正常进行都需要依赖前面事物的结果或前面事物正在使用的资源。