日志系统调研

日志系统

日志系统介绍

基于公司业务逐渐迁移到Kubernetes环境的现实需求。对日志系统的选型应按照对Kubernetes环境的要求进行。

应用程序和系统日志可以帮助我们了解集群内部的运行情况,日志对于我们调试问题和监视集群情况也是非常有用的。而且大部分的应用都会有日志记录,对于传统的应用大部分都会写入到本地的日志文件之中。对于容器化应用程序来说则更简单,只需要将日志信息写入到 stdout 和 stderr 即可,容器默认情况下就会把这些日志输出到宿主机上的一个 JSON 文件之中,同样也可以通过 docker logs 或者 kubectl logs 来查看到对应的日志信息。

但是,通常来说容器引擎或运行时提供的功能不足以记录完整的日志信息,比如,如果容器崩溃了、Pod 被驱逐了或者节点挂掉了,我们仍然也希望访问应用程序的日志。所以,日志系统应该独立于节点、Pod 或容器的生命周期,这种设计方式被称为 cluster-level-logging,即完全独立于 Kubernetes 系统,需要自己提供单独的日志后端存储、分析和查询工具。

一套完成的日志系统应该包含:数据采集,存储、搜索&分析,可视化&管理三部分。

日志系统选型

对于存储、搜索&分析这部分选择的组件是Elasticsearch。Elasticsearch 是一个实时的、分布式的可扩展的搜索引擎,允许进行全文、结构化搜索,它通常用于索引和搜索大量日志数据,也可用于搜索许多不同类型的文档。使用到的最著名场景就是GitHub。

对于日志系统最主要的调研对象在数据收集和可视化组件两部分。

日志采集

可选组件为logstash、filebeat、fluentd。

优缺点对比

Logstash <-- java

Logstash是一个开源数据收集引擎,具有实时管道功能。Logstash可以动态地将来自不同数据源的数据统一起来,并将数据标准化到你所选择的目的地。

优势

Logstash 主要的有点就是它的灵活性,主要因为它有很多插件,详细的文档以及直白的配置格式让它可以在多种场景下应用。我们基本上可以在网上找到很多资源,几乎可以处理任何问题。

劣势

Logstash 致命的问题是它的性能以及资源消耗(默认的堆大小是 1GB)。尽管它的性能在近几年已经有很大提升,与它的替代者们相比还是要慢很多的。这里有 Logstash 与 rsyslog 性能对比以及Logstash 与 filebeat 的性能对比。它在大数据量的情况下会是个问题。

另一个问题是它目前不支持缓存,目前的典型替代方案是将 Redis 或 Kafka 作为中心缓冲池:

典型应用场景

因为 Logstash 自身的灵活性以及网络上丰富的资料,Logstash 适用于原型验证阶段使用,或者解析非常的复杂的时候。在不考虑服务器资源的情况下,如果服务器的性能足够好,也可以为每台服务器安装 Logstash 。也不需要使用缓冲,因为文件自身就有缓冲的行为,而 Logstash 也会记住上次处理的位置。

如果服务器性能较差,并不推荐为每个服务器安装 Logstash ,这样就需要一个轻量的日志传输工具,将数据从服务器端经由一个或多个 Logstash 中心服务器传输到 Elasticsearch:

随着日志项目的推进,可能会因为性能或代价的问题,需要调整日志传输的方式(log shipper)。当判断 Logstash 的性能是否足够好时,重要的是对吞吐量的需求有着准确的估计,这也决定了需要为 Logstash 投入多少硬件资源。

Filebeat <-- Go

作为 Beats 家族的一员,Filebeat 是一个轻量级的日志传输工具,它的存在正弥补了 Logstash 的缺点:Filebeat 作为一个轻量级的日志传输工具可以将日志推送到中心 Logstash。

在版本 5.x 中,Elasticsearch 具有解析的能力(像 Logstash 过滤器)— Ingest。这也就意味着可以将数据直接用 Filebeat 推送到 Elasticsearch,并让 Elasticsearch 既做解析的事情,又做存储的事情。也不需要使用缓冲,因为 Filebeat 也会和 Logstash 一样记住上次读取的偏移,如果需要缓冲(例如,不希望将日志服务器的文件系统填满),可以使用 Redis/Kafka,因为 Filebeat 可以与它们进行通信。

优势

Filebeat 只是一个二进制文件没有任何依赖。它占用资源极少,尽管它还十分年轻,正式因为它简单,所以几乎没有什么可以出错的地方,所以它的可靠性还是很高的。它也为我们提供了很多可以调节的点,例如:它以何种方式搜索新的文件,以及当文件有一段时间没有发生变化时,何时选择关闭文件句柄。

劣势

Filebeat 的应用范围十分有限,所以在某些场景下我们会碰到问题。例如,如果使用 Logstash 作为下游管道,我们同样会遇到性能问题。正因为如此,Filebeat 的范围在扩大。开始时,它只能将日志发送到 Logstash 和 Elasticsearch,而现在它可以将日志发送给 Kafka 和 Redis,在 5.x 版本中,它还具备过滤的能力。

典型应用场景

Filebeat 在解决某些特定的问题时:日志存于文件,我们希望将日志直接传输存储到 Elasticsearch。这仅在我们只是抓去(grep)它们或者日志是存于 JSON 格式(Filebeat 可以解析 JSON)。或者如果打算使用 Elasticsearch 的 Ingest 功能对日志进行解析和丰富。

将日志发送到 Kafka/Redis。所以另外一个传输工具(例如,Logstash 或自定义的 Kafka 消费者)可以进一步丰富和转发。这里假设选择的下游传输工具能够满足我们对功能和性能的要求。

Fluentd <-- Ruby

Fluentd 创建的初衷主要是尽可能的使用 JSON 作为日志输出,所以传输工具及其下游的传输线不需要猜测子字符串里面各个字段的类型。这样,它为几乎所有的语言都提供库,这也意味着,我们可以将它插入到我们自定义的程序中。

优势

和多数 Logstash 插件一样,Fluentd 插件是用 Ruby 语言开发的非常易于编写维护。所以它数量很多,几乎所有的源和目标存储都有插件(各个插件的成熟度也不太一样)。这也意味这我们可以用 Fluentd 来串联所有的东西。

劣势

因为在多数应用场景下,我们会通过 Fluentd 得到结构化的数据,它的灵活性并不好。但是我们仍然可以通过正则表达式,来解析非结构化的数据。尽管,性能在大多数场景下都很好,但它并不是***的,和 syslog-ng 一样,它的缓冲只存在与输出端,单线程核心以及 Ruby GIL 实现的插件意味着它大的节点下性能是受限的,不过,它的资源消耗在大多数场景下是可以接受的。对于小的或者嵌入式的设备,可能需要看看 Fluent Bit,它和 Fluentd 的关系与 Filebeat 和 Logstash 之间的关系类似。

典型应用场景

Fluentd 在日志的数据源和目标存储各种各样时非常合适,因为它有很多插件。而且,如果大多数数据源都是自定义的应用,所以可以发现用 fluentd 的库要比将日志库与其他传输工具结合起来要容易很多。特别是在我们的应用是多种语言编写的时候,即我们使用了多种日志库,日志的行为也不太一样。

结论

对上上述对比结论:

​ 性能:filebeat < fluentd < logstash

​ 功能:logstash < fluentd < filebeat

通过对公司业务和技术栈的对比选择的方案为:filebeat收集日志,logstash处理日志。

可视化展示

可选组件为kibana、grafana。

组件介绍

Kibana和Grafana是两个开源工具,能可视化和推断大量日志数据内的趋势。

Kibana: 是一个分析和可视化平台,它可以浏览、可视化存储在Elasticsearch集群上排名靠前的日志数据,并构建仪表盘。

Grafana: 是一个开源仪表盘,主要用于大规模指标数据的可视化展现。

优缺点对比:

日志与度量

Grafana专注于根据CPU和IO利用率之类的特定指标提供时间序列图表。Grafana无法进行数据的检索和浏览。

Kibana则专注于另一方面,它运行于Elasticsearch的上层,能创建一个复杂的日志分析仪表盘。

基于角色的访问

Kibana的仪表盘是公开的,没有进行基于角色的访问控制。如果需要针对多个用户设置不同的权限级别,就得增加额外的配置Shield

Grafana 内置的 RBA 允许你维护用户和团队访问仪表盘的权限。Grafana 的富 API可能用于保存特定仪表表、创建用户用户和更新数据源的任务。

仪表盘灵活性

Kibana有大量内置的图表类型,但它们的控制仍是最初的限制。

Grafana包括更多的选择,可以更灵活地浏览和使用图表。

数据源的集成

Grafana支持许多不同的存储后端。Grafana 针对每个数据源都有一个特定的查询编辑器,它是针对数据源所具备的特性和能力特别定制的。

Kibana 原生集成进了 ELK 栈,这使安装极为简单,对用户非常友好。

结论

Grafana展示数据统计图形,Kibana看具体数据信息;

Kibana结合Elasticsearch操作简单集成了绝大多数ES的API,是专业的日志展示应用。

Grafana结合Elasticsearch操作复杂,对不同的应用,如nginx,tomcat 需要制作不通的json,功能不如Kibana全,Grafana只能查询,不能进行删改操作,不能查json。

可选方案:

elasticsearch + logstash + filebeat + kibana + kafka 【主推】

elasticsearch + logstash + filebeat + grafana + kafka 【可选】

部署方案

Kubernetes集群中的日志收集解决方案

编号 方案 优点 缺点
1 node上部署一个日志收集程序 每个node仅需部署一个日志收集程序,消耗资源少,对应用无侵入 应用程序日志需要写到标准输出和标准错误输出,不支持多行日志
2 pod中附加一个日志收集容器 低耦合 每个pod启动一个日志收集容器,增加资源消耗
3 应用程序直接推送日志 无需额外收集工具 侵入应用,增加应用复杂度

成果展示

Kibana:

Grafana:



这里,选择kafka作为消息队列,配置kafka集群,结合ELFK集群收集应用日志。那么选择redis还是kafka作为消息队列呢?从以下三点考虑:

生产初期,Service服务较少,访问量较少,使用ELFK集群就可以满足生产需求。但随着业务量的不断增加,日志量成倍增长,针对此情况,需要对ELK增加消息队列,以减轻前端ES集群的压力。

* 消息推送的可靠性:

Redis 消息推送(基于分布式 Pub/Sub)多用于实时性较高的消息推送,并不保证可靠。

Redis-Pub/Sub 断电就会清空数据,而使用 Redis-List 作为消息推送虽然有持久化,也并非完全可靠不会丢失。

Kafka 虽然有一些延迟但保证可靠。

* 订阅功能的分组:

Redis 发布订阅除了表示不同的 topic 外,并不支持分组。

Kafka 中发布一个内容,多个订阅者可以分组,同一个组里只有一个订阅者会收到该消息,这样可以用作负载均衡。

* 集群资源的消耗:

Redis 3.0之后个有提供集群ha机制,但是要为每个节点都配置一个或者多个从节点,从节点从主节点上面拉取数据,主节点挂了,从节点顶替上去成为主节点,但是这样对资源比较浪费。

Kafka 作为消息队列,能充分的运用集群资源,每个应用相当于一个topic,一个topic可拥有多个partition,并且partition能轮询分配到每个节点上面,并且生产者生产的数据也会均匀的放到partition中,

即使上层只有1个应用kafka集群的资源也会被充分的利用到,这样就避免了redis集群出现的数据倾斜问题,并且kafka有类似于hdfs的冗余机制,一个broker挂掉了不影响整个集群的运行。

原文地址:https://www.cnblogs.com/zisefeizhu/p/13063634.html