超大量的数据会因为太过庞大,又或者太过笨拙,又或者非常动态,因而不能有效地通过关系数据库来存储,传统的数据库技术会在这里显得很无力,这方面的例子包括了电话通话记录,网络日志,web文档库等等。对这样的数据集提供简单而又方便的分析和处理,这就是Dagger为我们做的事情。
    在对Dagger进行介绍之前,我们先来了解一下几个重要的工具:
1, sawzall :
    作为一种查询语言,Sawzall是一种类型安全的脚本语言。由于Sawzall自身处理了很多问题,所以完成相同功能的代码就简化了非常多-与MapReduce的C++代码相比简化了10倍不止。
    Sawzall语法和表达式很大一部分都是从C照搬过来的;包括for循环,while循环,if语句等等都和C里边的很类似。定义部分借鉴了传统Pascal的模式:i: int=0。Sawzall支持protobuffer数据类型。 通过转换就可以把protobuffer转成Sawzall支持tuple类型了。Sawzall有一个很广泛的选择基础函数库。在基础函数库中是给调用代码使用的国际化的函数,文档分析函数等等。
    虽然在语句级别Sawzall是一个很传统的语言,但是它有两个非常不寻常的特性,都在某种意义上超越了这个语言本身:
    1. Sawzall程序定义了对于数据的单个记录的操作。这个语言没有提供任何可以同时处理多条记录的方法,以及没有提供通过一个输入记录的值来影响另一个记录的方法。
    2. 这个语言为一个输出时emit语句,这个语句发送数据到一个外部的聚合器来汇聚每一个记录的结果并且在聚合器进行结果的加工和处理。
    现在已经有许多聚合器可以使用,比如collection(搜集器), sample(采样器),sum(累加器), maximum(最大值), top(最常见),quantile(分位数),unique(唯一)。
    2, XFS
    XFS是基础架构部Typhoon云平台提供的一个可靠的分布式存储系统,我们系统访问的数据集通常保存在XFS内。它通过组织分布在上千台计算机的以64M为单位的基本块,而成为上Petabyte级别的文件系统。每一个块都有备份,通常是3个备份,在不同的计算机节点上,这样XFS可以无缝的从磁盘或者计算机的故障中容错。
    3,Mapreduce
    Mapreduce是一款广为人知的分布式运算框架,在基础架构部的打造的Typhoon云平台上,就有MapReduce团队为我们设计的属于腾讯自己的强大的云计算框架。它提供三个主要功能。首先,它提供一个给予大量数据的并行处理的程序运行模式。第二,它把应用从运行在分布式程序的细节中隔离出来,包括类似数据分布,调度,容错等等。最后,当发现条件许可时,各个计算机上的应用程序充分利用存储在本地的XFS数据来执行计算,减少网络的流量。
    4, Torca
    Torca是Typhoon云平台提供的资源管理器,他负责把Job调度到计算机集群上运行。Torca能够很有效的在一组计算机及其磁盘组上创建了一个大尺度的分时共享机制。它调度任务,分配资源,报告状态,并且汇集结果。我们经常把Torca集群和XFS集群部署在相同的计算机集群上。这是因为XFS是一个存储系统,CPU通常负载不太高,在CPU空闲阶段可以用来运行Torca调度的Job。
    5, Xcube
    Xcube是Typhoon平台提供的一个分布式的结构化数据存储系统,它被设计用来处理海量数据:通常是分布在数千台普通服务器上的PB级的数据。腾讯的很多项目使用Xcube来存储数据,比如说新上线的新闻搜索。各种应用对Xcube提出的要求差异非常大,无论是在数据量上还是在响应速度上。尽管应用需求差异很大,但是,针对这些应用Xcube还是成功的提供了一个灵活的、高性能的解决方案。
    Dagger系统充分利用了上述工具的长处, 使用了Sawzall做为自己的语法解释器,将Sawzall语言转化为Mapreduce任务,使用Torca集群来进行任务调度,使用XFS/Xcube做为输入,并将运行的结果存储在XFS上。Dagger是集天地之精华,吸收海内外优秀基因,在合适的时刻、合适的地点、由合适的团队打造的一把短小精悍的利刃,在庞大的数据海洋里游刃有余。接下来将讲述Dagger的设计。
    Dagger的设计介绍
    Dagger是由用户编写Sawzall脚本来提交任务,在内部将任务分解成Map任务和Reduce任务在Mapreduce框架上来运行的。 因而Dagger可以划分为三个模块:Sawzall Process, Mapper Process, Reducer Process.
    Sawzall Process:
    Sawzall Process主要是对sawzall语言进扩充,丰富聚合器类型以及内置功能函数,丰富数据类型,并对用户编写的sawzall脚本进行解析,得到可执行的Process类。流程如下:
    构造Executable,对象 输入sawzall脚本并编译
    以Executable实例初始化Process对象
    为sawzall脚本中定义的聚合器向Process注册Emitter
    Process是一个独立的runnable Sawzall program,通过一组Run方法接受输入
    Process 将输入 传递给Executable执行,并将执行结果传给Emitter
    如下图所示:


红线为数据流, 黑线为执行流


    Mapper Process
    Mapper Process 执行Map阶段的操作,对输入数据进行切分,支持的输入数据类型有Xcube, SSTable, RecordIO, TEXT等。对数据切分得到的单个记录做为上图中的input record,使用sawzall process的main(即sawzall编写的执行逻辑)部分来处理,截取process 发送给emit的处理结果做为Mapper的输出,实现Mapper过程需要执行的逻辑。
    如下图所示:


红线为数据流, 黑线为执行流


    Reducer Process
    Reducer Process根据用户定义的聚合方法,处理最终数据的聚合。在Reducer阶段,将通过排序的数据传输给table聚合器,使用table聚合器对数据进行聚合操作,并取回聚合的结果,使用Reducer的输出流,将结果写回XFS. 如下图所示:


红线为数据流, 黑线为执行流


    通过将数据在Sawzall Process和Mapper Process, Reducer Process之间传输,Dagger利用sawzall语言编写的简易和便利性,结果Mapreduce编程框架,实现了一个脚本驱动,基于分布式运算框架,能够处理海量数据分析的精悍的工具。Dagger中整体的数据流程图如下:


红线为mapper数据流, 绿线为reducer数据流,黑线为执行流