为什么我们真的需要一个类似Flume 的系统呢? 为什么不直接将数据从应用服务器写到HDFS?
将系统之间彼此隔离的消息系统已经存在了很长时间,在Hadoop 环境中Flume 做了这样的工作。Flume 是专门设计用来从大量的源,推送数据到Hadoop 生态系统中各种各样存储系统中去的,例如HDFS 和HBase。
一般来说,当在Hadoop 集群上,有足够数据处理的时候,通常会有很多生产数据的服务器。这些服务器的数量是上百甚至是上千的。这样庞大数量的服务器试着将数据写入HDFS 或者HBase 集群,会因为多种原因导致重大问题。
HDFS 确切地需要一个客户端写入到文件——因此,在同一时间可能有成千上万的文件写入。每次一个文件被创建或者一个新块被分配,在NameNode 节点会发生一组复杂的操作。如此庞大数量的操作同时发生在服务节点上,可能会造成服务器承受巨大压力。
而且,当成千上万的机器写大量数据到小数量机器的时候,连接这些机器的网络可能会不堪重负并且开始经历严重的延迟。
很多情况下,存在于多个数据中心的应用程序服务器,在托管Hadoop 集群的单个数据中心聚合数据,这意味着应用程序必须通过广域网(WAN)写数据。在所有这些情况下,应用程序在尝试写入HDFS 和HBase 的时候,可能会遇到严重的延迟。如果托管应用程序的服务器数量或写数据的应用程序数量增加,延迟和失败率可能会增加。因此,在设计写入到HDFS 的软件时,要把HDFS 集群和网络延迟作为额外考虑的因素。
大多数应用程序以预见的方式查看生产流量,每天高峰流量有几个小时,其余时间的流量很小。为了确保应用程序直接写入HDFS 或HBase 时,不丢失数据或不需要缓冲很多数据,需要配置HDFS 或HBase 集群,以很少或没有延迟的方式处理峰值流量。所有这些案例可以清楚地看到,从HDFS 或HBase 隔离生产应用程序,且保证生产应用程序用可控和良好组织的方式推送数据到这些系统,是很重要的。
Flume 被设计成为一个灵活的分布式系统,可以很容易地扩展,而且是高度可定制化的。
一个配置正确的Flume Agent 和由相互连接的Agent 创建的Agent 的管道,保证不会丢失数据,提供持久的Channel。
Flume 部署的最简单元是Flume Agent。一个Flume Agent 可以连接一个或多个其他的Agent。一个Agent 也可以从一个或多个Agent 接收数据。通过相互连接的多个FlumeAgent,一个流作业被建立。这个Flume Agent 链条可以用于将数据从一个位置移动到另一个位置——特别是,从生产数据的应用程序到HDFS、HBase 等。
大量的Flume Agent 从应用服务器接收数据,然后将数据写入到HDFS 或者HBase(无论是直接或者通过其他Flume Agent), 通过简单增加更多的Flume Agent 就能够扩展服务器的数量并将大量数据写入到HDFS。
每个Flume Agent 有三个组件:Source、Channel 和Sink。Source 负责获取事件到FlumeAgent,而Sink 负责从Agent 移走事件并转发它们到拓扑结构中的下一个Agent,或者到HDFS、HBase、Solr 等。Channel 是一个存储Source 已经接收到的数据的缓冲区,直到Sink 已经将数据成功写入到下一阶段或者最终目的地。
实际上,在一个Flume Agent 中的数据流以下面几种方式运行:生产/ 接收的数据源写入数据到一个或者更多Channel,一个或者多个Sink 从Channel 读取这些事件,然后推送它们到下一个Agent,或者存储和索引系统。
Flume Agent 可以被配置成在数据被写入到目的地之前,从管道的一个Agent 发送数据到另一个Agent。一旦数据到达Flume Agent,数据的持久性完全取决于Agent 使用的Channel 的持久性保证。在一般情况下,当一个Flume agent 被配置成使用任何的内置Source 或Sink 以及一个持久的Channel,Agent 保证不会丢失数据。凭借独立Agent 不丢失数据的优势,Flume 管道也不会丢失任何数据。
如果Flume 管道中有意想不到的错误/超时并进行了重试,Flume 会产生重复的数据最终被写出。如果托管持久Channel 的硬盘遇到不可恢复的失败,Flume 可能会因为硬盘故障而丢失数据。虽然可能会引起冗余,Flume 允许用户通过冗余流复写事件,以确保硬盘和Agent 失败是可控的。所以,用户可能必须通过做一些后期处理来确保妥善处理这些冗余。
——本文摘自《Flume:构建高可用、可扩展的海量日志采集系统》