精华内容
下载资源
问答
  • 流处理基本介绍

    万次阅读 多人点赞 2017-01-23 10:14:56
    1. 什么是流处理 一种被设计来处理无穷数据集的数据处理系统引擎 2. 流处理的几个概念 1. 无穷数据(Unbounded data):一种持续生成,本质上是无穷尽的数据集。它经常会被称为“数据”。然而,用和批次来...


    1.  什么是流处理

    一种被设计来处理无穷数据集的数据处理系统引擎

    2.  流处理的几个概念

    1.     无穷数据(Unbounded data):一种持续生成,本质上是无穷尽的数据集。它经常会被称为“流数据”。然而,用流和批次来定义数据集的时候就有问题了,因为如前所述,这就意味着用处理数据的引擎的类型来定义数据的类型。现实中,这两类数据的本质区别在于是否有限,因此用能体现出这个区别的词汇来定性数据就更好一些。因此我更倾向于用无穷数据来指代无限流数据集,用有穷数据来指代有限的批次数据。

    2.     无穷数据处理(Unbounded dataprocessing):一种发展中的数据处理模式,应用于前面所说的无穷数据类型。尽管我本人也喜欢使用流式计算来代表这种类型的数据处理方式,但是在本文这个环境里,这个说法是误导的。用批处理引擎循环运行来处理无穷数据这个方法在批处理系统刚开始构思的时候就出现了。相反的,设计完善的流计算系统则比批处理系统更能承担处理有穷数据的工作。因此,为了清晰明了,本文里我就只用无穷数据处理。

    3.     低延迟,近似和/或推测性结果(Low-latency,approximate,and/or speculative results):这些结果和流处理引擎经常关联在一起。批处理系统传统上不是设计来处理低延迟或推测性结果这个事实仅仅是一个历史产物,并无它意。当然,如果想,批处理引擎也完全能产生近似结果。因此就如其他的术语,最好是用这些术语是什么来描述这些结果,而不是用历史上它们是用什么东西(通过流计算引擎)产生的来描述。

    3.  流处理的六种方式

    3.1.  Event Sourcing

    Event Sourcing是由老马(Martinfowler)提出来的一种模式,可以解释为事件溯源,该模式从事件源开始保存应用程序状态,保证每次更改都可以被保存为事件序列,也就是说,它不仅保存时间的自身,还保存时间的所有状态变化,在有需要的时候,可以随时根据时间日志重建当时状态,即不仅能做到知道在哪里,也能做到知道如何到那里去的,它会完整的描述对象的整个生命周期中经历的所有事件。

    这方面典型的架构就是LMAX。

    3.2.  Reactive

    反应式编程,也称为响应式编程。顾名思义,就是根据用户的输入来做出响应。这种动作一般是实时的。

    根据响应式编程宣言所述,反应式变成一般具有如下几个特点:

    响应:响应性是系统高可用的基础,但更重要的是,响应性意味着可以快速检测问题并处理问题。响应系统专注于提供快速一致的响应时间,建立可靠的上限,以便提供一致的服务质量,从而简化错误处理,建立用户信息,并鼓励做出更进一步的交互。

    弹性:系统在面对失败时候,仍然保持响应。

    弹性:系统在负载变化的时候仍然保持响应。我们可以通过增加或者减少分配给这些服务的资源来对负载变化做出响应。这意味着整个设计没有竞争和单点瓶颈。

    消息驱动:响应式系统依靠异步消息在组件之间建立一个边界,确保组件之间的松耦合和隔离性。这个边界还提供了失败委托,负载均衡,弹性和流控等手段来保证系统的高可用性,这是响应式系统的一个必备特点。

    3.3.  CEP

    Complex event processing。复杂事件处理。

    事件即事物的状态信息变化,事物之间的作用的动作。复杂事件处理描述的就是系统如何持续地处理这些事件,对系统对变化的持续反应。不论是个体还是系统,都需要从大量的实践中过滤提取,按照既定的处理反应规则做处理。CEP主要依靠规则语言或者持续查询语言来完成事件的过滤、判断和处理。

    这类典型应用比如Esper,TIBCO,IBM Streams等。

    3.4.  Stream Processing

    这个流处理架构,从大数据量领域发展起来的实时数据处理模型,其主要强调分布式,高性能,高可靠性。目前主要有Storm,Flink,Spark Streaming等,这类介绍的比较多,这里就不详细介绍了。

    3.5.  Actors/SEDA

    SEDA(Staged event-driven architecture) 阶段事件驱动架构,也成为阶段是服务器模型,其主要是将复杂的,事件驱动的应用分解为一系列通过队列连接的阶段,从而避免线程的并发模型带来高负载问题,同时还可以达到解耦,负载均衡,分布式等特性。

    Actor模型包装了消息传输和封装机制,用户只需要面对消息和业务逻辑,因此天然就具有分布式、高并发、无状态的特性;对外提供简单编程接口。

    这类应用,典型的有Apache Gearpump(基于Akka),Kafka Streams等。

    3.6.  Change Capture

    变更数据捕获,捕捉数据库插入、更新和删除的动作并作出相应反应。

    目前很多数据库都提供这样的功能,能够将数据操作日志导出并可以由其他工具导入Kafka等系统中来做二次处理。比如Kafka,Mysql等都提供这样的功能。

    4.  流处理的发展目标

    但是Kafka Streams的作者提出了一个观点,个人非常赞同,

     

    So what did we learn?Lots. One of the key misconceptions we had was that stream processing would beused in a way sort of like a real-time MapReduce layer. What we eventually cameto realize, though, was that the most compelling applications for streamprocessing are actually pretty different from what you would typically do witha Hive or Spark job—they are closer to being a kind of asynchronousmicroservice rather than being a faster version of a batch analytics job.

    What do I mean by this? What Imean is that these stream processing apps were most often software thatimplemented core functions in the business rather than computing analyticsabout the business.

     

    翻译过来的核心观点就是:

    我们曾经有过的一个关键的错觉是以为流处理将会被以一种类似于实时的MapReduce层的方式使用。我们最终却发现,大部分对流处理有需求的应用实际上和我们通常使用Hive或者Spark job所做的事情有很大不同,这些应用更接近于一种异步的微服务,而不是批量分析任务的快速版本

    大部分流处理程序是用来实现核心的业务逻辑,而不是用于对业务进行分析

    流处理当前需要在如下几个方面进行进入以保证自己的核心竞争力。

    1.     强一致性:这保证流计算能和批处理平起平坐。

    本质上,准确性取决于存储的一致性。流计算系统需要一些类似于checkpoint的方法来保证长时间的持久化状态。几年前,当Spark刚刚出现在大数据领域的时候,它几乎就是照亮了流计算黑暗面的灯塔(因为Spark支持强一致)。在这之后,情况越来越好。但是还是有不少流计算系统被设计和开发成尽量不去支持强一致性。目前Flink,Kafka Streams也能够支持强一致性,这简直就是流处理的福音。

    再次强调一遍重点:强一致性必须是“只处理一次(exactly-onceprocessing)”,这样才能保证正确性。只有这样的系统才能追平并最终超越批处理系统。除非你对计算的结果是否正确并不介意,否则我还是请你放弃任何不能保证强一致性的流计算系统。现有的批处理系统都保证强一致性,不会让你在使用前去检查计算结果是否正确。所以也不要浪费你的时间在那些达不到这样标准的流计算系统上。

    2. 时间推理的工具:这一点让流计算超越批处理。

    在处理无穷的、无序的、事件—时间分布不均衡的数据时,好的时间推理工具对于流计算系统是极其重要的。现在越来越多的数据已经呈现出上面的这些特征,而现有的批处理系统(也包括几乎所有的流计算系统)都缺少必要的工具来应对这些特性带来的难题。

    3、弹性伸缩功能,即在保证Exactly-once 语义的情况下,流处理应用无需用户的介入也能自动修改并发数,实现应用的自动扩容和缩容。

    4、流上的SQL查询功能以及完整SQL支持,包含窗口,模式匹配等语法支持。


    5.  时间

    流处理系统中的时间分为两种:事件时间和处理时间。

    事件时间(Event Time): 事件发生的时间

    处理时间(Processing Time) 事件处理的时间。

    时间是流处理的基础,绝大部分场景都对时间又严格要求。(PS如果没有的话,那这个世界简直就太简单了。)

    Kafka Streams系统中就要求必须以包含时间,如果没有事件时间,就必须在保存的时候添加系统时间。

    我们能够基于时间来对数据做聚合,实现窗口功能,能够解决乱序问题,总之,时间是流处理最为重要的一个因素。

    6.  Lambda架构

    Lambda架构最初是由Storm的创始人NatanMarz在2011年提出的。在他的文章《How to beat the CAP theorem》中提出了Lambda架构,通过流和批的融合,实现快速的实时数据处理,或者说是让批来为流提供服务。

    一个典型的lambada的架构来自于下面的图。


    这在当时是一个影响力很大的架构,并且有很多产品是基于该架构的,但是随着技术的演进,在现在看来,还是有很大问题的。比如:

    1、  lambda架构要搭建部署和维护两套队列的集群,并且对结果做合并,这是十分麻烦的,并且可靠性也是相当差的。

    2、  数据冗余,数据要同时进入两套系统,存放两份。

    7.  乱序问题

    分布式的流处理系统,不可避免的会遇到数据的乱序问题,数据乱序就是指数据达到某一个节点的时候,已经不是按照原来发生的顺序了,期间可能有丢失,错乱等。

             乱序问题一般的处理方式是使用时间排序窗口,不论是系统时间驱动还是事件时间驱动。其实就是数据在进入节点之后,按照时间进行排序,然后等待一段时间,等待事件都已经到达之后再来进行下一步操作。如果无法确定事件都已经到达,或者是由部分时间一直没有达到,那么就等到窗口超时为止,然后计算结果。

             这个时候计算出来的结果,在有的系统里面已经作为最终结果,直接输出了,即使后续时间过了很长时间已经到达了,也是直接丢弃,不会影响最终结果。在另外一些系统中,比如google的MillWheel中,有水印(WaterMark)机制可以在事件最终到来之后,重新计算并刷新结果。

    8.  数据可靠性问题

    流上的可靠性一直是一个老大难问题,在和业界其他人交流的时候,也纷纷摇头,这个问题无解。目前流处理最广泛的应用还是做一些不怎么关注可靠性的计算。

    不过这个问题在2016年有了很大的突破。

    Intel在2016年终于发布了自己的内存快照技术,通过使用新的存储介质,能够达到内存一半的存取速度,这是一个很了不起的成就,已经基本可以商用了,在流计算领域,为了性能考虑,数据都是保存在内存中的,如果操作系统能够自动完成快照,那就很大程度上保证了数据的可靠性,流处理系统就可以完全不用关注这些什么状态,数据等信息,内存里面已经全部都有了。如果Intel能够做到增量式的内存快照,或者是快照速度和内存读取速度一致,甚至更快的时候,流处理系统的春天就会到来,哪个时候,流处理系统就会变得无比简单。

    在硬件得到突破的同时,软件方面也在不断的取得突破。

    Flink的流处理系统实现了CheckPoint功能,能够将窗口数据保存到内存当中,当流计算发生故障的时候,得到快速恢复,目前功能已经可用,不过性能还是会差一些,在百万TPS级别,快照速度在秒级,还是稍微有些慢,不过已经可用。

    Kafka Streams的推出,利用Kafka消息队列自身Offset的特性,再加上新开发的compact功能,成功实现了流和表的结果,并且也可以通过重放来实现可靠性,状态信息通过数据库保存,这也是流处理在可靠性方面的突破,利用外界第三方组件来实现自身的可靠性。

    流处理系统可靠性处理还有一种趋势就是数据库。数据库系统天然具有可靠性和事务性的特点,能够很好的适应金融等事务性和可靠性比较高的场景,唯一就是数据量和拓展性存在问题,但是随着分布式内存数据库等的发展,也许后面分布式内存数据库替代流处理系统也不是不可能的。但是无论怎么说,我们最求的是实时计算,而不是流处理系统,我们的目标是Fast Data。

    9.        流上的SQL

    以前,CEP和其他流处理平台上面的SQL是五花八门,各有各的特点,包括我们的StreamCQL,都属于类SQL的范畴,但是从现在来看,流上的SQL目前发展趋势已经很明显了,那就是兼容标准SQL,语义不能和标准SQL冲突,这个是第一步;然后就是做尽可能少的拓展,尽可能的利用其他数据库SQL中已有的语法,比如Oracle的Match  recognize等语法来实现模式匹配功能,这样用户最容易接受。窗口等特性,使用函数功能或者是复用SQL的 over语法即可。不支持的场景可以适当做少量拓展。总的来说,流式SQL还在拓展阶段,大家都在拼命抢地盘,想占领制高点,然后推广自己的语法。

     

    9.1.    流和表的关系

    流和表的关系是理解流上SQL的基础,也是最重要的

    流和表实际上是一体的。

    流很容易理解,就是一个管道,当有窗口存在的时候,数据才会发生汇聚。

    表就是我们通常理解的数据库的表。

    流上窗口中的数据,实际上就是一张表。同样的,当表上数据在不断发生变化的时候,这种changelog,就是流。

    这种观点现在已经基本成为流处理领域概念理解的标准。而且绝大部分数据库都支持的data capture,也是传统数据库为了和流处理相结合而做出的改变。Kafka Streams就包含data capture的工具,支持将数据从数据库中导入kafka成为一个流。

    9.2.    流和表的转换

    1)        流和计算结果是表,这一点在分组窗口上体现的特别明显。而且我们的使用习惯也和表一致。

    比如:

    我们统计最近10分钟各区域的用户点击次数,输出每个区域的总点击次数,那么一次性就会输出多行结果,每个地区一行记录,这个就是流上的聚合结果,也是流的中间状态;而为了可靠性,我们一般会将这些计算结果保存到数据库中,以便于故障时候的恢复。

    2)        表中每一次的数据变化,用change log体现就是流。

    3)        表和流之间的Join,实际上是窗口和表之间的Join

    10.         参考

    https://www.oreilly.com.cn/ideas/?p=18&from=timeline

    http://www.cnblogs.com/devos/p/5616086.html

    http://www.oreilly.com/data/free/stream-processing.csp

    http://www.martinfowler.com/eaaDev/EventSourcing.html

    http://www.reactivemanifesto.org/

    http://nathanmarz.com/blog/how-to-beat-the-cap-theorem.html

     

    展开全文
  • JAVA:IO 之 节点处理流(2)

    万次阅读 多人点赞 2017-05-15 15:37:24
    处理数据单位不同:字节,字符。 (1) 字节:数据中最小的数据单元是字节。 (2)字符:数据中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。 按功能不同:节点,...

    1. 流的分类

    • 按数据流的方向不同:输入流,输出流。
    • 按处理数据单位不同:字节流,字符流。
      (1) 字节流:数据流中最小的数据单元是字节。
      (2)字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。
    • 按功能不同:节点流,处理流。
      (1)程序用于直接操作目标设备所对应的类叫节点流。
      (2)程序通过一个间接流类去调用节点流类,以达到更加灵活方便地读写各种类型的数据,这个间接流类就是处理流。

    2. 节点流

    2.1 节点流的类型

    这里写图片描述

    • (1)File 文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream。、
    • (2)Memory
      1)从/向内存数组读写数据: CharArrayReader与 CharArrayWriter、ByteArrayInputStream与ByteArrayOutputStream。
      2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream。
    • (3)Pipe管道流。 实现管道的输入和输出(进程间通信): PipedReader与PipedWriter、PipedInputStream与PipedOutputStream。

    2.2 节点流执行的图示

    这里写图片描述

    3. 处理流

    3.1 处理流的类型

    这里写图片描述
    - (1)Buffering缓冲流:在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader与BufferedWriter、BufferedInputStream与BufferedOutputStream。
    - (2)Filtering 滤流:在数据进行读或写时进行过滤:FilterReader与FilterWriter、FilterInputStream与FilterOutputStream。
    - (3)Converting between Bytes and Characters 转换流:按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader):InputStreamReader、OutputStreamWriter。
    - (4)Object Serialization 对象流 :ObjectInputStream、ObjectOutputStream。
    - (5)DataConversion数据流: 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream 。
    - (6)Counting计数流: 在读入数据时对行记数 :LineNumberReader、LineNumberInputStream。
    - (7)Peeking Ahead预读流: 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream。
    - (8)Printing打印流: 包含方便的打印方法 :PrintWriter、PrintStream。

    3.2 处理流执行的图示

    这里写图片描述

    3.3 缓冲流

    • 【1】对I/O进行缓冲是一种常见的性能优化,缓冲流为I/O流增加了内存缓冲区,增加缓冲区的两个目的:
      (1)允许Java的I/O一次不只操作一个字符,这样提高䇖整个系统的性能;
      (2)由于有缓冲区,使得在流上执行skip、mark和reset方法都成为可能。

    • 【2】缓冲流:它是要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,
      提高了读写的效率,同时增加了一些新的方法。例如:BufferedReader中的readLine方法,
      BufferedWriter中的newLine方法。

    • 【3】J2SDK提供了4种缓存流,常用的构造方法为:

    //字符输入流
    BufferedReader(Reader in)//创建一个32字节的缓冲区
    BufferedReader(Reader in, int size)//size为自定义缓存区的大小
    
    //字符输出流
    BufferedWriter(Writer out)
    BufferedWriter(Writer out, int size)
    
    //字节输入流
    BufferedInputStream(InputStream in)
    BufferedInputStream(InputStream in, int size)
    
    //字节输出流
    BufferedOutputStream(OutputStream in)
    BufferedOutputStream(OutputStream in, int size)
    • 【4】其他
      (1)缓冲输入流BufferedInputSTream除了支持read和skip方法意外,还支持其父类的mark和reset方法;
      (2)BufferedReader提供了一种新的ReadLine方法用于读取一行字符串(以\r或\n分隔);
      (3)BufferedWriter提供了一种新的newLine方法用于写入一个行分隔符;
      (4)对于输出的缓冲流,BufferedWriter和BufferedOutputStream,写出的数据会先在内存中缓存,
      使用flush方法将会使内存的数据立刻写出。

    • 示例1:

    import java.io.*;
    public class TestBufferStream1 {
      public static void main(String[] args) {
        try {
          FileInputStream fis = new FileInputStream(
              "d:\\JavaProject\\demo13\\ProcessingStream\\TestBufferStream1.java");
          BufferedInputStream bis = new BufferedInputStream(fis);
          int c = 0;
          System.out.println((char)bis.read());
          System.out.println((char)bis.read());
          bis.mark(100);/*在当前输入流的当前位置上做一个标志,允许最多再读入100个字节*/
          for(int i=0;i<=10 && (c=bis.read())!=-1;i++){
            System.out.print((char)c+" ");
          }
          System.out.println(); 
          bis.reset();/*把输入指针返回到以前所做的标志处*/
          for(int i=0;i<=10 && (c=bis.read())!=-1;i++){
            System.out.print((char)c+" ");
          }
          bis.close();
        } catch (IOException e) {e.printStackTrace();}
      }
    }
    • 示例2:
    import java.io.*;
    public class TestBufferStream2
    {
        public static void main(String[] args)
        {
        try{
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\JavaProject\\demo13\\BufferStream\\dat2.txt"));
        BufferedReader br = new BufferedReader(new FileReader("D:\\JavaProject\\demo13\\BufferStream\\dat2.txt"));
        String s = null;
        for(int i=0;i<10;i++)
        {
            s = String.valueOf(Math.random());//产生一个小于1的正的随机数,并转换成字符串形式
            bw.write(s);//把字符串s写入到dat2.txt文件中
            bw.newLine();//写入一个行分隔符
        }
        bw.flush();//使用flush方法将会使内存的数据立刻写出
    
        while((s=br.readLine()) != null)
        {
            System.out.println(s);
        }
        bw.close();
        br.close();
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    
        }
    }

    3.4 转换流

    • 转换流有两种:
      (1)InputStreamReader:将字节流转换为字符流;
      (2)OutputStreamWriter:将字符流转换为字节流。
    • 什么时候使用转换流?由以下分析: 流对象很多,就要明确使用哪个流对象。
    通过三点来完成: 
        1、明确数据的来源和数据到达的目的地。
                     来源:输入流 [InputStream,Reader]。 
                     目的:输出流 [OutputStream,Writer]。 
        2、操作的数据是否是纯文本。  
                     是:字符流,使用Reader与Writer; 
                     否:字节流,使用InputStreamOutputStream3、明确要使用哪个具体的对象。 通过设备来进行区分: 
                     源设备:内存用数组,硬盘就加file,键盘用System.in; 
                     目的设备:内存用数组,硬盘就加file,键盘用System.out。 
        4、明确是否还需要其他额外功能:例如 
                    (1)是否需要较高的效率,即是否需要使用缓冲区,是就加上Buffered;
                    (2)是否需要转换,是,就使用转换流,InputStreamReader 和 OutputStreamWriter。
    • 用一个例子简单的说明: 将键盘录入的数据保存到一个文件中,输入“over”时表示录入结束。 详细分析:
    源:从InputStream,Reader中选择; 因为是键盘录入的是纯文本,所以使用Reader。 
    设备:键盘,所以用System.in; 发现System.in是字节流的操作,与Reader(字符流)矛盾,
    这时就要用到转换流 InputStreamReader 。为了提高操作效率,使用缓冲技术,选择BufferedReader。 
    
    目的:从 OutputStream,Writer中选择。 因为是文本文件,所以选择Writer。 
    设备:硬盘上,一个文件,选择FileWriter。 为了提高操作效率,使用缓冲技术,选择BufferedWriter。 
    • 示例1:
    import java.io.*; 
        class ReadinFile 
            { 
                public static void main(String[] args)throws IOException //这里为了方便阅读,先不做异常处理。 
                { 
                    BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); 
                    BufferedWriter bufw=new BufferedWriter(new FileWriter("readin.txt")); 
                    String line=null; 
                    while((line=bufr.readLine())!=null) 
                    { 
                        if("over".equals(line)) break; 
                        bufw.write(line); 
                        bufw.newLine(); 
                    } 
                    bufw.close(); 
                    bufr.close(); 
                } 
            }
    • 示例2:
    import java.io.*;
    public class TestTransForm 
    {
        public static void main(String[] args) throws IOException //这里为了方便阅读,先不做异常处理。 
        {
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
            OutputStreamWriter osw = new OutputStreamWriter(
                                     new FileOutputStream("D:\\JavaProject\\demo13\\TransStream\\TransForm.txt",true));
            BufferedWriter bw = new BufferedWriter(osw);
            String str = null;
            str = br.readLine();
            while(str != null)
            {
                if(str.equalsIgnoreCase("exit")) break;
                bw.write(str);
                bw.newLine();
                str = br.readLine();
            }
            br.close();
            bw.close();
        }
    }
    • 注意:
      (1)构造方法:public FileOutputStream(String name,boolean append) throws FileNotFoundException
      如果append为True,输出字节流就写入文件的末尾,而不是开头(覆盖原来的内容);
      如果append为False,输出字节流就写入文件的开头,即覆盖原来的内容从文件开始处写内容。
      (2)构造方法:public FileOutputStream(String name) throws FileNotFoundException
      每次覆盖原文件的内容,从文件开始处写内容。

    3.5 数据流——数据的存储和数据恢复

    • 数据流:DataInputStream和DataOutputStream
      (0)DataInputStream和DataOutputStream是面向字节的,因此要使用InputStream和OutputStream。
      (1)DataInputStream和DataOutputStream分别继承InputStream和OutputStream,
      它们属于处理流,需要分别“套接”在InputStream和OutputStream类型的节点流上。
      (2)DataInputStream和DataOutputStream提供了可以存取与机器无关的Java原始类数据(如:int,double等)的方法。
      (3)DataInputStream和DataOutputStream的构造方法:
         DataInputStream(InputStream in)
         DataOutputStream(OutputStream out
    • 示例1:
    import java.io.*;
    public class TestDataStream
    {
        public static void main(String[] args) throws IOException
        {
            FileOutputStream fout = new FileOutputStream("D:/JavaProject/demo13_IO/DataStream/demo.txt",true);
            BufferedOutputStream bout = new BufferedOutputStream(fout);
            DataOutputStream dout = new DataOutputStream(bout);
            /*DataOutputStream,BufferedOutputStream,FileOutputStream这里使用了流栈。*/
    
            dout.writeInt(110);
            dout.writeUTF("hello,中国");
            dout.writeFloat(3.14f);
            dout.writeChar(97);/*97对应的是'a'*/
            dout.close();/*如果正在使用一个流栈,程序关闭最上面的一个流也就自动的关闭了栈中的所有底层流。*/
    
            FileInputStream fin = new FileInputStream("D:/JavaProject/demo13_IO/DataStream/demo.txt");
            BufferedInputStream bin = new BufferedInputStream(fin);
            DataInputStream din = new DataInputStream(bin);
    
            int i = din.readInt();
            String str = din.readUTF();
            float f = din.readFloat();
            char c = din.readChar();
            fin.close();/*如果正在使用一个流栈,程序关闭最上面的一个流也就自动的关闭了栈中的所有底层流。*/
            System.out.println("int:"+i+"\nString:"+str+"\nfloat:"+f+"\nchar:"+c);
        }
    
    }
    • 编译,运行:
    D:\JavaProject\demo13_IO\DataStream>javac TestDataStream.java
    
    D:\JavaProject\demo13_IO\DataStream>java TestDataStream
    int:110
    String:hello,中国
    float:3.14
    char:a
    • 注意:
            int i = din.readInt();
            String str = din.readUTF();
            float f = din.readFloat();
            char c = din.readChar();
            /*此段代码的顺序不能乱,要保证先写入的先读出来的原则,否则会出现错误。
            *    因此,我们在写代码的时候,我们必须:
            *         要么为文件中的数据采用固定的格式;
            *         要么将额外的信息保存到文件中,以便能够对其进行解析以确定数据的寻访位置。
            */
    展开全文
  • 7、Flink 计算处理和批处理平台

    千次阅读 2018-11-15 12:30:33
    Flink 是一个批处理和流处理结合的统一计算框架,其核心是一个提供了数据分发以及并行化计算的数据处理引擎。它的最大亮点是流处理,是业界最顶级的开源流处理引擎。Flink 与 Storm 类似,属于事件驱动型实时...

    一、Flink 基本概念

    Flink 是一个批处理和流处理结合的统一计算框架,其核心是一个提供了数据分发以及并行化计算的流数据处理引擎。它的最大亮点是流处理,是业界最顶级的开源流处理引擎。Flink 与 Storm 类似,属于事件驱动型实时流系统。

    所谓说事件驱动型指的就是一个应用提交之后,除非明确的指定停止,否则,该业务会一直持续的运行,它的执行条件就是触发了某一个事件,比如在淘宝中,我们付款需要在支付宝付款,但是付款成功与否的条件是从淘宝获取的,支付宝通过接口向淘宝反馈扣款结果,这个计算的应用是一直存在的,它需要获取支付宝扣款的结果,将结果进行计算加入到后台数据库,记录日志并且向淘宝反馈扣款成功的信息。这个时候,这一系列的操作都是由于用户触发了付款这个事件而导致的,之后系统就会进行这个计算,应用是持续存在的,没有事件驱动的情况下,这个应用是处于静止状态的,事件驱动之后,应用进行计算和反馈。

    1.批处理和流处理

    批处理在大数据世界有着悠久的历史。批处理主要操作大容量静态数据集,并在计算过程完成后返回结果。

    批处理模式中使用的数据集通常符合下列特征:

    (1) 有界:批处理数据集代表数据的有限集合

    (2) 持久:数据通常始终存储在某种类型的持久存储位置中

    (3) 大量:批处理操作通常是处理极为海量数据集的唯一方法

    批处理非常适合需要访问全套记录才能完成的计算工作。例如在计算总数和平均数时,必须将数据集作为一个整体加以处理,而不能将其视作多条记录的集合。这些操作要求在计算进行过程中数据维持自己的状态。

    需要处理大量数据的任务通常最适合用批处理操作进行处理。无论直接从持久存储设备处理数据集,或首先将数据集载入内存,批处理系统在设计过程中就充分考虑了数据的量,可提供充足的处理资源。由于批处理在应对大量持久数据方面的表现极为出色,因此经常被用于对历史数据进行分析。大量数据的处理需要付出大量时间,因此批处理不适合对处理时间要求较高的场合。流处理系统会对随时进入系统的数据进行计算。相比批处理模式,这是一种截然不同的处理方式。流处理方式无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作。

    流处理中的数据集是“无边界”的,这就产生了几个重要的影响:

    (1) 完整数据集只能代表截至目前已经进入到系统中的数据总量。

    (2) 工作数据集也许更相关,在特定时间只能代表某个单一数据项。

    (3) 处理工作是基于事件的,除非明确停止否则没有“尽头”。处理结果立刻可用,并会随着新数据的抵达继续更新。

    流处理系统可以处理几乎无限量的数据,但同一时间只能处理一条(真正的流处理)或很少量(微批处理,Micro-batch Processing)数据,不同记录间只维持最少量的状态。虽然大部分系统提供了用于维持某些状态的方法,但流处理主要针对副作用更少,更加功能性的处理(Functional processing)进行优化。

    功能性操作主要侧重于状态或副作用有限的离散步骤。针对同一个数据执行同一个操作会或略其他因素产生相同的结果,此类处理非常适合流处理,因为不同项的状态通常是某些困难、限制,以及某些情况下不需要的结果的结合体。因此虽然某些类型的状态管理通常是可行的,但这些框架通常在不具备状态管理机制时更简单也更高效。

    此类处理非常适合某些类型的工作负载。有近实时处理需求的任务很适合使用流处理模式。分析、服务器或应用程序错误日志,以及其他基于时间的衡量指标是最适合的类型,因为对这些领域的数据变化做出响应对于业务职能来说是极为关键的。流处理很适合用来处理必须对变动或峰值做出响应,并且关注一段时间内变化趋势的数据。

    2.Flink 特点和应用场景

    Flink 最适合的应用场景是低时延的数据处理场景:高并发处理数据,时延毫秒级,且兼具可靠性。

    典型应用场景有:

    (1) 互联网金融业务。

    (2) 点击流日志处理。

    (3) 舆情(舆论情绪)监控。 Flink 的特点有以下几种:

    (1) 低时延:提供 ms 级时延的处理能力。

    (2) Exactly Once:提供异步快照机制,保证所有数据真正只处理一次

    (3) HA:JobManager 支持主备模式,保证无单点故障。

    (4) 水平扩展能力:TaskManager 支持手动水平扩展。

    Flink 能够支持 Yarn,能够从 HDFS 和 HBase 中获取数据;能够使用所有的Hadoop 的格式化输入和输出;能够使用 Hadoop 原有的 Mappers 和 Reducers,并且能与 Flink 的操作混合使用;能够更快的运行 Hadoop 的作业。

    二、Flink 架构

    1.Flink 组件架构

    (1) Data storage 底层是数据存储

    (2) Single node execution 表示的是部署方式

    (3) Local Environment 等表示的是不同的运行环境

    (4) Flink Local Runtime 表示是运行线程

    (5) Flink Optimizer,Flink Stream Builder 等表示的是优化器

    (6) Common API 表示的是 Flink 平台的 API

    (7) Scala API 和 Java API 表示的是对外提供的 API

    该逻辑图按照从上向下的结构,我们可以看出,最高层的组件都是 API 接口,用于提供用户的接入。第二层主要是创建编译工作流,并且对工作流做优化操作。然后将输入的数据按照创建好的工作流去执行,通过 Flink Local Runtime 组件来执行计算。第三层是环境层,不同的数据和应用的执行环境不同,就比如有一些游戏需要运行在 Java 环境中,在对不同的数据进行计算的时候,我们需要的底层环境也是不同的。最下边的一层是部署和数据的最底层,Flink 默认支持两种部署模式,一种是单独部署,也就是指 Flink 直接部署在集群上,作为独立计算工具运行。另一种是 Yarn 部署,就是将 Flink 认知为是 Hadoop 中的一个组件,和 Yarn 对接来使用。这样做可以充分利用各个组件的优势,组件之间互相结合来进行工作的执行。

    2.Flink 的数据结构

    DataStream 是数据模型,所有的数据在进入 Flink 到从 Flink 输出都必须要按照 DataStream 的模型来进行计算和数据的转换。Flink 用类 DataStream 来表示程序中的流式数据。用户可以认为它们是含有重复数据的不可修改的集合(collection),DataStream 中元素的数量是无限的。这里有两个重点,首先, Stream 流式数据可能会存在有重复的数据,这点本身无可厚非,我们在实际写入数据的时候,不同的用户提交相同的数据是很有可能的,而系统也必须要对每一个相同的数据做都做相关的计算操作。那么流数据还有一个特点就是元素是无限的。我们认为流式数据是一个无头无尾的表,旧的数据已经计算完成就被淘汰,而新的数据会被切分成数据分片添加到数据流的结尾。

    DataStream 之间的算子操作:

    (1) 含有 Window 的是窗口操作,与后面的窗口操作相关连,之间的关系可以通过 reduce,fold,sum,max 函数进行管关联。

    (2) connect:进行 Stream 之间的连接,可以通过 flatmap,map 函数进行操作。

    (3) JoinedStream :进行 Stream 之间的 join 操作,类似于数据库中的 join,可以通过 join 函数等进行关联。

    (4) CoGroupedStream:Stream 之间的联合,类似于关系数据库中的 group 操作,可以通过 coGroup 函数进行关联。

    (5) KeyedStream:主要是对数据流依据 key 进行处理,可以通过 keyBy 函数进行处理。

    DataStream 在计算中一共分为了三个步骤:DataSource、Transformation 和DataSink。

    (1) Data source:流数据源的接入,支持 HDFS 文件、kafka、文本数据等。

    (2) Transformations:流数据转换。

    (3) Data sink:数据输出,支持 HDFS、kafka、文本等。

    在 DataStream 中,数据流转换流程与 Spark 类似:

    (1) 从 HDFS 读取数据到 DataStream 中

    (2) 接下来进行相关算子操作,如 flatMap,Map,keyBy

    (3) 接下来是窗口操作或算子操作(4) 最后处理结果 sink 到 HDFS

    三、Flink 执行流程

    (1) Client:Flink  Client 主要给用户提供向 Flink 系统提交用户任务(流式作业)的能力。

    (2) TaskManager :Flink 系统的业务执行节点,执行具体的用户任务。TaskManager 可以有多个,各个 TaskManager 都平等。

    (3) JobManager:Flink 系统的管理节点,管理所有的 TaskManager,并决策用户任务在哪些 Taskmanager 执行。JobManager 在 HA 模式下可以有多个,但只有一个主 JobManager。

    (4) TaskSlot(任务槽):类似 yarn 中的 container 用于资源隔离,但是该组件只包含内存资源,不包含 cpu 资源。每一个 TaskManager 当中包含 3 个 Task Slot,TaskManager 最多能同时并发执行的任务是可以控制的,那就是 3 个,因为不能超过 slot 的数量。 slot 有独占的内存空间,这样在一个 TaskManager 中可以运行多个不同的作业,作业之间不受影响。slot之间可以共享 JVM 资源, 可以共享 Dataset 和数据结构,也可以通过多路复用(Multiplexing) 共享 TCP 连接和心跳消息(Heatbeat Message)。

    (5) Task:任务执行的单元。执行流程:

    (1) 任务的执行流程主要是分成了工作流的下发创建和数据流的执行流程两个部分。在执行数据流计算之前,必须先把任务的执行流程先做好。所以 Client 收到用户提交的应用之后,会通过 FlinkProgram 将用户提交的应用转换成为流式作业,以 Topology 的形式提交到 JobManager 中,该流式作业的 Topology 如果没有在用户的强制指定关闭的情况下,会一直持续的按照事件驱动型进行运行。

    (2) JobManager 通过 Actor 进程和其他组件进行联系,通过 scheduler 进程检查当前集群中所有 TaskManager 中的集群负载,选择负载最小的TaskManager,将任务下发到不同的 TaskManager 中。

    (3) TaskManager 其实可以理解成为是节点,TaskManager 通过 ActorSystem收到 JobManager 的请求之后,下一步会将提交的作业进行下发执行,但是执行之前 TaskManager 还需要检测当前集群资源的使用情况,将内存资源封装成 TaskSlot,下发到其中进行执行。CPU 资源由节点所有进程共享。

    (4) 最终 TaskSlot 执行完任务之后,会将执行的结果直接传送到下一个TaskManager 中,而不是反馈给 JobManager。所以作为 JobManager,其只负责了任务的下发,数据的下发,还有结果的接收,对于所有的中间结果,JobManager 都不负责管理。

     

    (1) Flink YARN Client 首先会检验是否有足够的资源来启动 YARN 集群,如果资源足够的话,会将 jar 包、配置文件等上传到 HDFS。

    (2) Flink YARN Client 首先与 YARN Resource Manager 进行通信,申请启动ApplicationMaster(以下简称 AM)。在 Flink YARN 的集群中,AM 与 Flink JobManager 在同一个 Container 中。

    (3) AM 在启动的过程中会和 YARN 的 RM 进行交互,向 RM 申请需要的 Task ManagerContainer,申请到 Task Manager Container 后,在对应的 NodeManager 节点上启动 TaskManager 进程。

     

    (4) AM 与 Fink JobManager 在同一个 container 中,AM 会将 JobManager 的 RPC 地址通过 HDFS 共享的方式通知各个 TaskManager,TaskManager 启动成功后,会向 JobManager 注册。

    (5) 等所有 TaskManager 都向 JobManager 注册成功后,Flink 基于 YARN 的集群启动成功,Flink YARN Client 就可以提交 Flink Job 到 Flink JobManager,并进行后续的映射、调度和计算处理。

    四、Flink 技术原理

    1.流式数据运行原理

    用户实现的 Flink 程序是由 Stream 数据和 Transformation 算子组成。Stream 是一个中间结果数据,而 Transformation 是算子,它对一个或多个输入 Stream 进行计算处理,输出一个或多个结果 Stream。

     

    Flink 程序执行时,它会被映射为 Streaming Dataflow 。一个 Streaming Dataflow 是由一组 Stream 和 Transformation Operator 组成,它类似于一个DAG 图,在启动的时候从一个或多个 Source Operator 开始,结束于一个或多个Sink Operator。

    (1) Source:流数据源的接入,支持 HDFS 文件、kafka、文本数据等。

    (2) Sink:数据输出,支持 HDFS、kafka、文本等。

    (3) Stream 是 Flink 计算流程中产生的中间数据。Flink 是按 event 驱动的,每个 event 都有一个 event time 就是事件的时间戳,表明事件发生的时间,这个时间戳对 Flink 的处理性能很重要,后面会讲到 Flink 处理乱序数据流时,就是靠时间戳来判断处理的先后顺序。

    一个 Stream 可以被分成多个 Stream 分区(Stream Partitions),一个 Operator 可以被分成多个 Operator Subtask,每一个 Operator Subtask 是在不同的线程中独立执行的。一个 Operator 的并行度,等于 Operator Subtask 的个数,一个Stream 的并行度等于生成它的 Operator 的并行度。

    1.One-to-one 模式比如从 Source[1]到 map()[1],它保持了 Source 的分区特性(Partitioning)和分区内元素处理的有序性,也就是说 map()[1]的 Subtask 看到数据流中记录的顺序,与 Source[1]中看到的记录顺序是一致的。

    2.Redistribution 模式这种模式改变了输入数据流的分区,比如从 map()[1] 、 map()[2] 到 keyBy()/window()/apply()

    [1] 、keyBy()/window()/apply()[2] , 上 游 的Subtask 向下游的多个不同的 Subtask 发送数据,改变了数据流的分区,这与实际应用所选择的 Operator 有关系。 Subtask 的个数,一个 Stream 的并行度总是等于生成它的 Operator 的并行度。

     

    Flink 内部有一个优化的功能,根据上下游算子的紧密程度来进行优化。紧密度高的算子可以进行优化,优化后可以将多个 Operator Subtask 串起想·来组成一个 Operator Chain,实际上就是一个执行链,每个执行链会在 TaskManager 上一个独立的线程中执行。上半部分表示的是将两个紧密度高的算子优化后串成一个 Operator Chain,实际上一个 Operator Chain 就是一个大的 Operator 的概念。途中的 Operator Chain 表示一个 Operator,keyBy 表示一个 Operator,Sink 表示一个 Operator,他们通过 Stream 连接,而每个 Operator 在运行时对应一个 Task,也就是说图中的上半部分 3 个 Operator 对应的是 3 个 Task。下半部分是上半部分的一个并行版本,对每一个 Task 都并行华为多个 Subtask,这里只是演示了 2 个并行度,sink 算子是 1 个并行度。

    2.Flink 窗口技术

    Flink 支持基于时间窗口操作,也支持基于数据的窗口操作:

    (1) 按分割标准划分:timeWindow、countWindow。

    (2) 按窗口行为划分:Tumbling Window、Sliding Window、自定义窗口。窗口按驱动的类型分为时间窗口(timeWindow)和事件窗口(countWindow)。窗口可以是时间驱动的(Time Window,例如:每 30 秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。

    窗口按照其想要实现的功能分为:

     翻滚窗口(Tumbling Window,无时间重叠,固定时间划分或者固定事件个数划分)

    滚动窗口(Sliding Window,有时间重叠)

    会话窗口(Session Window,将事件聚合到会话窗口中,由非活跃的间隙分隔开)。

    3.Flink 容错机制

     

    checkpoint 机制是 Flink 运行过程中容错的重要手段。 checkpoint 机制不断绘制流应用的快照,流应用的状态快照被保存在配置的位置(如:JobManager 的内存里,或者 HDFS 上)。Flink 分布式快照机制的核心是 barriers,这些 barriers 周期性插入到数据流中,并作为数据流的一部分随之流动。barrier 是一个特殊的元组,这些元组被周期性注入到流图中并随数据流在流图中流动。每个 barrier 是当前快照和下一个快照的分界线。在同一条流中 barriers 并不会超越其前面的数据,严格的按照线性流动。一个 barrier 将属于本周期快照的数据与下一个周期快照的数据分隔开来。每个 barrier 均携带所属快照周期的 ID,barrier 并不会阻断数据流,因此十分轻量。Checkpoint 机制是 Flink 可靠性的基石,可以保证 Flink 集群在某个算子因为某些原因(如异常退出)出现故障时,能够将整个应用流图的状态恢复到故障之前的某一状态,保证应用流图状态的一致性。该机制可以保证应用在运行过程中出现失败时,应用的所有状态能够从某一个检查点恢复,保证数据仅被处理一次(Exactly Once)。另外,也可以选择至少处理一次(at least once)。

     

     

    每个需要 checkpoint 的应用在启动时,Flink 的 JobManager 为其创建一个CheckpointCoordinator,CheckpointCoordinator 全权负责本应用的快照制作。用 户 通 过 CheckpointConfig 中 的 setCheckpointInterval() 接 口 设 置checkpoint 的周期。

    CheckPoint 机制

    CheckpointCoordinator 周期性的向该流应用的所有 source 算子发送barrier。当某个 source 算子收到一个 barrier 时,便暂停数据处理过程,然后将自己的当前状态制作成快照,并保存到指定的持久化存储中,最后向 CheckpointCoordinator 报告自己快照制作情况,同时向自身所有下游算子广播该 barrier,恢复数据处理。下游算子收到 barrier 之后,会暂停自己的数据处理过程,然后将自身的相关状态制作成快照,并保存到指定的持久化存储中,最后向 CheckpointCoordinator 报告自身快照情况,同时向自身所有下游算子广播该barrier,恢复数据处理。每个算子按照步骤 3 不断制作快照并向下游广播,直到最后 barrier 传递到 sink 算子,快照制作完成。当 CheckpointCoordinator 收到所有算子的报告之后,认为该周期的快照制作成功;否则,如果在规定的时间内没有收到所有算子的报告,则认为本周期快照制作失败。

    展开全文
  • 这几年大规模的物联网(IoT)数据监控系统和视频系统等的大数据系统出现,已经是必然现象了,我相信在5G的推动下,这类些系统会越来越。 在我们开发过程中也会时常的跟这些数据打交道,所以明白其处理方式也是...

    大数据篇:如何区分流处理和批处理

    今天我们来讲讲大数据的处理模式:批处理(Batching Processing)和流处理(Streaming Processing)。

    这几年大规模的物联网(IoT)数据监控系统和视频流系统等的大数据系统出现,已经是必然现象了,我相信在5G的推动下,这类些系统会越来越多。

    在我们开发过程中也会时常的跟这些数据打交道,所以明白其处理方式也是必要的。

    这些数据被抽象成两种数据,分别是有边界数据(Bounded Data)和无边界数据(UnBounded Data)

    有边界数据和无边界数据

    无边界数据

    无边界数据,其实就是一种可增长,无限的数据集。

    我们无法判断他到底会在什么时候结束。例如:我们生活中的支付宝中的交易数据,每时每刻都会有数据产生,无法判断它什么时候会停止发送。

    在这里插入图片描述

    我们也可以称他为”流数据(Streaming Data)“。

    有边界数据

    有边界数据,其实就是一种保存好了的数据,例如数据库中的数据或者csv中的数据等

    拿我们之前的交易数据来说,如果按照一定的时间窗口,拿取一小部分数据,那么提取出来的数据也是有边界数据了。例如我提取2019年08月19日这天地数据来做处理,我们提取出来地这份数据就是有边界数据。

    这里说到了时间窗口,那么我们下面就介绍下两个关于时间的时域吧,他们分别是事件时间处理时间

    事件时间和处理时间

    事件时间(Event Time)指的是一个数据实际产生的时间,处理时间(Precessing Time)指的是这条数据实际被处理数据的系统接收的时间。

    下面我们通过一个例子更了解事件时间和处理时间。

    例如:我打开淘宝准备购物,在12点05分下了单,由于进入车库没信号,导致这个订单一直在重试支付,直到我离开车库,提示支付成功,这时的时间是12点08分。这里的12点05分就是事件时间,而12点08分就是处理时间,这样你是否明白了呢?

    下面我们就进入主题批处理流处理

    批处理和流处理

    批处理

    数据的批处理,可以理解为一系列相关的任务按顺序或并行的,一个接一个地执行。批处理地输入是在一段时间内收集好地数据。每次批处理地输出都可以是下次批处理地输入。

    大部分情况下,批处理地输入数据和输出数据都是有边界数据。所以在批处理中,我们更关注地事件事件。

    举个例子,你在年初的时候,很多“大厂”都会对你这一年所做的事情做一次分析,得到一些有趣的事情。下面我们以网易云音乐为例子:

    在这里插入图片描述

    每年的网易云音乐都会将我们过去一年中听取的歌曲记录存储起来,作为批处理的数据来源,经过一系列的分析计算得到一份有趣的数据作为数据输出。

    在大部分情况,批处理任务会被安排,并在预先设定好的事件间隔来执行。例如:一年、一个月、一天的特定时间。

    网易云音乐的日推也是根据批处理系统,以预先设定好的一天的时间间隔运行,而产生出来的。

    批处理的系统架构通常会被设计在以下这些应用场景中:

    • 日志分析:日志系统是在一定时间段内收集的。而日志系统的数据处理分析是在不同的时间内执行的,以得到系统的关键性指标(例如之前说的准确性和系统容量等)。
    • 计费的应用程序:计费应用程序会计算出一段时间内一项服务的使用程度,并生成计费信息,例如支付宝花呗的还款账单。
    • 数据仓库:数据仓库的主要目标是根据收集好的数据事件时间,将数据信息合并为静态快照(static snapshot),并将它们聚合为每周、每月、每季度的报告等。

    像现在的Apache Hadoop或者是Apache Spark等开源框架都是支持这种大数据批处理架构的。

    由于批处理一般都具有高延迟性,有可能计算需要几小时、几天甚至是几周的时间。所以对实时性比较有要求,那么应该考虑使用流处理的方式处理数据。

    流处理

    数据的流处理可以理解为系统需要接收并处理一系列连续不断变化的数据。例如,音视频的实时推荐、周边推荐等。

    流处理的输入基本都是无边界数据。而流处理系统中是关心事件时间还是处理时间一般是随应用场景而定的。

    例如,像网页监控系统这样的流处理系统要计算网站的QPS,它关心的更多是处理时间,也就是网页请求数据被监控系统接收到的时间,而计算QPS。而在一些医疗护理监控系统的流处理系统中,他们则关心数据的事件时间,这种系统不会因为网络延迟而忽略系统原本产生的时间。

    流处理的特点应该是足够快、低延迟、以及来自各种数据源的大规模数据。流处理所需的响应时间更应该以毫秒(或秒)来进行计算。向我们平时用到的搜索引擎,系统必须在用户输入关键字后以毫秒级的延时返回搜索结果给用户。

    流处理快的原因,是因为他是在数据未达到磁盘时计算的,也就是在内存中计算的。

    当流处理架构拥有一定时间间隔(毫秒)内产生逻辑上正确的结果,这种架构可以被定义为实时处理(Real-time Processing)。

    当一个系统可以接收以分钟为单位的数据处理时间延时,我们可以把它定义为准实时处理(Near Real-time Processing)。

    还记得我们说过批处理架构的不足之处吗?没错,那就是高延迟性。而我们的流处理架构恰恰拥有低延迟和高吞吐等特点。

    下面介绍几个流处理的应用场景:

    • 实时监控:捕获和分析各种来源发布的数据,入传感器,新闻源,点击网页等。
    • 实时商业只能:智能汽车,智能家居,智能病人护理等。
    • 销售终端(POS)系统:像是股票价格的更新,允许用户实时完成付款的系统。

    如今开源的生态圈中,入Apache Kafka、Apache Storm、Apache Flink、Apache Samza等都是流行的流处理架构平台。

    经过介绍你不难发现,无论是批处理模式还是流处理模式,在现实中都是广泛的被使用,而采用哪种处理模式,则应当由使用场景决定。

    总结

    像是对不需要实时分析结果的情况下,其实批处理是一个很好的选择。特别是业务逻辑十分复杂,数据量大的时候,更容易从数据中挖掘到有用的信息。

    而对应用的实时分析处理有要求的情况下,或者数据传输的结束时间、数据量无法确定的情况下,就可以采用流处理的处理架构来完成这件事情

    名言:难走的路,从不拥挤

    下一章:Workflow设计模式

    展开全文
  • C++的标准输入输出

    千次阅读 2018-01-18 21:54:11
     前面曾多次说明,cout和cin并不是C++语言中提供的语句,它们是iostream类的对象,在未学习类和对象时,在不致引起误解的前提下,为叙述方便,把它们称为cout语句和cin语句。正如C++并未提供赋值语句,只提供赋值...
  • Streaming 102批处理之外的流处理世界

    千次阅读 2017-09-18 14:06:41
    Steaming 101介绍了基本的术语,有限数据(bounded)VS无限数据(unbounded),然后是批处理和流处理的区别,在介绍完术语之后,阐述了事件时间和处理时间这两个重要概念,在Steaming 102中增加了3个新的概念:Watermark...
  • Streaming 101批处理之外的流处理世界

    千次阅读 2017-09-13 09:12:00
    Streaming 101批处理之外的流处理世界 本文整理谷歌Tyler Akidau写的两篇文章,对于技术人员来理解大数据计算中的一些概念非常有用。原文写于2015年,所以对有些问题的是不准确的,但是不影响文章所表达的主要宗旨...
  • stringstream可作为内存来使用,比如再需要处理文件,过滤内容后再输出到另一个文件里。内存不需要操作文件指针,比较省时间和io.
  • 紧随上一篇博文,通过利用RawCap.exe和WireShark等抓包工具从数据最底层角度来分析一下DICOM3.0标准中的网络通讯服务,并且查看分析了DCMTK和fo-dicom开源库源码的相关实现,使得对DICOM3.0标准的网络通讯部分(第...
  • Flink内置引擎是一个分布式数据引擎,支持 流处理和批处理 ,支持和使用现有存储和部署基础架构的能力,它支持个特定于域的库,如用于机器学习的FLinkML、用于图形分析的Gelly、用于复杂事件处理的SQL和...
  • C++的输入和输出与标准输出

    万次阅读 2014-10-06 14:06:44
    第二十讲: C++的输入和输出与标准输出 本讲基本要求  * 掌握:输入输出的含意;文件以及输入/输出的格式控制;标准输出在C++程序中的应用。  * 理解:C++类库中的常用类。  * 了解:C++的I/O对C的...
  • 流处理和批处理框架的异同

    千次阅读 2019-01-23 19:00:00
    A t least once意味着每条消息会进行多次传输尝试,至少一次成功,即消息传输可能重复但不会丢失;Exactly once的消息传输机制是每条消息有且只有一次,即消息传输既不会丢失也不会重复。   容错:流处理框架...
  • 在Darwin媒体服务器解析1中,我们分析了建立一路RTSP Session的过程,本文将具体深入到RTSPSession内部,分析RTSPSession对每一个RTSP请求的处理过程:  继续在Darwin媒体服务器解析1中最后说到的,进入到...
  • 最近在学习一些流处理相关的知识,对比与笔者接触比较的离线处理系统,实时流处理的有些地方还是比较有意思的。在这里面,最常被人提到的词应该是“Exactly Once”语义 ,在工作面试中,如果做过实时系统,肯定...
  • 以新的数据仓库平台为基础,结合行内的通用文件传输平台、统一调度平台,规范了源数据系统的数据报送,梳理构建了新的数据模型,大数据平台解决了传统数仓在批量数据处理能力的不足,在相关任务上体验到了从数小时到...
  • 解决HttpServletRequest的只能读取一次的问题写文背景解决思路不能读取多次的原因解决方式借用HttpServletRequestWrapper类来包装最终解决办法总结 写文背景 在使用公司的springboot框架做开发的过程中,参数...
  • 一个事件其实在页面上 有个元素相应事件处理,点击页面上的一个button,会发生什么?其实 是相当于先后点击了按钮,它的容器,及这个页面.也就是说没一个元素都按照特定的顺序响应那个事件.事件的发生顺序在IE和mozilla...
  • 业界对流处理已经有几种适用的框架来解决,下面我们来比较各流处理框架的相同点以及区别。 分布式流处理是对无边界数据集进行连续不断的处理、聚合和分析。它跟MapReduce一样是一种通用计算,
  • 越大,说明单位时间内取样率越大,数据,精度就越高,处理出来的文件就越接近原始文件,图像质量越好,画质越清晰,要求播放设备的解码能力也越高。 单位一般是Kbps(Kbit/s)或者Mbps(Mbit/s)。注意1B(Byte)...
  • [网络]学习笔记:一理解网络

    万次阅读 多人点赞 2018-02-23 18:23:52
    网络:所有弧上流量的集合f={f(u,v)},称为容量网络的一个网络. 定义:带权的有向图G=(V,E),满足以下条件,则称为网络图(flow network): 仅有一个入度为0的顶点s,称s为源点 仅有一个出...
  • 【Java基础-3】吃透Java IO:字节、字符、缓冲

    万次阅读 多人点赞 2020-09-23 20:12:33
    什么是Java-IO?字符和字节的区别与适用场景是什么?缓冲到底实现了什么?如何高效地读写文件? 本文用大量的示例图和实例,带你吃透Java IO。
  • bpm的三个标准以及如何结合使用

    万次阅读 2020-06-04 12:47:50
    工作系统、工作引擎、BPM、Camunda BPM
  • 标准IO

    千次阅读 2018-03-09 13:54:51
    一、文件I/O和标准I/O 二、标准I/O 2.1 错误报告 2.2 和FILE结构 2.2.1 简述 2.2.2 打开 2.2.3 进程启动自动打开 2.2.4 FILE结构 ...2.3.5 进程与缓冲 2.4 标准I/O函数 2.4.1 简述 2.4...
  • 媒体及媒体传输协议简介

    千次阅读 多人点赞 2019-06-01 22:26:10
    媒体(streaming media):是指将一连串的媒体数据压缩后,经过网上分段发送数据,在网上即时传输影音以供观赏的一种技术与过程,此技术使得数据包得以像流水一样发送;如果不使用此技术,就必须在使用前下载整个...
  • IO线程总结

    千次阅读 2016-09-22 16:28:24
    IO用来处理设备之间的数据传输 Java对数据的操作是通过的方式 Java用于操作的类都在IO包中 按流向分为两种:输入,输出按操作类型分为两种:字节与字符。 字节可以操作任何数据,字符...
  • istream:输入类型,提供输入操作。 ostream:输出类型,提供输出操作。 cin:istream对象,从标准输入读取数据。 cout:ostream对象,向标准输出写入数据。 cerr:ostream对象,向标准错误写入数据。 >>...
  • 工作activiti

    千次阅读 2015-05-31 21:17:23
    下载工作引擎和下载插件就不说了,这个百度上很。 安装遇到的问题: 说一下再下载插件中容易遇到的几个问题以及解决的方案;自己电脑上安装的有java ide的有myeclipse 8.5,eclipse 3.7中文版32位和eclipse 4.2 64...
  • FMRI数据分析与处理

    万次阅读 多人点赞 2016-12-21 13:22:23
    近年来,血氧水平依赖性磁共振脑功能成像(Blood oxygenation level-dependent functional magnetic resonance imaging, BOLD-...图像数据的后处理技术成为fMRI中的关键环节一、功能图像数据的性质功能磁共振数据包括
  • 简介  先看看下面这个过程: 我们从未手动开启过PHP的相关进程,它是随着Apache的...PHP内核用来处理请求、文件、错误处理等相关操作;Zend引擎(ZE)用以将源文件转换成机器语言,然后在虚拟机上运行它;扩展层是

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 401,958
精华内容 160,783
关键字:

多次流标该如何处理