分布式系统下的日志收集分析方案

前言

分布式系统下,大规模集群应用分布在数台甚至成百上千台不同的服务器上,而日志又是我们开发人员用于定位问题、监控系统健康度、用于报警的最基础的数据来源。要想快速方便的对日志进行查找、分析归纳、归档、报警等功能,使用传统的 Linux 命令去查看日志,肯定不现实。所以一般的分布式集群系统环境下,我们都会去构建一个集中的日志系统,可以将各个服务日志收集起来。从而达到我们需要的的效果。

业务规模复杂导致构建分布式日志系统的难点:

  • 导致的日志多节点、日志量也在爆炸式的增长;
  • 日志格式的不规范与不确定性;
  • 日志的形式的复杂化(物理机/虚拟机、K8S、Docker,Application 等等),容器的标准输出,容器内文件、容器事件、K8S事件等等;
  • 环境复杂、在K8S环境下的,机器宕机、上下线、POD销毁、扩容缩容引起的日志的更改,都需要瞬时的收集起来;
  • 日志的种类多(Nginx 、CDN、Ingress、ServiceMesh Pod等等日志,审计日志、应用日志、中间件日志、调用链日志、网络日志等等)
  • ……

日志的特点:

  • 大量的数据, 流式数据;
  • 上述的步骤,应该要解耦
  • 要具体扩展性,数据量增加的时候,支持水平扩展。

开源的日志系统

我们要构建一个企业级的日志系统的,一般选择的有免费的和收费的,收费的,云厂商的日志服务,我们今天不在考虑范围内。免费的开源的主要有:

日志的产生到使用,主要经过下面的阶段: 采集 -> 传输 -> 缓冲 -> 处理 -> 存储 -> 检索

ELK stack

ELK stack 是由 Elasticsearch、Logstash、Kibana 开源组件集合分析、搜索、展示的日志系统解决方案。

  • Elatsicsearch 是全文搜索分析引擎
  • Logstash 日志聚合器,收集和处理多种数据源的数据、转换并发送到其他目的地
  • Kibana 用户界面,用于可视化的查询分析数据
  • Beats 用于数据收集数据

GrayLog

GrayLog 也是一款开源的日志解决方案,本身 Graylog 提供了日志收集、日志存储搭配 MongoDB,查询层面依赖 Elasticsearch, Github 地址 github

  • Graylog 提供对外接口,Web页面
  • Elasticsearcg 日志文件的持久化存储和检索
  • MongoDB 存储 Graylog 的配置

Graylog 一体化方案、方便、但是没有分层。因为不是 agent 方式,其支持的日志收集方式有 RestApi、UDP、TCP。 整体来说,通过构建 Input 来收集日志,每个 Input 可以单独配置 Extractors 来做字段转换。 当然还有其他的概念,诸如

  • Inputs 日志抓取接收、由 Sidecar 主动抓取、或者其他服务主动上报的
  • Extractors 日志数据格式解析转换, json解析、kv解析、时间戳解析、正则解析
  • Streams 日志分类分组,将日志分类条件并发生到不同的索引文件中
  • Indices 持久化存储,数据存储性能
  • Outputs 日志数据转发,解析的 Stream 发送到其他的 Graylog 集群或服务
  • Pipelines 日志数据过滤,建立数据清洗过滤规则、字段的添加删除、条件过滤、自定义函数等
  • Sidecar 轻量级的日志采集器,适合大规模的适合使用
  • Lookup Tables 服务解析,基于 IP 的 whois 查询 和 基于 来源IP 的监控
  • Geolocation 可视化地理位置,基于 来源IP 的监控

Loki

Loki 是一个日志聚合系统,旨在纯纯和查询来自所有的应用程序和基础架构的日志。它与 prometheus 一样是可扩展、高可用、多租户的日志聚合系统,它不索引日志内容,只是为每个日志设置标签。

  • 很简便
  • 对象存储
  • 结合 alert manager 生成报警
  • 与 Prometheus、Grafana、K8S 原生集成
  • 实时查看日志

一个简单的使用 Loki 的组件,日志系统包含了几个

  • promtail 客户端,抓取日志,通过网关推送给 Loki
  • Minio 用于存储数据
  • Grafana 提供 Loki 捕获的日志行的可视化

Loki

Loki 最佳实践

  • 静态标签支持的更好,标签应该具有有限的值。并且在查询日志的适合更有效与快速
  • 谨慎使用动态标签,太多的标签会导致太多的流,这种会降低性能。在确实需要的时候,应该使用 过滤器 去查询
  • 动态标签的化,请使用有界的值
  • 使用 chunk_target_size 和 max_chunk_age 来合理控制区块大小 与 时间内区块数量
  • 日志的时间顺序,当然 Loki 接受乱序的写入,但是针对一个日志,最好是顺序,否则后续的会使用新日志,如果是多个实例的,最好加上实例的host。 Promtail pipeline stage 可以从日志行提取时间,或者让 Promtail 为日志行分配时间戳

Loki 的几个核心配置

  • 基本的配置
  • HTTP 和 GRPC
  • 服务发现 支持 consul、etcd
  • 存储支持Local、GCS、AZURE、Swift、BOS(百度对象存储)

Loki支持客户端有哪些

  • Promtail : Promtail是K8S首选,同一个节点的运行POD抓取日志。节点机器也可以使用 Promtail。
  • Docker Driver :
  • Fluentd 和 Fluent Bit : 当使用 Flentd 的时候,可以使用这个插件,选择 filter
  • Logstash : 如果是 Logstash 或 beats,直接添加输出插件。
  • Lambda Promtail : Loki 监控 AWS lambda 日志
  • 非官方的 Go、Java、C#、Js、Python3

Loki 有一个可配置的存储模式 : 一个 from 标志着起点,在这个期间,该 schema都是活动状态,直到另一个条目具有了 新的 from 日期

WAL(Write Ahead Log)

Ingester 是将数据存在内存中,而 WAL机制可以弥补在发生奔溃的情况下导致的数据丢失的情况, WAL 是将数据存储在本地文件系统中, 重启的时候 Loki 将对数据进行 “重放”, 然后重放完毕后将自己注册为准备好了的,预备接收后续写入。一旦确认写入就不会丢失数据。

Loki 设计亮点

在 K8S 环境下的日志收集

不管以选择哪种日志方案、或者商业化的日志收集方案, 先看要收集哪些日志

  • 系统 和 K8S 组件日志 /var/log/..
  • 业务应用程序日志 自定义日志路径

涉及到 K8S 的日志采集、主要有以下几种方式

  • Node 级日志代理 : 在每个宿主机上一个日志收集agent, 减少资源消耗、对应用无侵入。但是对于一些定制化的支持的不够

Node级日志代理

  • Sidecar Container 作为日志代理 : 伴生容器,和应用容器在一个POD下, 专门收集应用日志,通过共享卷获取日志上传,也带来了额外的资源消耗,增加运营成本。但是低耦合。

Sidecar日志代理

  • App 级直接上传日志 : 无需额外收集器、但同时也侵入应用了,增加应用复杂度。
comments powered by Disqus