V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
rollingwaye
V2EX  ›  问与答

she

  •  
  •   rollingwaye · 2016-03-09 11:46:07 +08:00 · 847 次点击
    这是一个创建于 3141 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本文是野狗资深工程师廖斌旭在“ iGeek Camp ”北京站第 4 期上进行的《基于 Flume 的野狗实时日志系统的演进和优化》的演讲实录,主要分为两个部分:野狗日志系统的架构演进和优化方案。
    野狗官博: https://blog.wilddog.com/
    野狗官网: https://www.wilddog.com/
    公众订阅号: wilddogbaas

    1.pic.jpg
    在讲解日志架构之前,先介绍一下我们野狗的业务。我们的业务共有两类 SDK ,基于两种连接技术。第一类是 WebSocket 长连接或用 Long polling 模拟的长连接,另外一类是 HTTP REST 短连接。
    3.pic.jpg
    大家看这张图,野狗的业务架构分为两层,第一层是接入层,包括 NodeJs 接入层、 Nginx Rest API 接入层;第二层是核心业务处理层,包括数据处理和 Push server 同步推送。 SDK 通过长连接或短连接与接入层相连接。所有的请求都通过 SDK 发送到接入层,接入层转化协议,然后转发到业务处理层。所以接入层是用户访问的入口,天生适合做流控和统计。
    4.pic.jpg
    野狗的日志业务主要分为两类:日常日志和计费服务。日常统计包括 UV 、 PV 以及客户的 API 操作记录。后面又因为业务需求,增加了计费服务,主要包括流量统计和连接数统计。
    5.pic.jpg
    我们的第一版,很简单。使用 crontab 命令来定时执行 rsync 命令,同步日志文件。
    6.pic.jpg
    从这张图可以看到,接入层通过打本地日志的方式,把请求信息记录下来。然后使用 crontab 定时执行 rsync 同步日志到“日志归档服务器”。处理统计业务的服务“ cloud-stat ”,定时从“日志归档服务器”获取日志文件,然后把计算的流量统计结果保存到数据库中。但是设计架构的目标并不仅仅是完成需求,同时还要知道它的优势和劣势,才能了解架构下一步的改进方向。接下来,我们来看看 v0.1 版本的优缺点。
    7.pic.jpg
    最突出的优点是简单,使用两条命令就能搞定。使用 rsync 命令比 SCP 更灵活,因为前者支持增量拷贝。还有一个优点就是支持数据压缩。

    但是因为有了流量数据,所以想做实时流控,还是挺难的。因为定时同步最快能够做到分钟级别,实时性不够。文件在多台服务器之间流转,也增加管理的文件的成本。文件的多副本,同时也会造成存储的浪费。

    所以基于实时性的考虑, 我们又改进了日志系统的架构。这就是我们的 v0.2 版。
    8.pic.jpg
    介绍 v0.2 架构之前,先描述下项目背景。因为项目时间非常紧张,所以我们引进了 redis 做流量数据的缓存。但是这个方案并不是行业的最优的做法,不过当时已经搭建 redis 集群,正好能够解决实时性的需求。
    9.pic.jpg
    我们来看下下面这张图。 Redis 作为生产者消费者模式的缓冲队列,接收“接入层”的流程数据,并交给统计业务消费。 NodeJs 接入层和 Nginx Rest API 接入层,把流量数据通过 redis 的客户端写入 Redis 集群。统计业务 cloud-stat 则定时从 redis 集群消费。时间从 v0.1 的最快分钟级别,降到现在 5 秒内完成日志产生、收集、处理整个过程。这对于我们系统的实时性是一个很大的提升。
    10.pic.jpg
    经过改进之后,日志系统的延迟降低了,这也是我们 v0.2 的主要目的。但是,任何系统都不是完美的。日志文件记录我们的最原始的用户访问记录,这些数据我们不能丢。加上 redis 这套架构,并存两套架构,就在无形中增加了我们的维护成本。 Redis 缓存在带来高性能的同时,也带来了一个副产品,就是在接入层必须硬编码 redis 的逻辑。
    11.pic.jpg
    经历两版的系统改造,我们有了一点心得:一是利用日志干更多的事情,二是日志统计不要侵入原系统。
    12.pic.jpg
    经过前两版的积累,在 v0.3 我们决定引入 flume 服务,来做日志收集。主要体现在两点:一是在日志源服务器部署 flume agent ,第二个就是增加了中心化的收集服务 flume collector 。
    13.pic.jpg
    现在的日志系统分为 3 层,一是部署在接入层机器上的 flume agent ,二是中心化收集服务器 flume Collector ,三是日志处理服务。

    接入层生成的日志,由 flume agent 进程,通过 avro rpc 发送到 flume Collector 。日志在 collector 汇总之后,主动发给第三层日志处理服务。主要包括统计服务 cloud-stat 、 分析服务 analyze 和日志归档服务 log archive 。
    14.pic.jpg
    前面我们讲了 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 。
    15.pic.jpg
    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 会讲到。
    16.pic.jpg
    SpoolingDirSource 用于监控文件目录变化的,但是实际的使用中会有以下两个问题:一是文件不能写,只能读。二是延迟比较高,需要等待日志定期归档。
    17.pic.jpg
    为了解决速率控制的问题, 我们用 Java 程序实现了“模拟 tail -F ”的功能,主要是使用 ExceSource ,定时修改 Flume 的配置文件。另外就是根据我们的需求自定义 Source 。
    18.pic.jpg
    Channel 的功能是做缓存队列, Flume 提供两种 Channel 。
    19.pic.jpg
    MemoryChannel 使用内存做缓冲队列,所有数据都保存在内存。但是这样做有两个问题:一是可用性差,另一个就是当队列数量小于阈值时,会一直等待被消费。
    20.pic.jpg
    FileChannel 使用磁盘做缓冲队列,所有数据都保存在磁盘。它的一个问题就是吞吐量比较低。
    21.pic.jpg
    因为我们野狗自身的需求,在要求实时的同时,还要保证一定的可用性。美团的解决方案是提供一种基于内存 Channel 和 FileChannel 的 Channel 。

    而我们野狗自己开发了一种基于 MemoryChannel 的增强 Channel ,主要增加了队列序列化功能,并且在重启的时候能够做到持久化。另外因为 Flume 低于阈值时才会触发 Channel 被消费事件,而我们在流量较低时也有收集日志的需求,所以在原生系统上又增加了空闲超时检测。
    22.pic.jpg
    谢谢大家。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5390 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 08:22 · PVG 16:22 · LAX 01:22 · JFK 04:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.