大数据架构商业之路:从业务需求到技术方案
上QQ阅读APP看书,第一时间看更新


2.2.1 Apache Flume简介

Flume(http://flume.apache.org/)是一个分布式、可靠和高可用的海量数据收集系统,目前最新的版本是1.6.0。它同时采用推送和拉取这两种采集模式,其能力受到了业界的认可与广泛应用。它支持在系统中定制各类数据发送方,同时还支持对数据进行简单处理,然后写到各种可定制的数据接收方。Flume最早属于知名的Cloudera公司,初始的发行版本被统称为Flume-OG(Original Generation),目前版本号是Flume 0.9X这种形式。随着Flume功能的扩展,Flume-OG代码工程臃肿、核心模块设计不合理、核心配置不标准等缺点纷纷暴露出来,尤其是在Flume-OG的最后一个发行版本0.94.0中,日志传输不稳定的问题尤为突出。为了解决这些问题,2011年Cloudera完成了Flume中里程碑式的改动,核心模块、核心配置及代码架构都得到了重构,改善后的新版本统称为Flume-NG(Next Generation),版本号都是Flume 1.X形式。与此同时,Flume也被纳入Apache社区,Cloudera Flume正式改名为Apache Flume。本书后面提到的Flume如无特殊说明均指Flume-NG。

Flume的核心模块有三个:

  • 源头(Source):负责接收数据的模块,它定义了数据的源头,从源头收集数据,传递给通道。源头还可用于接收其他Flume代理的沉淀器传输过来的数据。
  • 沉淀器(Sink):批量地从通道读取并移除数据,并将所读取的内容存储到指定的位置。
  • 通道(Channel):作为一个管道或队列,连接源头和沉淀器。

通过这几个模块,形成了如下重要概念:

  • 代理(Agent):Flume运行在服务器上的程序,是最小的运行单位。每台机器只会运行一个代理,其中可包含多个源头和沉淀器。
  • 事件(Event):Flume的数据流由事件贯穿始终,是应用逻辑上的基本处理单元,如当Flume处理网站日志记录的收集时,事件可以是一条日志记录,它携带日志数据和头信息。代理中的源头会生成这些事件,进行特定的格式化,然后将事件推入若干通道中。你可以将通道看作一个缓冲区,它将保存事件直到沉淀器处理完该事件为止。沉淀器负责持久化日志或将事件推向另一个源头,这也表明Flume的数据流传输是可以嵌套的,经过多级的传递和预处理。

Flume的整个收集流程可以通过图2-9来展示。

图2-9 Flume工作的基本流程

在图2-9中,我们可以将源头想象成为一个水龙头,沉淀器是一个水桶,而通道就是水管。水管两头分别接上水龙头和水桶,当水龙头打开,水就源源不断地通过水管流入水桶。

Flume的一大优势在于它是集群化管理,如果需要采集的应用过多的时候,单个Flume的代理可能就无法处理了,这时就需要更多的代理来组成集群,图2-10显示了大体的架构,其中从应用程序端到集群就需要做流量的负载均衡。类似的比方,这里可以想象成水龙头有太多的水需要放出,一根水管远远不够,因此需要接多根水管用于传送。

图2-10 使用Flume集群处理更多的数据流

前文也提到过,Flume的数据流是可以通过多级嵌套来进行传输的,图2-11就体现了这样的架构。如此架构的优势在于,可以将不同的处理逻辑分层,以便于开发、测试和管理。同时,也能更好地控制数据流缓冲的节奏。同样,我们可以认为是通过管道连接器将多段水管连接起来了。每个连接器还可以加入不同的净水处理模块,比如,让第1段和第2段水管连接器进行活性炭吸附杂质,而第2段和第3段的水管连接器进行紫外线杀菌,等等。

图2-11 层次型的Flume集群架构

从上述的模块和流程中可以看出,源头、沉淀器和通道的实现至关重要。好消息是,对于三大模块,Flume已经为我们实现了很多的基本功能,下面来快速浏览一下。

Flume的源头主要包括:

  • Spooling Directory源头:在一些场景中,应用数据产生后会被存入本地的文件中,文件中的一行或若干行组成一个逻辑单元。但是不同的应用会导致不同的字段定义和格式,而你又无法修改这些应用本身,如何将这些信息整合是一个令人头疼的问题。这个时候Spooling Directory源头就有了用武之地,它是非常简单和常用的源头,会监视指定目录的变化,从这些目录的文件中读取所需要的数据,并且进行必要的预处理,将不同数据源的内容转化为对应于Flume的事件。由于Spooling Directory源头是磁盘I/O读取密集型的,所以它的性能通常不会很高。
  • HTTP源头:该源头可以通过HTTP的POST方式接收数据。从客户端的角度来看,它的表现就像Web服务器一样,同时还接收Flume的事件。
  • JMS源头:JMS的全称是Java消息服务(Java Message Service),用于在分布式系统中发送消息,进行异步通信。在第3章的及时性数据处理中,我们还会详细介绍。Flume自带的JMS源头可以获取来自Java消息服务队列或主题的数据,如ActiveMQ和Kafka等。
  • 嵌套:Avro和Thrift这样的源头,可以和上一级代理的沉淀器进行对接,实现代理的多级嵌套。

Flume封装的沉淀器也不少,能够写到例如HDFS、HBase、Solr和Elasticsearch如果你对这些名词陌生,不用担心,后面相应的章节会有介绍,此处可以暂时忽略。等存储和检索引擎中。由于它们在Flume流程中通常都是最终点,因此这些类型一般被称为终端沉淀器。另外一些类型,如Avro和Thrift沉淀器,将与之前介绍的Avro和Thrift源头对接,用于将数据传给下一级代理。

  • HDFS沉淀器:在大数据架构方案中,它是十分常用的沉淀器,可以将数据直接写入Hadoop的分布式文件系统HDFS中,便于大规模的数据存储。该沉淀器非常灵活,可以根据不同事件的报头、时间戳等信息,配置不同的目录中。
  • HBase沉淀器:HBase是基于Hadoop的宽表系统。直接写入HBase的沉淀器将使得查询HDFS中的数据变得更为高效。
  • Morphine Solr沉淀器:Morphine是一个高度扩展的ETL(Extraction,Transform and Load)框架,这里它可以将Flume的事件加载到Solr搜索引擎,通过Solr的索引和查询功能,实现更为强大的数据功能。
  • Elasticsearch沉淀器:Elasticsearch是一个类似Solr的搜索引擎实现,Flume同样可以将数据存储到其中,并让Elasticsearch对这些数据进行下一步的处理。
  • 嵌套:Avro和Thrift这样的沉淀器,用于将数据传给下一级代理。

Flume自带两种通道:

  • 内存通道:该通道是内存中的队列,源头从它的尾部写入数据,而沉淀器从它的头部读取数据。由于都是内存操作,因此内存通道可以支持非常高的吞吐量。不过由于是非持久化数据的持久化和非持久化概念,会在第3章的开头进行介绍。的方式,存在丢失数据的风险。
  • 文件通道:该通道会将事件都写入到磁盘中,以持久化的方式保存。这样数据就不会因为突然宕机或断电而丢失,而且海量数据的存储成本也较低,不过其性能远远不及内存通道。综合来看,如果对于数据的丢失无法容忍,并且不在意数据处理的速度,那么文件通道是理想的选择。相反,如果对系统反应速度要求很高,而且能允许一定程度的数据丢失,那么就可以选择内存通道。

还有一些源头和沉淀器通道的实现在这里没有被提及。更为重要的是,我们不要忘记Flume是开放源代码的,这就意味着开发者们完全可以自定义这些模块的功能和实现。