日志的艺术:Loki背后的存储智慧

2024-02-29 16:04:20 浏览数 (2)

近日见闻

1、 小红书开源一款播放器。REDPlayer是一款由小红书自主研发的跨平台(支持Android、iOS、HarmonyOS等平台)播放器。不同于行业其他播放器,REDPlayer 具有结构简单、耦合度低、功能边界清晰等特点,提供了多种接入方式,技术人员可根据需要灵活选择,既可快速集成SDK使用,也可基于源码进行定制开发。 --gitee

2、南京大学将开通全国高校首家 AI 课程,相信一定会有更多的创新。

3、鸿蒙程序员平均月薪超 1万8,打造鸿蒙生态需要人才的不断注入。

  1. 摘抄:
代码语言:javascript复制
一个人不论伟大还是平凡,

只要他顺应自己的天性,

找到了自己真正喜欢做的事,

并且一心把自己喜欢做的事做得尽善尽美,

他在这世界上就有了牢不可破的家园。

于是,他不但会有足够的勇气去承受外界的压力,

而且会有足够的清醒来面对形形色色的机会的诱惑。


——格里高利《项塔兰》

ioredis 作者 @Luin 宣布该项目已被 Redis 公司收购。太强了,十年坚持不懈做好自己的项目!十年的坚持有了很好的结果,羡慕的同时值得我们去学习!希望自己在不断努力后也有自己的好项目吧!地址https://github.com/luin

关于Loki日志收集

Loki是一个开源的日志聚合系统,由Grafana Labs开发,有水平扩展、高可用、多租户的特点。它与Grafana监控平台紧密集成,旨在提供一种高效、易于操作的方法,来存储和查询大量的日志数据。Loki的设计目标是提供类似于Prometheus的日志聚合解决方案,但它主要关注日志内容本身的索引,而不是全文索引,这样可以减少存储需求和提高效率。

特点

Loki的原理和架构设计专注于简单和效率,使用较少的CPU和内存资源,同时最大化存储和查询速度。

  • 最小化索引

Loki的一个核心原理是它并不索引日志内容,而是只索引日志的元数据,即标签信息。这与传统的全文搜索工具(如Elasticsearch)不同,后者会对日志的每个词创建索引以加速搜索。Loki索引的是一系列的标签键值对,每个日志流(stream)都附加了这些标签,这些标签可以是机器名、应用名、日志级别等。这种做法大幅减少了索引大小和索引操作所需的资源。

  • 日志流和数据块

Loki中日志数据被结构化为日志流。每个流由唯一的一组标签标识,并且包含了一个或多个日志数据块(chunks)。一个数据块包含了一定时间范围内的日志数据,并且是按时间顺序存储。数据块被压缩后存储,以节省存储空间。

  • 水平可扩展和多租户

Loki设计为水平可扩展的系统,支持多租户使用。这意味着Loki可以在多个服务器上运行,通过增加更多的节点来扩展其处理能力。多租户能力允许不同的用户或团队共享相同的Loki实例,同时保证数据隔离和权限控制。

  • 查询日志数据

Loki提供了一个类似于PromQL的查询语言,允许用户基于时间、标签过滤以及正则表达式搜索日志内容。虽然不提供全文搜索的能力,但是通过有效的过滤和搜索,用户通常可以快速定位到所需的日志信息。

  • 可插拔的存储后端

Loki设计了可插拔的存储后端,可以根据需求选择不同的存储解决方案来存放日志数据和索引,包括本地磁盘、高速缓存层(如memcached)和云存储服务(如Amazon S3或Google Cloud Storage)。

组件

  • loki是主服务器,负责存储日志和提供查询功能,存储的是日志数据而不是时序数据。
  • promtail是代理,负责收集日志并将其发送给 loki 。
  • Grafana用于 UI 展示,用于查询和查看日志数据。

存储架构

  • Loki设计了一套简洁的存储架构,用于高效地处理日志数据。它将日志数据分为两个部分存储:索引和压缩的数据块。
  • 索引数据用于快速查找日志流,而数据块则包含实际的日志内容。
  • Loki支持多种存储后端,例如Amazon S3、本地文件系统等,用户可以选择适合自己需求的存储解决方案。

工作流程

  • 日志收集:

Promtail或其他集成的代理(如Fluentd、Fluent Bit)监控目标日志文件。 当日志文件发生变化,这些代理就会读取新的日志行,并添加必要的标签。

  • 日志处理和转发:

收集到的日志会被格式化并附上标签,然后推送到Loki服务。

  • 日志存储:

Loki接收到数据后,会将索引和数据块分别进行处理。 索引存储了日志流的元数据,而数据块则是被压缩后的日志内容。

  • 查询和可视化:

用户通过Grafana对Loki进行查询,通常是基于时间范围和标签选择器。 Loki处理查询请求,返回匹配的日志数据。 Grafana展示查询结果,提供了丰富的日志查看和分析功能。

浅谈设计原理

Loki的设计灵感来自于Prometheus,它的设计原理主要基于以下几点:

  • 索引最小化: Loki不对日志内容本身建立全文索引,而是只对每个日志流的元数据(例如,日志来源的标签)建立索引。这种方式减少了索引的大小和存储需求。
  • 日志数据分离: Loki将日志数据和索引分开存储。索引存储在内存中或者高效的数据库中,而日志数据可以存储在更廉价的存储系统中,如S3、GCS或本地磁盘。
  • 强大的查询语言: Loki使用类似于PromQL的查询语言LogQL,允许用户基于标签过滤和搜索日志数据。
  • 可伸缩性: Loki的设计支持水平扩展,可以通过增加更多的节点来处理更多的数据。

安装方式

二进制

这种方式需要手动下载Loki的预编译二进制文件,然后在你的系统上运行它。 大致步骤如下:

  • 访问Loki的GitHub发布页面(https://github.com/grafana/loki/releases)。
  • 选择要下载的版本。根据你的操作系统和架构下载二进制文件。
  • 解压缩后,你将得到一个名为loki-linux-amd64的可执行文件(名称可能略有不同)。运行它即可启动Loki服务器:

./loki-linux-amd64 -config.file=config.yaml

收集日志的promtail方法如上,只要更改配置文件即可,类似如下:

代码语言:javascript复制
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://localhost:3100/loki/api/v1/push

scrape_configs:
- job_name: system
  static_configs:
  - targets:
      - localhost
    labels:
      job: varlogs
      __path__: /var/log/*log

配置文件中,Promtail 将会收集 /var/log 目录下所有以log结尾的文件,并将它们发送到运行在localhost上的 Loki 服务器。请根据你的实际情况调整 Loki 服务器的 URL 和日志文件的路径。

Docker

  • 获取Loki的Docker镜像:
代码语言:javascript复制
docker pull grafana/loki
  • 运行Loki容器:
代码语言:javascript复制
docker run -p 3100:3100 grafana/loki

这将启动Loki,并将容器内的3100端口映射到主机的3100端口。

  • 收集日志: 获取Promtail的Docker镜像:
代码语言:javascript复制
docker pull grafana/promtail

配置Promtail,通常需要创建一个配置文件promtail-config.yaml,指定Loki的服务地址和需要收集的日志文件。

运行Promtail容器,并挂载配置文件和日志目录:

代码语言:javascript复制
docker run -v /path/to/your/promtail-config.yaml:/etc/promtail/config.yml -v /var/log:/var/log grafana/promtail

确保将/path/to/your/promtail-config.yaml替换为你的配置文件路径,/var/log是大多数Linux系统日志存储的地方。

HELM

  • 添加Loki的Helm repository:
代码语言:javascript复制
helm repo add grafana https://grafana.github.io/helm-charts

更新Helm仓库,并安装Loki Stack,其中包括Loki本身和Promtail::

代码语言:javascript复制
helm repo update
helm upgrade --install loki grafana/loki-stack

索引、数据块

在Loki中,日志数据被分为两个主要组成部分:索引(Indices)和数据块(Chunks)。这种设计使得Loki能够高效地存储大量日志数据,并在检索时实现快速查询。

索引

索引是关于日志流的元数据,而不是日志内容本身。在Loki中,日志流是由一组唯一的标签集定义的。例如,每个日志流可能代表一个特定应用的日志,标签可以包括应用的名称、所在的Kubernetes集群、命名空间、Pod等。这些标签用于识别和查询日志数据。

索引中存储的内容包括:

  • 标签集(Label set):每个日志流的唯一标签集,用于识别和选择日志流。
  • 流的标识符(Stream identifiers):与标签集相关联的内部标识符。
  • 时间范围(Time ranges):日志流中日志条目的时间戳范围。

这些索引允许Loki快速筛选并查找匹配特定查询条件的日志流,而无需扫描实际的日志数据。索引通常存储在分布式数据库中,以提供快速的读取和查询性能。

数据块

数据块是包含日志内容的实体。当Promtail或其他日志收集器向Loki发送日志时,Loki会将这些日志行组织成块。

数据块中存储的内容包括:

  • 压缩的日志条目(Compressed log entries):日志条目被聚集并压缩以减少存储空间。
  • 时间序列信息(Time series information):每个块存储一系列时间排序的日志条目。
  • 块标识符(Chunk identifiers):每个块都有一个唯一的标识符,将其与一个或多个索引关联。

数据块在压缩后会以二进制格式存储。Loki设计了一种简单的格式来存储这些时间序列的日志数据。这种格式允许Loki在检索日志时只解压查询所需的部分,而不是整个块,从而提高效率。数据块通常存储在如Amazon S3或本地文件系统等对象存储中。

在Loki配置中,你可以定义如下配置以指定索引和块的存储路径:

代码语言:javascript复制
storage_config:
  boltdb_shipper:
    active_index_directory: /path/to/loki/index
    cache_location: /path/to/loki/index_cache
    shared_store: filesystem
  filesystem:
    directory: /path/to/loki/chunks

0 人点赞