设计一套实时分布式日志流收集平台(tail Logs --->HDFS)

目前业界大概这么几个开源的分布式日志系统,notify+rsync,Facebook 的Scribe,apache的chukwa,linkin的kafa和cloudera的flume。
之所以自己设计一台这么一个平台,而没有采用开源,主要是基于这么考虑
   1、以上这几种开源日志系统,虽然提供了日志tail实时输出的功能,但是在tail进程宕掉后,无法从收集的点开始收集,只能重新开始,这样有很多重复的日志
   2、这几种开源的日志系统功能比较全面,但是对我们平台来说,只用部分的功能,设计一个简单可用可控的平台是我们的一个目标
这篇文章讲述了笔者以前自己设计的一个日志收集平台的技术细节,在电商开放平台中有应用到。
应用场景是这样的,
平台中各个应用客户端会实时产生大量的日志,需要实时把各个应用客户端的日志收集起来,发送到分布式文件系统中,供后续的数据挖掘和分析。
数据会收集到HDFS中,每天定时生成一个文件(文件前缀为日期,后缀为序列号从0开始),并且当文件的大小超多一定大小时,自动生成一个新的文件,文件前缀为当前日期,后缀为当前序列号递增。
系统的运行架构图,以及相关说明
设计一套实时分布式日志流收集平台(tail Logs --->HDFS)

 

说明如下:
1、首先启动一个日志扫描线程(扫描日志目录),当有本地日志文件生成的时,会生成一个日志tail任务,放到日志tail队列中等待调度。
2、对任务队列中的tail任务从线程池获取一个tail线程,该线程的职责是tail日志文件,输出到MQ中。在输出到MQ的同时,把当前的行号LSN记录到LSN Store中, 这里有一个考虑是如果日志tail线程宕掉,可以从宕掉时的日志行开始tail(seek操作)。
3、Collector节点启动多个线程从MQ中获取日志数据,并梳理日志的类别(操作日志,访问日志,业务日志等),根据不同的类型写到HDFS中不同的文件。如果在写入过程中,出现错误(比如HDFS暂时不可访问,这里有告警机制),那么就暂存在本地,等待恢复正常后,批量导入到HDFS中。
4、Lsn记录器,记录日志当前tail到哪一行了,在tail时,先写入Lsn Buffer中,是append方式,当超过一定的100M大小或者一定时间间隔时,就写到LSN File,只写最后的行号,并清除buffer。
     这样做的好处是,append数据到buffer(而不是update操作)的内存操作非常快。宕机恢复,在查询时,先从buffer查找,如果buffer中不存在,再从File中查找。
5、对于HDFS文件名称的切换按照以下策略进行
   每天定时生成一个文件(文件前缀为日期,后缀为序列号从0开始),并且当文件的大小超多一定大小时,自动生成一个新的文件,文     件前缀为当前日期,后缀为当前序列号递增。
    实现了两个Trigger,分别为SizeTriger(在调用HDFS输出流写的同时,count该流已经写入的大小总和,若超过一定大小,则创建新的文件和输出流,写入操作指向新的输出流,同时close以前的输出流)和TimeTriger(开启定时器,当到达该点时,自动创建新的文件和输出流,新的写入重定向到该流中,同时close以前的输出流)。
 
附带HDFS flush写数据说明:
HDFS操作过程中,只有在流flush(当数据包满的时,会自动flush;或者手动flush)和关闭的时候,才真正的写数据到datenode的硬盘上,那么对于HDFS来讲,默认的packet是64K,当超过数据超过64K时,会自动进行输出到dataNode的输出流中。
调用close时候,会自动把未构成一个packet的数据,也输出到dataNode输出流中写到datanode硬盘,完成后汇报给NameNode(当然datanode中的数据大小超过一个块如64M的时候,也会向NameNode汇报)

你可能感兴趣的:(hadoop,hdfs)