实时日志分析系统的基本架构

5,447 阅读6分钟

这段时间的文章,主要关注在团队的成长和流程的梳理,缺乏真正的技术”干货“。所以,今天打算分享一下构造日志分析系统的思路,来围绕技术话题多讲一讲,感觉自己还是适合多讲讲技术。言归正传,做这个系统的出发点很简单,就是在做大促活动期间,运营的同事希望能实时看到用户的行为数据和订单的情况,从而根据数据能及时有效的调整运营策略。虽然互金产品的用户量还远不能和国内龙头电商的大促期相比,但是活动期间的日志的量还是普通的架构难以招架的,所以做了一些调研后,实时日志分析系统的架构如下:


引入了Flume+Kafka+Storm来做作为班底,并继续通过Redis+Mysql的“经典”组合来做好日志数据处理后的存储。下面会分开讨论一下,选择这组班底的原因和过程中的思考。

通过Flume收集日志数据

最初的时候,有两套收集日志的思路,一是考虑通过shell脚本来批量处理日志文本,二是在程序中将要收集的日志数据直接通过一组特定的API来收集。不过这两种方案很快就被否定了,方案一的问题是工作量大,脚本不方便维护,维护成本相当高。方案二的问题是业务代码侵入性大,很难及时对API进行调整或者更新,最重要的一点在于,这个方案对业务服务的性能也是有一定的影响。

经过调研后,决定采用第三方框架Flume进行日志采集,Flume是一个分布式的高效的日志采集系统,它能把分布在不同服务器上的海量日志文件数据统一收集到一个集中的存储资源中,与Kafka也有很好的兼容性。

为什么不使用Logstash?

坦白的说,在这个项目前,我对Flume一无所知。我在顺丰的时候,对日志进行处理,用的是ELK组合(ElasticSearch、Logstash、Kibana),所以我对Logstash更加熟悉。之所以考虑Flume有两个原因:

1. Flume + Kafka的组合的方案更加成熟,由于考虑Kafka来做消息系统,会考虑反推使用Flume。

1. Flume的优势,在于传输的稳定性,所以既然是业务数据的分析,稳定性自然是重点考虑的一点。Flume的agent是运行在JVM上的,每一个Flume agent部署在一台服务器上,Flume会收集应用服务产生的日志数据,并封装成一个个的事件发送给Flume Agent的Source。Flume提供了点对点的高可用的保障,某个服务器上的Flume Agent Channel中的数据只有确保传输到了另一个服务器上的Flume Agent Channel里或者正确保存到了本地的文件存储系统中,才会被移除。

搭建消息处理系统

Kafka提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息。

(图片摘自Kafka官网)

kafka在日志分析系统中实际上就相当于起到一个数据缓冲池的作用, 因为是基于log File的消息系统,数据不容易丢失,以及能记录数据的消费位置并且用户还可以自定义消息消费的起始位置,这就使得重复消费消息也可以得以实现,而且同时具有队列和发布订阅两种消息消费模式,十分灵活,并且与Storm的契合度很高,充分利用Linux系统的I/O提高读写速度。

通过Storm进行Steaming Computing

Storm是一个开源的分布式实时计算系统,常被称为流式计算框架。什么是流式计算呢?通俗来讲,流式计算顾名思义:数据流源源不断的来,一边来,一边计算结果,再进入下一个流。例如,一个理财产品一直不间断的运行,会持续进行金融产品交易、用户的所有行为都记录进日志里;海量数据使得单节点处理不过来,所以就用到分布式计算机型,Storm 是其中的典型代表之一,一般应用场景是:中间使用一个消息队列系统如kafka,先将消息缓存起来,Storm 中有很多的节点,分布式并行运行处理程序,进行数据处理。

从Kafka comsumer到Storm的流程如下:

根据Storm的编程模型,实现这个数据处理需求需要建立1个数据源Spout组件,2个业务逻辑组件Bolt,以及一个Topology结构,将这3个组件加入到这个topology结构中。 Spout用于产生数据或者从外部接收数据,它相当于数据源;Bolt用于消费从Spout发送出来的数据流并实现用户自定义的数据处理逻辑;对于复杂的数据处理,可以定义多个连续的Bolt去协同处理。tuples是Storm的数据模型,由值和其所对应的field所组成。

在Storm中提出了Stream Group的概念,它用来决定从Spout或Bolt组件中发出的tuples接下来应该传到哪一个组件,明确了在程序里设置某个组件应该接收来自哪一个组件的tuples; 并且在Storm中提供了多个用于数据流分组的机制,比如说shuffleGrouping,随机分组,随机派发stream里面的tuple,保证每个bolt task接收到的tuple数目大致相同。最后在程序中通过Spout和Bolt生成Topology对象并提交到Storm集群上执行。Topology类便将之前编写的1个spout 和2个bolt组装到一个topology中,并通过追加shuffleGrouping方法设置了他们之间的数据传递方向,以及进程个数。

最后一点总结

基于以上的FKS组合的讨论,实时日志分析系统的运行流程如下:

  1. 通过Flume去监听业务系统产生的日志,并实时把每一条日志信息抓取下来并存进Kafka消息系统中;

  2. 接着由Storm系统消费Kafka中的消息,使用用户定义好的Storm Topology去进行日志信息的分析并输出到Redis缓存数据库中;

  3. 同时将redis缓存的数据,定期同步到MySQL中;

  4. 为了服务各个前端系统,建立了一套API服务,方便获得各个维度的数据。

扫描二维码或手动搜索微信公众号【架构栈】: ForestNotes

欢迎转载,带上以下二维码即可