为什么要构建监控系统
在后移动互联网时代,良好的用户体验是增长的基础,而稳定的使用体验则是用户体验的基础。大型的互联网公司,尤其是面向 C 端客户的公司,对业务系统稳定性的要求越来越高,因此对线上问题发现和处理的速度要求通常是分钟级的。比如滴滴等出行公司,打车服务停摆 10 分钟都会导致导致乘客、司机大规模投诉,不仅造成经济损失,而且严重平台商誉和用户口碑。
大型互联网公司的业务系统都是大规模的分布式系统,各种业务应用和基础组件(数据库、缓存、消息队列等)共同交织成复杂的依赖网络,任何节点都可能出现故障,导致系统不可用。因此,业务系统的监控非常重要,通过监控及时发现和干预问题,避免事故或降低事故影响范围。
本文将从监控系统整体架构设计、监控系统技术方案落地这两部分阐述了百亿级大数据实时监控系统的建设过程,目的是帮助技术人员了解监控系统设计思路,为监控系统的建设提供专业指引,协助读者快速构建监控系统。
监控系统整体设计
监控系统需求
世界上并不存在完全可靠的系统,程序、机器、网络等都可能在运行中出现故障,进而导致服务异常。因此监控的目标就是高效及时地发现、定位系统异常问题,期望缩短异常的平均修复时间,从而降低异常造成的损失。
为了实现高效发现系统异常,缩短异常的平均修复时间这两个目标,监控系统应该具有这些能力:
- 数据采集能力:全面、准确、快速、低损耗地获取监控日志及数据
- 数据汇聚能力:将相关数据汇聚起来,方便加工,得到我们需要关注的数据
- 数据分析与处理能力:对需要关注的数据提供异常指标检测、故障诊断等分析方法,以及数据过滤、采样、转换等处理手段
- 数据存储能力:为海量日志与监控指标提供高性能存储
- 监控告警能力:指定监控规则,触发规则后提供电话、邮件、微信、短信等各类告警机制
- 数据展示能力:提供监控数据与告警的 Dashboard 展示功能,加速问题定位
- 高可用:整个监控系统需要做到高可用,监控就是为了发现异常,如果由于异常导致自身不可用,肯定是减分的
监控系统架构
根据对监控系统需求的调研,可以将监控系统整体的数据流转过程抽象为以下几个阶段:采集 -> 汇聚 -> 处理 -> 存储 -> 分析 -> 展示 -> 告警。
从中我们可以总结出监控系统的一般架构:
从下往上来分析,首先是数据采集层,提供众多采集手段,包括 Agent 采集、RPC 埋点、HTTP 上报等,可以通过 Agent 采集宿主机监控数据和日志,或者 RPC 埋点上报,也可以由用户直接通过 HTTP 推送进行数据采集。
成功采集到的数据,需要经过统一的数据汇聚层,将相关联的数据进行汇聚。例如同一业务系统的所有服务器数据将会汇聚到一个相同的消息队列中,便于异常检测。
数据完成汇聚后,将分为三条数据流处理:数据处理、数据分析、数据存储。
- 数据处理层:对原始监控数据进行加工,通过数据清洗与转换将数据格式化,并进行基础的聚合计算,例如累加计算 10 台服务器的 ERROR 日志次数;
- 数据分析层:对标准化后的数据进行关联分析、异常检测、故障诊断等,为后续的告警提供判断依据;
- 数据存储层:对日志、指标、时序数据进行存储,便于 Dashbord 展示,可用于进一步的数据挖掘。
数据流处理完成后,进入监控告警层,对符合监控、告警规则的事件进行告警推送。
数据流最终到达数据展示层,提供常见的用户交互页面:如监控面板、告警面板等。
监控系统方案落地
技术选型
方案 1: 流计算 Oceanus Elastic Stack
提到监控系统方案,许多用户都会想到 Elastic Stack(Elasticsearch、Logstash、Kibana、Beats),其活跃的社区、简单的安装流程、便捷的使用方式等优势吸引了大量用户,当前很多互联网公司的监控系统架构都是基于开源 Elastic stack 搭建的。
Elastic Stack 由 Elasticsearch、Logstash、Kibana 和 Beats 组成。下面分别对各个组件进行简单的介绍。
Elasticsearch 是一款实时全文搜索和分析引擎。作为 Elastic stack 的核心,Elasticsearch 可用于搜索各种类型的数据:从文本、数字和地理空间数据到其他类型的结构化和非结构化数据,主要支持搜索、分析、存储数据三大功能。Elasticsearch 基于 Apache Lucene 搜索引擎库构建,它易于使用且可扩展。
Logstash 是一款日志聚合器,它可以从各种输入源动态采集监控日志和数据,对其进行转换后,将数据传送到各种支持的输出目的地。许多用户将转换后的数据发送到 Elasticsearch,在其中对日志、监控数据进行索引与搜索。
Kibana 是工作在 Elasticsearch 之上的可视化层,为用户提供数据分析和可视化的能力,可将存储在 Elasticsearch 中的数据转换为易于使用的图表、图形、直方图和其他可视化表示,进而深入挖掘数据特征。
Beats 是一款轻量级日志采集器,目前 Beats 包含多种工具:Metricbeat、Filebeat、Heartbeat 等。每个 Beat 都有一个简单的任务:采集日志或数据并发送到输出目的地。
早期的 ELK Stack 使用 Logstash 收集并解析日志,但是 Logstash 本身是基于 jdk 的,而且它集成了许多插件,对内存、CPU、IO 等资源消耗比较高。相比于 Logstash,Beats 所占系统的 CPU 和内存几乎可以忽略不计,因此考虑使用轻量级的 Beats 组件来完成日志和监控数据的采集操作。架构如下:
Elastic Stack 运行于分布式系统之上,为用户提供了一个性能强大的平台,该平台通过采集、过滤、传输、储存,对海量日志和监控数据进行集中管理和准实时搜索、分析,提供准实时搜索、监控、事件消息和分析报表等简单易用的功能,帮助运维人员进行线上业务的实时监控,业务异常时及时定位原因、排除故障,深度挖掘日志的大数据价值。
但是 Elastic Stack 也存在一些不足。首先 Beats 只有采集日志与监控数据的功能,无法对数据进行处理;另外 Logstash 的数据处理功能很弱,无法满足复杂的数据处理需求,且不支持监控数据缓存,存在数据丢失的隐患。
综上所述,在将监控数据与日志信息保存到 Elasticsearch 之前,需要引入消息队列缓存数据,并使用大数据实时计算引擎对数据进行实时的过滤、转换、聚合。
而腾讯云流计算 Oceanus 恰好可以实现这些功能。流计算 Oceanus 是大数据产品生态体系的实时化分析利器,是基于 Apache Flink 构建的具备一站开发、无缝连接、亚秒延时、低廉成本、安全稳定等特点的企业级实时大数据分析平台。流计算 Oceanus 能很好地满足监控场景下海量实时数据处理的需求,监控系统可以利用 Oceanus 的实时计算能力,对监控日志与数据进行清洗、转换并完成聚合分析,实时计算的结果可以直接用于监控告警展示,极大地提升了运维人员在故障发生时的决策能力。
使用 Elastic Stack 还需要关注的点是监控面板。Kibana 的长处在于日志分析,且仅适用于Elasticsearch,不支持任何其他类型的数据源;它的面板展示能力还有提高的空间,而且具有陡峭的学习曲线,对于非技术业务用户来说很难上手。因此可以考虑使用其他的数据可视化工具代替 Kibana 作为监控面板,让 Kibana 专注于日志分析。综合对比现有的可视化工具后,我们选择使用 Grafana。
在实际应用场景中,可以使用 Beats 采集日志与监控数据,将 Kafka 作为 Beats 的输出端。Kafka 实时接收到 Beats 采集的数据后,使用流计算 Oceanus(Flink)进行实时处理与聚合,将满足需求的数据输出到 Elasticsearch 中进行分布式检索,通过 Kibana 进行日志分析,最后采用 Grafana 作为监控面板。流程如下图所示:
方案 2: Zabbix Prometheus Grafana
Zabbix 是一款开源的分布式系统监控软件。它支持可视化配置,提供多种指标采集,支持自定义告警阈值与多样的通知机制。Zabbix 灵活的设计为用户提供了易用的二次开发接口,让用户既可以使用 Zabbix 本身提供的功能,又可以自定义更多的监控项功能,如硬件监控、操作系统指标监控、服务进程监控等。
Prometheus 是一款基于 Go 语言开发的监控、告警、存储套件,它通过 HTTP 协议从远程的机器收集数据并存储在本地的时序数据库上。Prometheus 架构简单,单个服务器节点可直接工作,属于轻量级的 Server。同时不依赖外部存储,便于迁移和维护,其监控数据直接存储在 Prometheus Server 本地的时序数据库中,单个实例可以处理数百万的 Metrics。Prometheus 具有灵活的数据模型和强大的数据查询语句,可以帮助快速定位和诊断问题,非常适用于面向服务架构的监控。
Grafana 是一个开箱即用的可视化工具,具有功能齐全的度量仪表盘和图形编辑器,有灵活丰富的图形化选项,支持配置多种数据源,例如 Elasticsearch、InfluxDB、Prometheus 等。Grafana 可以通过 Datasource 链接 Prometheus url,并对接入的数据进行分组、过滤、聚合等逻辑运算,从而在监控面板中直观展示监控指标。
Zabbix、Prometheus 和 Grafana 构建的监控系统部署简单,功能完善,非常适合容器化环境,但是也存在一定的局限,主要缺点是在超大规模数据量下存在性能瓶颈。
- Zabbix 入门容易,能实现基础的监控,但是深层次需求需要非常熟悉 Zabbix 并进行大量的二次定制开发;
- Zabbix 使用 pull 方式采集数据,存在性能瓶颈;
- Prometheus 是基于 监控指标(Metric) 的监控,不适用于日志(Logs)、事件(Event)、调用链(Tracing)等监控;
- Prometheus 目前只能提供非持久化的数据存储,无法长期保存数据;
- Prometheus 只适合单机部署,对于集群化和水平扩展,官方和社区都没有银弹,无法支持海量数据存储与监控。
选型总结
Elastic Stack 与流计算 Oceanus 组合,构建了分布式、可拓展、实时化的监控系统,对海量日志和监控数据进行集中管理和实时搜索、分析,提供指标监控、事件消息和分析报表等简单易用的功能。性能完善,扩展性强,缺点是部署比较麻烦,资源消耗较高。
Zabbix、Prometheus 和 Grafana 构建的监控系统部署简单,功能完善,非常适合容器化环境,但是存在致命缺陷,超大规模监控数据量下无法突破性能瓶颈。
综上所述,我们最终考虑采用流计算 Oceanus 和 Elastic Stack 构建监控系统。实际操作指引可以参考 基于流计算 Oceanus 和 Elasticsearch Service 实现实时监控系统。
系统优化
随着业务量的上涨,监控指标逐渐增多,需要监控的设备不断增长,对监控系统的性能要求也日益提升。当数据量增长到百亿甚至千亿级别,监控系统可能会出现以下问题:
- 处理性能下降 系统整体处理性能变弱,处理抖动、毛刺情况增多。上游消息队列出现大量数据堆积情况,监控延时上升。
- 数据倾斜 由于业务系统各组件监控数据与日志分布不均匀,导致数据倾斜,Flink 任务反压严重,各算子的 Checkpoint 时间变长甚至频繁失败。部分节点出现 CPU 过载、OOM 的情况。
- 存储写入性能下降 Elasticsearch 写入时延上涨,存在大面积写入被拒绝的现象,最终导致上游 Flink 任务反压,甚至任务崩溃。
当系统不稳定或者处理性能下降时,数据延时会上涨至小时甚至天级别,这对于需要尽量做到实时化的监控系统来说是无法接受的。
而面对超大规模监控数据量的场景,腾讯云流计算 Oceanus 和 Elasticsearch service 进行了大量优化。下面进行详细介绍。
流计算 Oceanus
流计算 Oceanus 能很好地满足监控场景下海量实时数据处理的需求。监控系统可以利用 Oceanus 的实时计算能力,使用简单的 SQL 对监控日志与数据进行实时清洗、转换与聚合分析。
SQL 性能优化
流计算 Oceanus 对原生 Flink SQL 进行了大量优化,提升超大规模数据量下作业的处理性能。
数据倾斜是导致 Flink 作业性能问题的常见原因。数据倾斜指的是数据分布严重不均衡,过多数据集中在某些 task 上,导致内存紧张,频繁 GC;而频繁的 GC 导致系统吞吐下降,数据延迟,严重情况下还可能导致 TaskManager 失联,任务崩溃。
针对数据倾斜问题,流计算 Oceanus 自动为作业开启 Local-Global Aggregate 与 Mini-Batch 功能。Local-Global Aggregate 能够靠 Local Aggregate 的预聚合筛除部分倾斜数据,从而降低 Global Aggregate 的热点,避免数据倾斜,提升处理性能。同时,在 Aggregate 的处理过程中可以开启 Mini Batch 方式,Local 阶段采取微批提交避免数据量缓存过多,Global 阶段则可以减少状态的访问次数,降低 I/O 压力。
Flink SQL 下还存在 UDF 函数复用的问题。如果相同的 UDF 在 SQL 中出现多次,例如简单的 JSON 解析、URL 解析等,原生的 Flink SQL 会多次执行,影响性能。
针对 UDF 函数复用问题,流计算 Oceanus 将逻辑执行计划中重复调用的 UDF 提取出来,并对 UDF 的执行结果进行缓存,避免多次调用。
流表维表 Join 中存在数据冷启动问题,如果将维表数据加载到所有的 subtask 里面会造成较大的内存消耗,而且很容易造成反压。
流计算 Oceanus 的解决方案是,在维表的 DDL 中指定 Bucket 信息,流与维表进行 Join 的时候会基于 Bucket 信息去加载维表中对应分片的数据,同时在翻译执行计划的时候流表拿到 Bucket 信息,以保证流与维表的数据都会基于同一个 Bucket 信息进行 Join。这种处理方案能大大减少全量维表数据预加载带来的内存消耗与反压问题。
作业智能诊断与监控
流计算 Oceanus 为作业异常重启、Snapshot 失败、以及 JobManager/TaskManager 的 CPU、内存异常等各类运行状态的事件提供可视化的提示。
并且以异常日志的采集和聚合分析为切入,智能地诊断分析异常信息,并给出建议的解决方案。
此外,流计算 Oceanus 还以 Task 粒度定义动态指标,并以维度聚合(sum、max、min、avg)的方式定义从上下游系统到集群作业的健康运行相关的 65 项监控指标,对作业进行全方位监控告警。
流计算 Oceanus 提供的上述功能可以为用户的实时计算作业保驾护航,大大提升发现作业问题与解决问题的效率。
作业自动扩缩容
流计算 Oceanus 提供作业自动扩缩容功能,根据 CPU、内存、反压状况等业务负载情况,自动进行作业并行度的调整,完成作业扩缩容。
当遇到数据倾斜、作业负载过高等事件时,流计算 Oceanus 会自动调整作业并行度,增加作业运行资源,从而避免数据倾斜,降低作业负载,保障作业稳定运行。而在业务低谷期流计算 Oceanus 会自动缩减作业计算资源,减少资源浪费。
作业自动扩缩容功能在保障业务时效性的同时,避免了资源浪费,可以为用户降低可观的成本。
腾讯云 Elasticsearch Service
伴随数据量的极速上涨,开源 Elasticsearch 暴露出来的问题为:
- 写入耗时过大,大量写入被拒绝
- 部分索引查询性能慢
- 存储成本急剧增加
- 堆内存使用过大
Elasticsearch 的使用姿势、参数调优等在社区有很多的案例和经验可以借鉴,但是百亿级实时监控场景下,很多的痛点和挑战是无法通过简单的调优来解决的。
腾讯云 Elasticsearch Service(ES)是基于开源搜索引擎 Elasticsearch 打造的高可用、可伸缩的云端全托管的 Elasticsearch 服务,包含 Beats、Kibana 及常用插件,并集成了安全、SQL、机器学习、告警、监控等高级特性(X-Pack)。为了应对上述的困难,腾讯云 ES 从内核层面做了深度的优化。
存储模型优化
Elasticsearch 底层的 Lucene 是基于 LSM Tree 的数据文件,原生默认的合并策略是按文件大小相似性合并,默认一次固定合并 10 个文件,近似与分层合并。这种合并方式的最大优点是合并高效,可以快速降低文件数;主要问题是数据不连续,会导致查询时文件剪枝的能力变弱,比如查询最近一小时的数据,很有可能一小时的文件被分别合并到了几天前的文件中去了,导致需要遍历的文件增加了。
为了提升数据连续性、收敛文件数量,提升文件的裁剪能力来提高查询性能,腾讯云 ES 实现的文件合并策略主要是按时间序分层合并,每层文件之间按创建时间排序,除了第一层外,都按照时间序和目标大小进行合并,不固定每次合并文件数量,这种策略可以保证合并的高效性。对于少量的未合并的文件以及冷分片文件,采用持续合并的策略,将超过默认五分钟不再写入的分片进行持续合并,并控制合并并发和范围,以降低合并开销。
通过对合并策略的优化,腾讯云 ES 将搜索场景的查询性能提升了 40%,同时带主键的数据写入性能提升了一倍。
成本优化
腾讯云 ES 对业务数据访问频率进行调研,发现最近的数据访问频率较高,例如最近 5 分钟的,一小时的,一天的,近几天的访问频率就比较少了,超过一个月的就更少了。
基于这种数据特征,腾讯云 ES 通过冷热分离,把冷数据放到 HDD 来降低成本,同时利用索引生命周期管理来搬迁冷数据,冷数据盘一般比较大,因此还要利用多盘策略来提高吞吐和数据容灾能力。最后将超冷的数据冷备到腾讯云的对象存储 COS 上,冷备成本非常低。
通过冷热数据分离,监控数据总体存储成本下降了将近 10 倍。
内存优化
通过对线上 Elasticsearch 集群进行分析,发现很多场景下,堆内内存使用率很高,而磁盘的使用率比较低。其中 Elasticsearch 的 FST 即倒排索引占据了绝大部分堆内内存,而且这部分是常驻内存的。每 10 TB 的磁盘 FST 的内存消耗大概在 10 GB 到 15 GB 左右。
为了对 FST 这种堆内占用比较大的内存做优化,腾讯云 ES 将其移至堆外(off-heap),按需加载,实现更精准的淘汰策略,提高内存使用率,再加上多级 cache 的管理模式来提升性能。通过内存优化,可以提升堆内内存利用率,降低 GC 开销,提升单个节点管理磁盘的能力。
总结
本文从监控系统整体架构设计、监控系统技术方案落地这两部分阐述了百亿级大数据实时监控系统的建设过程。
首先阐述了监控系统的需求,并根据需求总结出监控系统架构。随后进行技术选型,分别分析了基于流计算 Oceanus、Elastic Stack 和基于 Zabbix、Prometheus、Grafana 的监控系统技术方案,并选择基于流计算 Oceanus 和 Elastic stack 构建监控系统。最后针对超大规模监控数据量的场景,介绍腾讯云流计算 Oceanus 与 Elasticsearch Service 对性能与成本的各种优化策略与手段。总体而言,选择流计算 Oceanus 与 Elasticsearch Service 能很好地支撑海量数据实时监控的需求,并极大地降低用户成本。
希望本文可以帮助读者了解监控系统设计思路,快速构建高性能的监控系统。