zoukankan      html  css  js  c++  java
  • Spark Streaming揭秘 Day32 WAL框架及实现

    Spark Streaming揭秘 Day32

    WAL框架及实现

    今天会聚焦于SparkStreaming中非常重要的数据安全机制WAL(预写日志)。

    设计要点

    从本质点说,WAL框架是一个存储系统,可以简单的认为是一个文件系统,其作用类似于BlockManager,
    我们首先看一下官方的说明:
    Snip20160710_53

    这里有三个要点:

    1. 总体上,sparksteaming是用WAL去保存接收到的数据,并且在写入数据后,要把元数据汇报给Driver,这样失败了才能恢复起来。
    2. 每当写入一个log,就返回一个handle,handle包含所有的从写入后的记录中恢复回原来数据的所有信息,和blockManager是一样的,使用时间来索引record,所以在sparkstreaming,WAL是顺序读写的。这个时间也方便我们进行清理(会有一个自己的超时时间)。具体的子类,必须确保数据是可持久化和可读取的。
    3. 为什么选择顺序写,是因为在数据备份的时候,效率会比较高。当读的时候,采用一块一块的读,而不是一条一条的读,找数据的时候,需要找到起始点,并结合数据长度来批量读取,而不是读一条,找一条。可以极大的节省读取的时间。

    总体结构

    WriteAheadLog作为一个抽象类,主要提供一些操作的方法,并没有说明如何对数据本身如何进行操作。因为具体的操作往往会涉及底层的存储系统。这种写法,可以使客户端依赖于抽象,而不是依赖于具体,既方便使用者,也方便开发者。最为关键的是下面三个方法:
    Snip20160710_54

    1. write方法,输入一个ByteBuffer,ByteBuffer只是个很简单的java类,里面封装了一个字节数组。
    2. read方法,基于handle,读取我们要读取的记录。
    3. clean方法,threshTime是一个阀值,在之前的数据会被清理掉。

    那handle里是啥呢,其实非常简单,WriteAheadLogRecordHandle也是抽象的。具体实现在FileBasedWriteAheadLogSegment:
    Snip20160710_55
    这是个case class,只是保存了三个信息,数据文件路径、位置以及数据长度。

    WriteAheadLog实现

    FileBasedWriteAheadLog是WriteAheadLog一般情况下的实现。

    让我们看下说明,在管理WAL文件时,会把数据周期性的写入日志文件中。当失败时,会从文件中恢复数据。
    这里的关键是rolling的管理方式,这是写数据的一种特征,写log的时候,每隔一段时间,就把已经在写的文件关闭掉,再产生新的文件保存新的数据。这种方式的好处是:

    1. 写的文件,单个文件不会太大。
    2. 删除数据比较方便。

    Snip20160710_56

    currentLogWriter是WAL中的关键,专门来写数据到log file中,一个文件会对应一个writer,产生新的文件就会有新的writer。实际存数据时是放在checkpoint Directory下的。
    Snip20160710_57

    write方法,是写入数据到hadoop支持的文件系统中,并且会确保数据已经到了文件系统中。其中会根据时间获取writer来写入数据。
    Snip20160710_58

    其中,getLogWriter放大,会根据时间,生成writer,从代码看,会按照时间分段来生成新文件。这是实现rolling方式的关键。
    Snip20160710_59

    read方法,根据file segment来读数据,所以实际读数据时是一批一批读的。
    Snip20160710_60

    intitializeOrRecover方法也是关键,在启动时调用,会根据文件信息恢复pastLogs,也就是说在记录log文件时,文件是自解释的,包含开始时间、结束时间和路径。
    Snip20160710_61

    Writer和Reader实现

    FileBasedWriteAheadLogWriter负责将数据写入日志文件中。

    Snip20160710_62

    每次把数据写完的时候,都会记录offset和length。flush会调用文件系统的方法,优先使用hflush方法,否则使用sync方法。

    FileBasedWriteAheadLogRandomReader是reader的默认实现,会根据给定handle返回block。

    Snip20160710_63

    首先会使用seek方法跳到索引位置,此后采用原生字节操作进行读取,同时会加锁,返回时用HeapByteBuffer封装起来。

    除了random的方式,还有一种顺序读的方式FileBasedWriteAheadLogReader,采用了迭代器来封装,数据在hasNext中产生,next方法只是读取结果。

    WAL触发机制

    那么,WAL机制在SparkStreaming框架中是如何触发的呢?

    首先,在接收数据后,会判断是不是要进行WAL操作。
    Snip20160710_64

    在构造时,createLog方法默认情况,就是创建了FileBasedWriteAheadLog,需要注意的是在WAL方式下数据副本只能有一个。
    Snip20160710_65

    storeBlock方法中实际触发操作,这里构建了一个future(和blockManager是并行执行),将数据写入WAL,在执行后会返回了handle并进行登记。
    Snip20160710_67

    总结的来说,WAL比普通的文件操作,增加了时间的维度和索引位置两个因素,两个加起来形成了WAL框架。

    欲知后事如何,且听下回分解!

    DT大数据每天晚上20:00YY频道现场授课频道68917580

  • 相关阅读:
    WebApp触屏版网站开发要点
    Web前端开发规范手册
    Web页面切图和CSS注意事项
    javascript中的一些基本方法收藏
    浅谈浏览器兼容性问题
    html 5 标签分类
    前端meta知多少
    浏览器内核信息整理
    Javascript中的undefined、null、""、0值和false的区别总结
    JQUERY中的AJAX应用
  • 原文地址:https://www.cnblogs.com/dt-zhw/p/5658501.html
Copyright © 2011-2022 走看看