巅峰战队|PowerJob日志饱受好评的秘诀:小但实用的分布式日志系统

本文适合有 Java 基础知识的人群
巅峰战队|PowerJob日志饱受好评的秘诀:小但实用的分布式日志系统作者:HelloGitHub-Salieri
HelloGitHub 推出的《讲解开源项目》系列 。
项目地址:
PowerJob 的在线日志一直是饱受好评的一个功能 , 它能在前端界面实时展示开发者在任务处理过程中输出的日志 , 帮助开发者更好的监控任务的执行情况 。 其功能展示如下图所示(前端界面略丑 , 请自动忽略~) 。
巅峰战队|PowerJob日志饱受好评的秘诀:小但实用的分布式日志系统在线日志这个功能 , 乍一听很简单 , 无非 worker 向 server 发日志数据 , server 接受后前端展示 。 但对于 PowerJob 这种任意节点都支持分布式部署且支持分布式计算的系统来说 , 还是存在着不少难点的 , 简单来说 , 有以下几点:

  1. 多对多问题:在 PowerJob 的理想部署模式中 , 会存在多个 server 和多个 worker , 当某个任务开始分布式计算时 , 其日志散布于各台机器上 , 要想在前端统一展示 , 需要有收集器将分散的日志汇集到一起 。
  2. 并发问题:当 worker 集群规模较大时 , 一旦执行分布式计算任务 , 其产生的日志 QPS 也是一个不小的数目 , 要想轻松支持百万量级的分布式任务 , 需要解决并发情况下 QPS 过高的问题 。
  3. 排序问题:分布式计算时 , 日志散布在不同机器 , 即便收集汇总到同一台机器 , 由于网络延迟等原因 , 不能保证日志的有序性 , 而日志按时间排序是强需求(否则根本没法看啊...) , 因此 , 还需要解决大规模日志数据的排序问题 。
  4. 数据的存储问题:当日志数据量非常大时 , 如何高效的存储和读取这一批数据 , 也是需要解决的问题 。
因此 , 为了完美实现在线日志功能 , PowerJob 在内部实现了一个麻雀虽小五脏俱全的分布式日志系统 。 话不多说 , 下面正式开始逐一分析~
一、多对多问题这个问题 , 其实在 PowerJob 解决多 worker 多 server 的选主问题时顺带着解决了 。 简单来说 , PowerJob 系统中 , 某一个分组下的所有 worker , 在运行时都只会连接到某一台 server 。 因此 , 日志数据上报时 , 选择当前 worker 进行上报即可 。 由于任务不可能跨分组执行 , 因此某个任务在运行过程中产生的所有日志数据都会上报给该分组当前连接的 server , 这样就做到了日志的收集 , 即日志会汇总到负责当前分组调度的 powerjob-server , 由该 server 统一处理 。
二、并发问题并发问题的解决也不难 。
大家一定都听说过消息中间件 , 也知道消息中间件的一大功能为削峰 。 引入消息中间件后 , 把原来同步式的调用转化为异步的间接推送 , 中间通过一个队列在一端承接瞬时的流量洪峰 , 在另一端平滑地将消息推送出去 。 消息中间件就像水库一样 , 拦蓄上游的洪水 , 削减进入下游河道的洪峰流量 , 从而达到减免洪水灾害的目的 。
巅峰战队|PowerJob日志饱受好评的秘诀:小但实用的分布式日志系统PowerJob 在处理日志的高并发问题时也采用了类似的方式 , 通过引入本地队列 , 对需要发送给 server 的消息进行缓存 , 再定时将消息批量发送给 server , 化同步为异步 , 并引入批量发送的机制 , 充分利用每一次数据传输的机会发送尽可能多的数据 , 从而降低对 server 的冲击 。
三、排序问题3.1 日志的存储将排序问题之前 , 先来聊一聊 server 怎么处理接收到的日志数据 , 也就是如何存储日志 。


推荐阅读