文章转载参考自:https://jishuin.proginn.com/p/763bfbd2ac34
Loki 是 Grafana Labs 团队最新的开源项目,是一个水平可扩展,高可用性,多租户的日志聚合系统。它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流配置一组标签。项目受 Prometheus 启发,官方的介绍就是:Like Prometheus, but for logs,类似于 Prometheus 的日志系统。
1. 概述
Loki 只会对你的日志元数据标签(就像 Prometheus 的标签一样)进行索引,而不会对原始的日志数据进行全文索引。然后日志数据本身会被压缩,并以 chunks(块)的形式存储在对象存储(比如 S3 或者 GCS)甚至本地文件系统。一个小的索引和高度压缩的 chunks 可以大大简化操作和降低 Loki 的使用成本。
1.1 多租户
Loki 支持多租户模式,租户之间的数据是完全分开的。多租户是通过一个租户 ID(用数字字母生成的字符串)实现的。当多租户模式被禁用后,所有请求都会在内部生成一个**假的**
租户 ID。
1.2 操作模式
Loki 可以在本地小规模运行也可以横向扩展。Loki 自带单进程模式,可以在一个进程中运行所有需要的微服务。单进程模式非常适合于测试 Loki 或者小规模运行。对于横向扩展来说,Loki 的微服务是可以被分解成单独的进程的,使其能够独立扩展。
1.3 组件
Distributor(分配器)
分配器服务负责处理客户端写入的日志。本质上它是日志数据写入路径中的第一站
。一旦分配器接收到日志数据,它就会把它们分成若干批次,并将它们并行地发送到多个采集器去。
分配器通过 gPRC 和采集器进行通信。它们是无状态的,所以我们可以根据实际需要对他们进行扩缩容。
Hashing
分配器采用一致性哈希和可配置的复制因子结合使用,来确定哪些采集器服务应该接收日志数据。该哈希是基于日志标签和租户 ID 生成的。
存储在 Consul 中的哈希环被用来实现一致性哈希;所有的采集器将他们自己的一组 Token 注册到哈希环中去。然后分配器找到和日志的哈希值最匹配的 Token,并将数据发送给该 Token 的持有者。
一致性
由于所有的分配器都共享同一个哈希环,所以可以向任何分配器发送写请求。
为了确保查询结果的一致性,Loki 在读和写上使用了 Dynamo 方式的法定人数一致性。这意味着分配器将等待至少有一半以上的采集器响应,再向用户发送样本,然后再响应给用户。
Ingester(采集器)
采集器服务负责将日志数据写入长期存储的后端(DynamoDB、S3、Cassandra 等等)。
采集器会校验采集的日志是否乱序。当采集器接收到的日志行与预期的顺序不一致时,该行日志将被拒绝,并向用户返回一个错误。有关更多相关信息,可以查看时间戳排序部分内容。
采集器验证接收到的日志行是按照时间戳递增的顺序接收的(即每条日志的时间戳都比之前的日志晚)。当采集器接收到的日志不按照这个顺序,日志行将被拒绝并返回错误。
每一个唯一的标签集数据都会在内存中构建成chunks
,然后将它们存储到后端存储中去。
如果一个采集器进程崩溃或者突然挂掉了,所有还没有被刷新到存储的数据就会丢失。Loki 通常配置成多个副本(通常为3个)来降低这种风险。
时间戳排序
一般来说推送到 Loki 的所有日志行必须比之前收到的行有一个更新的时间戳。然而有些情况可能是多行日志具有相同的纳秒级别的时间戳,可以按照下面两种情况进行处理:
-
如果传入的行和之前接收到的行完全匹配(时间戳和日志文本都匹配),则传入的行会被视为完全重复并会被忽略。
-
如果传入行的时间戳和前面一行的时间戳相同,但是日志内容不相同,则会接收该行日志。这就意味着,对于相同的时间戳,有可能有两个不同的日志行。
Handoff(交接)
默认情况下,当一个采集器关闭并视图离开哈希环时,它将等待查看是否有新的采集器视图进入,然后再进行 flush,并尝试启动交接。交接将把离开的采集器拥有的所有 Token 和内存中的 chunks 都转移到新的采集器中来。
这个过程是为了避免在关闭时 flush 所有的 chunks,因为这是一个比较缓慢的过程,比较耗时。
文件系统支持
采集器支持通过 BoltDB 写入到文件系统,但这只在单进程模式下工作,因为查询器需要访问相同的后端存储,而且 BoltDB 只允许一个进程在给定时间内对 DB 进行锁定。
Querier(查询器)
查询器服务负责处理 LogQL 查询语句来评估存储在长期存储中的日志数据。
它首先会尝试查询所有采集器的内存数据,然后再返回到后端存储中加载数据。
前端查询
该服务是一个可选组件,在一组查询器前面,来负责在它们之间公平地调度请求,尽可能地并行化它们并缓存请求。
Chunk(块)存储
块存储是 Loki 的长期数据存储,旨在支持交互式查询和持续写入,无需后台维护任务。它由以下几部分组成:
-
块索引,该索引可以由 DynamoDB、Bigtable 或者 Cassandra 来支持。
-
块数据本身的 KV 存储,可以是 DynamoDB、Bigtable、Cassandra,也可以上是对象存储,比如 S3。
与 Loki 的其他核心组件不同,块存储不是一个独立的服务、任务或者进程,而是嵌入到需要访问 Loki 数据的采集器和查询器中的库。
块存储依赖统一的 ”NoSQL“ 存储(DynamoDB、Bigtable 和 Cassandra)接口,该接口可以用来支持块存储索引。该接口假设索引是由以下几个 key 构成的集合:
-
哈希 KEY - 这是所有的读和写都需要的。
-
范围 KEY - 这是写的时候需要的,读的时候可以省略,可以通过前缀或者范围来查询。
上面支持的这些数据库中接口的工作原理有些不同:
-
DynamoDB 支持范围和哈希 KEY。所以索引条目直接建模为 DynamoDB 的数据,哈希 KEY 为分布式 KEY,范围为范围 KEY。
-
对于 Bigtable 和 Cassandra,索引项被建模为单个的列值。哈希 KEY 成为行 KEY,范围 KEY 成为列 KEY。
一些模式被用于对块存储的读取和写入时使用的匹配器和标签集合映射到索引的适当操作中来。随着 Loki 的发展也会增加一些新的模式,主要是为了更好地平衡些和提高查询性能。
1.4 对比其他日志系统
EFK(Elasticsearch、Fluentd、Kibana)用于从各种来源获取、可视化和查询日志。
Elasticsearch 中的数据以非结构化 JSON 对象的形式存储在磁盘上。每个对象的键和每个键的内容都有索引。然后可以使用 JSON 对象来定义查询(称为 Query DSL)或通过 Lucene 查询语言来查询数据。
相比之下,单二进制模式下的 Loki 可以将数据存储在磁盘上,但在水平可扩展模式下,数据存储需要在云存储系统中,如 S3、GCS 或 Cassandra。日志以纯文本的形式存储,并标记了一组标签的名称和值,其中只有标签会被索引。这种权衡使其操作起来比完全索引更便宜。Loki 中的日志使用 LogQL 进行查询。由于这种设计上的权衡,根据内容(即日志行内的文本)进行过滤的 LogQL 查询需要加载搜索窗口内所有与查询中定义的标签相匹配的块。
Fluentd 通常用于收集日志并转发到 Elasticsearch。Fluentd 被称为数据收集器,它可以从许多来源采集日志,并对其进行处理,然后转发到一个或多个目标。
相比之下,Promtail 是为 Loki 量身定做的。它的主要工作模式是发现存储在磁盘上的日志文件,并将其与一组标签关联的日志文件转发到 Loki。Promtail 可以为在同一节点上运行的 Kubernetes Pods 做服务发现,作为 Docker 日志驱动,从指定的文件夹中读取日志,并对 systemd 日志不断获取。
Loki 通过一组标签表示日志的方式与 Prometheus 表示指标的方式类似。当与Prometheus 一起部署在环境中时,由于使用了相同的服务发现机制,来自Promtail 的日志通常与你的应用指标具有相同的标签。拥有相同级别的日志和指标,用户可以在指标和日志之间无缝切换,帮助进行根本性原因分析。
Kibana 被用于可视化和搜索 Elasticsearch 数据,并且在对这些数据进行分析时非常强大。Kibana 提供了许多可视化工具来做数据分析,例如地图、用于异常检测的机器学习,以及关系图。也可以配置报警,当出现意外情况时,可以通知用户。
相比之下,Grafana 是专门针对 Prometheus 和 Loki 等数据源的时间序列数据定制的。仪表板可以设置为可视化指标(即将推出的日志支持),也可以使用探索视图对数据进行临时查询。和 Kibana 一样,Grafana 也支持根据你的指标进行报警。
2 开始使用 Loki
2.1 Loki 在 Grafana 中的配置
Grafana 在 6.0 以上的版本中内置了对 Loki 的支持。建议使用 6.3 或更高版本,就可以使用新的LogQL功能。
-
登录 Grafana 实例,如果这是你第一次运行 Grafana,用户名和密码都默认为
admin
。 -
在 Grafana 中,通过左侧侧边栏上的图标转到 "
配置 > 数据源
"。 -
单击
+ Add data source
按钮。 -
在列表中选择 Loki。
-
Http URL 字段是你的 Loki 服务器的地址,例如,在本地运行或使用端口映射的 Docker 运行时,地址可能是 http://localhost:3100。使用 docker-compose 或 Kubernetes 运行时,地址很可能是 https://loki:3100。
-
要查看日志,可以单击侧边栏上的 "
探索
",在左上角下拉菜单中选择 Loki 数据源,然后使用日志标签按钮过滤日志流。