基于Storm的Nginx log实时监控系统

标签: Hadoop Adative Counting ANTLR Storm 基数计数 | 发表时间:2014-09-01 17:49 | 作者:钟国英
出处:http://tech.uc.cn

背景

UAE(UC App Engine)是一个UC内部的PaaS平台,总体架构有点类似CloudFoundry,包括:

  1. 快速部署:支持Node.js、Play!、PHP等框架
  2. 信息透明:运维过程、系统状态、业务状况
  3. 灰度试错:IP灰度、地域灰度
  4. 基础服务:key-value存储、MySQL高可用、图片平台等

这里它不是主角,不作详细介绍。

有数百个Web应用运行在UAE上,所有的请求都会经过UAE的路由,每天的Nginx access log大小是TB级,如何实时监控每个业务的访问趋势、广告数据、页面耗时、访问质量、自定义报表和异常报警?

Hadoop可以满足统计需求,但秒级的实时性不能满足;用Spark Streaming又有些大材小用,同时我们也没有Spark的工程经验;自写分布式程序调度比较麻烦并且要考虑扩展、消息流动;

最后我们的技术选型定为Storm:相对轻量、灵活、消息传递方便、扩展灵活。

另外,而由于UC的各地集群比较多,跨集群日志传输也会是其中一个比较大的问题。

技术准备

基数计数(Cardinality Counting)

在大数据分布式计算的时候,PV(Page View)可以很方便相加合并,但UV(Unique Visitor)不能。

分布式计算的情况下,几百个业务、数十万URL同时统计UV,如果还要分时段统计(每分钟/每5分钟合并/每小时合并/每天合并),内存的消耗是不可接受的。

这个时候,概率的力量就体现了出来。我们在 Probabilistic Data Structures for Web Analytics and Data Mining可以看到,精确的哈希表统计UV和基数计数的内存比较,并不是一个数量级的。基数计数可以让你实现UV的合并,内存消耗极小,并且误差完全在可接受范围内。

可以先了解 LogLog Counting,理解均匀哈希方法的前提下,粗糙估计的来由即可,后面的公式推导可以跳过。

具体算法是 Adaptive Counting,使用的计算库是 stream-2.7.0.jar

实时日志传输

实时计算必须依赖于秒级的实时日志传输,附加的好处是可以避免阶段性传输引起的网络拥堵。

实时日志传输是UAE已有的轻量级的日志传输工具,成熟稳定,直接拿来用了,包括客户端(mca)和服务器端(mcs)。

客户端监听各个集群的日志文件的变化,传输到指定的Storm集群的各台机器上,存储为普通日志文件。

我们调整了传输策略,使得每台Storm机器上的日志文件大小大致相同,所以Spout只读取本机数据即可。

数据源队列

我们并没有用Storm常用的队列,如Kafka、MetaQ等,主要是太重了…

fqueue是一个轻量的memcached协议队列,把普通的日志文件转为memcached的服务,这样Storm的Spout就可以直接以memcached协议逐条读取。

这个数据源比较简单,它不支持重新发射(replay),一条记录被取出之后就不复存在,如果某个tuple处理失败或超时,则数据丢失。

它比较轻量,基于本地文件读取,做了一层薄的缓存,并不是一个纯内存的队列,它的性能瓶颈在于磁盘IO,每秒吞吐量跟磁盘读取速度是一致的。但对于我们这个系统已经足够,后续有计划改成纯内存队列。

架构

通过上面的技术储备,我们可以在用户访问几秒后就能获取到用户的日志。

discovery_arch

整体架构也比较简单,之所以有两种计算bolt,是基于计算的均匀分布考虑。业务的量相差极大,如果仅按业务ID去进行fieldsGrouping,计算资源也会不均衡。

  1. spout将每条原始日志标准化,按照URL分组(fieldsGrouping,为保持每台服务器计算量的均匀),派发到对应的stat_bolt上;
  2. stat_bolt是主要的计算Bolt,将每个业务的URL梳理并计算,如PV、UV、总响应时间、后端响应时间、HTTP状态码统计、URL排序、流量统计等;
  3. merge_bolt将每个业务的数据合并,如PV数,UV数等。当然,这里的UV合并就用到了前面提到的基数计数;
  4. 自写了一个简单的Coordinator协调类,streamId标记为”coordinator”,作用:时间协调(切分batch)、检查任务完成度、超时处理。原理跟Storm自带的Transactional Topolgoy类似。
  5. 实现一个Scheduler通过API获取参数,动态调整Spout、Bolt在各服务器的分布,以便灵活分配服务器资源。
  6. 支持平滑升级Topology:当一个Topology升级的时候,新Topology和旧Topology讲同时运行,协调切换时间,当新的Topology接管了fqueue之后,过河拆桥,杀死旧的Topology。

注意点:

  • Storm机器尽量部署在同一个机柜内,不影响集群内的带宽;
  • 我们的Nginx日志是按小时切分的,如果切分的时间不准确,在00分的时候,就可以看到明显的数据波动,所以,尽量使用Nginx module去切日志,用crontab发信号切会有延迟。切日志这种10秒级的延迟,在大尺度的统计上没有问题,秒级的统计时波动却很明显;
  • 堆太小会导致woker被强制杀死,所以要配置好-Xmx参数;

自定义项

  • 静态资源:静态资源过滤选项,通过Content-Type或后缀筛选特定的静态资源。
  • 资源合并:URL合并,比如RESTful的资源,合并后方便展示;
  • 维度与指标:通过ANTLR v3做语法、词法分析,完成自定义维度和指标,并且后续的报警也支持自定义表达式。

其他

我们还用其他方式实现了:

  • 业务的进程级(CPU/MEM/端口)监控
  • 业务依赖的服务,如MySQL/memcached等的监控
  • 服务器的磁盘/内存/IO/内核参数/语言环境/环境变量/编译环境等监控

相关 [storm nginx log] 推荐:

基于Storm的Nginx log实时监控系统

- - UC技术博客
UAE(UC App Engine)是一个UC内部的PaaS平台,总体架构有点类似CloudFoundry,包括:. 快速部署:支持Node.js、Play!、PHP等框架. 信息透明:运维过程、系统状态、业务状况. 灰度试错:IP灰度、地域灰度. 基础服务:key-value存储、MySQL高可用、图片平台等.

基于Lua+Kafka+Heka的Nginx Log实时监控系统

- - 开源软件 - ITeye博客
在我们的系统架构中,Nginx作为所有HTTP请求的入口,是非常重要的一层. 每天产生大量的Nginx Access Log,闲置在硬盘上实在是太浪费资源了. 所以,能不能把Nginx日志利用起来,实时监控每个业务的访问趋势、用户行为、请求质量和后端异常呢,这就是本文要探讨的主题. 错误码告警(499、500、502和504);.

使用 LAL 收集并分析 Nginx access log

- - 掘金 后端
本篇文章演示如何将 Nginx access log 收集到 SkyWalking 中,并通过 LAL 进行指标分析. 本文由社区贡献者  魏翔 撰写, SkyWalking 社区帐号发表. Nginx access log 中包含了丰富的信息,例如:日志时间、状态码、响应时间、body 大小等.

Log调试

- - ITeye博客
在开发中我们一定不能避免使用Log类,但是这个类存在一个问题就是,当你在程序中使用了大量的Log,那么在程序开发完毕的时候,这将是一个问题,因为,你需要将所有的Log记录注释掉(当然,你不注释也是可以的). 我们可以写一个类,将Log类包装起来,使用一个boolean来控制所有的Log记录的显示. public static final boolean isDebug = true;//这里控制所有Log的显示情况.

log file sync总结

- - 数据库 - ITeye博客
log file sync等待时间发生在redo log从log buffer写入到log file期间. 下面对log file sync做个详细的解释. 1.commit或者rollback. 3.log buffer 1/3满或者已经有1M的redo数据.       更精确的解释:_LOG_IO_SIZE 大小默认是LOG_BUFFER的1/3,当log buffer中redo数据达到_LOG_IO_SIZE 大小时,发生日志写入.

storm简介

- - 搜索技术博客-淘宝
伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样、更加便捷,同时对于信息的时效性要求也越来越高. 举个搜索场景中的例子,当一个卖家发布了一条宝贝信息时,他希望的当然是这个宝贝马上就可以被卖家搜索出来、点击、购买啦,相反,如果这个宝贝要等到第二天或者更久才可以被搜出来,估计这个大哥就要骂娘了.

Storm Trident 学习

- - 小火箭
Storm支持的三种语义:. 至少一次语义的Topology写法. 参考资料: Storm消息的可靠性保障 Storm提供了Acker的机制来保证数据至少被处理一次,是由编程人员决定是否使用这一特性,要使用这一特性需要:. 在Spout emit时添加一个MsgID,那么ack和fail方法将会被调用当Tuple被正确地处理了或发生了错误.

Storm实战之WordCount

- - 编程语言 - ITeye博客
 在全面介绍Storm之前,我们先通过一个简单的Demo让大家整体感受一下什么是Storm. 本地模式(Local Mode): 即Topology(相当于一个任务,后续会详细讲解)  运行在本地机器的单一JVM上,这个模式主要用来开发、调试. 远程模式(Remote Mode):在这个模式,我们把我们的Topology提交到集群,在这个模式中,Storm的所有组件都是线程安全的,因为它们都会运行在不同的Jvm或物理机器上,这个模式就是正式的生产模式.

Oracle online redo log 扫盲

- - CSDN博客数据库推荐文章
Oracle 的日志分为:ONLINE REDO LOG 和 archived log. 一个数据库至少要有2组 redo log,每组 redo log 至少要有一个 member(出于安全考虑,建议每组 redo log 至少有 2 个多元化的 redo log member). redo log 循环使用,当一组日志写满后,就会切换到下一组日志.

必须了解的MySQL三大日志:binlog、redo log和undo log

- - DockOne.io
日志是 MySQL数据库的重要组成部分,记录着数据库运行期间各种状态信息. MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类. 作为开发,我们重点需要关注的是二进制日志( binlog)和事务日志(包括 redo log和 undo log),本文接下来会详细介绍这三种日志.