日志收集系统解决方案探讨
dutianmin@gmail..com
一、 需求背景
公司许多平台系统每天都会产生很多日志,日志的产生是源源不断的流数据(如网页pv,游戏实时在线等),为什么分析数据,需要一套通用的日志系统来传输这些数据,一般而言,这个系统需要具备以下几个特征
(1) 解耦在线应用系统与分析系统,为他们之间搭起桥梁
(2) 支持数据的实时、有序的传输,以便做实时统计与分析
(3) 具有高可扩展性,日志系统随着流数据的增加可添加节点水平扩展
(4) 容错性好
二、 系统组成
现在日志系统已经开源的比较多,比如最早的facebook的scriber(C++),以及采用push/pull
方式的Linkedln的Kafka(scala) 阿里的TimeTunnel(java),还有功能齐全的的Cloudera的Flume(java)通过对比总结这些系统,可以知道,一个日志系统一般都会有一下组件
(1) Agent: 主动采集数据,并把数据推送到collector
(2) Collector: 接收多个agent的数据,并能把数据实现有序可靠且高系能的转发,并提 供容错功能
(3) Store: 存储系统,接收或主动拉去collector的数据,并写入存储系统或其他系统直接用作计算
图1 采集系统基本架构
图1,就是整个系统的整个架构,除了上述提到的几个组件,系统一般还会考虑组件间负责均衡,相互通信而设计另外的组件,负责均衡一般用zookeeper实现,组件间通信用thrift的居多(一般都是给客户端提供各种语言的API实现RPC调用,hadoop、hive 、hbase都采用这样的方式)
三、 TimeTunnel介绍
TimeTunnel(简称TT)是一个基于thrift通讯框架搭建的实时数据传输平台,具有高性能、实时性、顺序性、高可靠性、高可用性、可扩展性等特点。
高性能
2k大小的消息,峰值每秒4wTPS的访问。淘宝3台服务器,每天处理2.3T(压缩后)数据,峰值每秒50MByte流入流量、130MByte流出流量
实时性
90%的消息5ms以内送达
顺序性
节点的主从关系和顺序也是通过zookeeper保证。消息顺序的实现是通过称为router的路由到固定节点做传输,如果你开启了顺序传输功能,timetunnel保证消息的发布顺序和订阅顺序是一致的,
高可靠性
存储方面,我们设计了内存->磁盘->hadoopdfs三级缓存机制,确保数据可靠。 系统方面,我们将服务器节点组织成环,在环里面每一个节点的后续节点是当前节点的备份节点,当某节点故障时,后续节点自动接管故障节点数据,以保证数据可靠性
高可用性
单个节点故障,不影响系统正常运行,TT在高可用性上的方案也很有特色,所有的服务器节点形成一个环,两两相互主辅备份。
可扩展性
可以对系统进行横向和纵向扩展,横向扩展可以向现有的服务环里面增加节点,纵向扩展可以增加服务环
目前TimeTunnel在淘宝广泛的应用于日志收集、数据监控、广告反馈、量子统计、数据库同步等领域。
图2 TT架构
整个系统大概分四部分:client,router,zookeeper,broker
client
用户访问timetunnel的接口,通过client用户可以向timetunnel发布消息,订阅消息。
router
timetunnel的门户,提供安全认证、服务路由、负载均衡三个功能。router知道每个broker的工作状态,router总是向client返回正确的broker地址。
zookeeper
timetunnel的状态同步模块,router就是通过zookeeper感知系统状态变化,例如增加/删除broker环、环节点的增删、环对应的topic增删、系统用户信息变化等。
broker
timetunnel的核心,负责消息的存储转发。broker以环的形式组成成集群,可以通过配置告知router哪些数据应该被分配到那个集群,以便router正确路由。环里面的节点是有顺序的,每个节点的后续节点自己的备份节点,当节点故障时,可以从备份节点恢复因故障丢失的数据。
四、 基于TimeTunnel的日志系统
TT是基于push/poll方式的框架,提供了客户端API(现在支持java、python),它的Agent
组件以及Store组件都要根据提供的客户端进行开发
Agent数据采集
TT只负责被动的接收传入它的数据,而不会主动去抓取数据。为了向TT的broker推送数据,我们必须实现Agent抓取数据功能,通过TT提供的客户单API接口传给TT的broker。
把写入日志到TT服务器的功能集成到应用系统是一种可行的解决方案,但是不是唯一的解决方案,我们还可以现实一个单独的Agent,专门用来抓取应用系统生成的日志文件,然后写入到scribe服务器。下面就针对这两种方案具体探讨。
(1)单独的数据采集端
写一个单独的客户端是一种适用于任何应用系统的解决方案,前提是应用系统需要产生日志文件(如采用java的log4j参数的滚动文件日志)。这个单独的客户端可以用thrift支持的任何一种语言实现,不过通常采用python实现,方便修改、扩展和部署。
这种解决方案实现的方式有两种:一是循环的去检测日志文件或文件夹,如果有新的日志生成就读取日志文件并上传到TT服务器;二是通过监控系统的读写事件的机制来监控文件或文件夹的变化而抓取增量数据。
这种方案一个很大的有点就是通用性强,不需要和应用系统集成,对应用系统没有影响,但却开发成本高且效率低
这种方案需要考虑单点故障问题,如和TT不能通信了,怎么把抓取的数据保存起来,等到和TT恢复通信后把把累计的数据重新发给TT,如采集节点挂掉,重启后怎么把错过的增量数据也抓取过来等
(2)把Agent集成到应用系统
与系统集成有两种解决方案,一是通过TT提供的开发API自己开发,另一种是通过与日志工具(如log4j)集成
这种方案写入日志的效率更高,因为不需要在通过一个转发的环节,通过应用系统直接写入,而且这种方案降低了出错的可能性,不需要单独去维护一个程序了。但是这种解决方案会对应用系统有一定的影响,因为它作为应用系统的一个功能模块加入,所以需要加入额外的jar和需要额外的占用应用系统开销,除了这些还需要考虑TT服务器不能正常通信时的异常处理,还有就是不具有通用性,每一个应用系统需要单独开发一个这样的功能模块(开发的思路和方法基本相同)。