基于Flume的野狗实时日志系统的演进和优化

图片描述

本文是野狗实时后端云 (www.wilddog.com)资深工程师廖斌旭在“iGeek Camp”第4期北京站上进行的《基于Flume的野狗实时日志系统的演进和优化》的演讲实录,主要分为两个部分:野狗日志系统的架构演进和优化方案。redis

在讲解日志架构以前,先介绍一下咱们野狗的业务。咱们的业务共有两类SDK,基于两种链接技术。第一类是WebSocket长链接或用Long polling模拟的长链接,另一类是HTTP REST短链接。shell

图片描述

你们看这张图,野狗的业务架构分为两层,第一层是接入层,包括NodeJs接入层、Nginx Rest API接入层;第二层是核心业务处理层,包括数据处理和Push server同步推送。SDK经过长链接或短链接与接入层相链接。全部的请求都经过SDK发送到接入层,接入层转化协议,而后转发到业务处理层。因此接入层是用户访问的入口,天生适合作流控和统计。数据库

幻灯片04

野狗的日志业务主要分为两类:平常日志和计费服务。平常统计包括UV、PV以及客户的API操做记录。后面又由于业务需求,增长了计费服务,主要包括流量统计和链接数统计。后端

幻灯片05

咱们的初版,很简单。使用crontab命令来定时执行rsync命令,同步日志文件。api

幻灯片06

从这张图能够看到,接入层经过打本地日志的方式,把请求信息记录下来。而后使用crontab定时执行rsync同步日志到“日志归档服务器”。处理统计业务的服务“cloud-stat”,定时从“日志归档服务器”获取日志文件,而后把计算的流量统计结果保存到数据库中。可是设计架构的目标并不只仅是完成需求,同时还要知道它的优点和劣势,才能了解架构下一步的改进方向。接下来,咱们来看看v0.1版本的优缺点。缓存

幻灯片07

最突出的优势是简单,使用两条命令就能搞定。使用rsync命令比SCP更灵活,由于前者支持增量拷贝。还有一个优势就是支持数据压缩。服务器

可是由于有了流量数据,因此想作实时流控,仍是挺难的。由于定时同步最快可以作到分钟级别,实时性不够。文件在多台服务器之间流转,也增长管理的文件的成本。文件的多副本,同时也会形成存储的浪费。架构

因此基于实时性的考虑, 咱们又改进了日志系统的架构。这就是咱们的v0.2版。性能

幻灯片08

介绍v0.2架构以前,先描述下项目背景。由于项目时间很是紧张,因此咱们引进了redis作流量数据的缓存。可是这个方案并非行业的最优的作法,不过当时已经搭建redis集群,正好可以解决实时性的需求。优化

幻灯片09

咱们来看下下面这张图。Redis做为生产者消费者模式的缓冲队列,接收“接入层”的流程数据,并交给统计业务消费。NodeJs接入层和Nginx Rest API接入层,把流量数据经过redis的客户端写入Redis集群。统计业务cloud-stat 则定时从redis集群消费。时间从v0.1的最快分钟级别,降到如今5秒内完成日志产生、收集、处理整个过程。这对于咱们系统的实时性是一个很大的提高。

幻灯片10

通过改进以后,日志系统的延迟下降了,这也是咱们v0.2的主要目的。可是,任何系统都不是完美的。日志文件记录咱们的最原始的用户访问记录,这些数据咱们不能丢。加上redis这套架构,并存两套架构,就在无形中增长了咱们的维护成本。Redis缓存在带来高性能的同时,也带来了一个副产品,就是在接入层必须硬编码redis的逻辑。

幻灯片11

经历两版的系统改造,咱们有了一点心得:一是利用日志干更多的事情,二是日志统计不要侵入原系统。

幻灯片12

通过前两版的积累,在v0.3咱们决定引入flume服务,来作日志收集。主要体如今两点:一是在日志源服务器部署flume agent,第二个就是增长了中心化的收集服务flume collector。

幻灯片13

如今的日志系统分为3层,一是部署在接入层机器上的flume agent,二是中心化收集服务器flume Collector,三是日志处理服务。

接入层生成的日志,由flume agent进程,经过avro rpc发送到flume Collector。日志在collector汇总以后,主动发给第三层日志处理服务。主要包括统计服务cloud-stat、 分析服务analyze和日志归档服务log archive。

幻灯片14

前面咱们讲了v0.3的架构图,如今详细介绍一下flume。Flume的全名是Apache Flume,最初由 cloudera公司开发。捐给Apache基金会后,命名从flume-og更名为flume-ng,又称为Apache Flume。

下面介绍一下flume相关的几个术语:

Event:一个数据单元,带有一个可选的消息头。
Flow:Event从源点到达目的点的迁移的抽象。
Client:操做位于源点处的Event,将其发送到Flume Agent。
Agent:一个独立的Flume进程,包含组件Source、Channel、Sink。
Source:用来消费传递到该组件的Event。
Channel:中转Event的一个临时存储队列,保存有Source组件传递过来的Event。
Sink:从Channel中消费Event,将Event传递到Flow Pipeline中的下一个Agent。
它的设计目标主要是可靠、可伸缩、易扩展和易管理。下面咱们介绍几个经常使用的解决方案:

一是Flume串联,它适用收集日志的规模较小的场景。

二是Flume多路Agent,能实现更复杂的业务逻辑。

三是Flume 并联,它提升了日志汇聚效率,可是存在单点问题。

四是复杂均衡,主要用于解决单点问题。

介绍完Flume的架构和使用场景。下面讲一讲,Flume在野狗云中的使用以及遇到的问题。野狗云使用Agent的主要收集接入层产生的本地日志文件。前面讲到Source是Agent用于接收数据的一个组件。Flume提供了多种基于日志文件的Source,包括两种:ExecSource和SpoolingDirSource。

幻灯片22

ExecSource 的主要做用是,在Agent中执行shell脚本或shell命令,而后经过管道接收前者的数据。咱们主要建立了两种接入层的日志。

一是Rest API 接入层流量日志:日志格式是 restapi.access.log, 天天零点把原来的日志更名为 restapi.access.log.date -d "a days ago" "+%Y-%m-%d", 而后再建立文件 restapi.access.log。这种机制叫作日志轮转。
二是NodeJs 接入层流量日志:日志格式是 longconnect.log.date "+%Y-%m-%d", 天天零点建立按天的日志文件。
在这个过程咱们碰见了几个问题。一是当发生日志轮转的时候,由于tail -f命令打开的仍是原来的文件描述符,因此就没法获取到当天新日志文件的内容。不过tail命令的--retry选项会按期检查文件名对应的文件描述符的变化。这就解决了咱们这个问题。另一个就是没有办法作到生产速率控制。这个咱们在下面的PPT会讲到。

幻灯片23

SpoolingDirSource用于监控文件目录变化的,可是实际的使用中会有如下两个问题:一是文件不能写,只能读。二是延迟比较高,须要等待日志按期归档。

幻灯片24

为了解决速率控制的问题, 咱们用Java程序实现了“模拟tail -F”的功能,主要是使用ExceSource,定时修改Flume的配置文件。另外就是根据咱们的需求自定义Source。

幻灯片25

Channel的功能是作缓存队列,Flume提供两种Channel。

幻灯片26

MemoryChannel使用内存作缓冲队列,全部数据都保存在内存。可是这样作有两个问题:一是可用性差,另外一个就是当队列数量小于阈值时,会一直等待被消费。

幻灯片27

FileChannel使用磁盘作缓冲队列,全部数据都保存在磁盘。它的一个问题就是吞吐量比较低。

幻灯片28

由于咱们野狗自身的需求,在要求实时的同时,还要保证必定的可用性。美团的解决方案是提供一种基于内存Channel和FileChannel的Channel。

而咱们野狗本身开发了一种基于MemoryChannel的加强Channel,主要增长了队列序列化功能,而且在重启的时候可以作到持久化。另外由于Flume低于阈值时才会触发Channel被消费事件,而咱们在流量较低时也有收集日志的需求,因此在原生系统上又增长了空闲超时检测。

幻灯片29

谢谢你们。

相关文章
相关标签/搜索