再见笨重的ELK,轻量化日志 Loki 牛逼,奉上全攻略教程!

再见笨重的ELK,轻量化日志 Loki 牛逼,奉上全攻略教程!大家好 我是宝哥 1 前言在对公司容器云的日志方案进行设计的时候 发现主流的 ELK Elasticsearc Logstash Kibana 或者 EFK Elasticsearc FilebeatorFl

大家好,欢迎来到IT知识分享网。

3d0d8f38cb282a2a6e99aadb125feada.png

大家好,我是宝哥!

1、前言

在对公司容器云的日志方案进行设计的时候,发现主流的 ELK(Elasticsearch,Logstash,Kibana)或者 EFK(Elasticsearch,Filebeat or Fluentd,Kibana)比较重,再加上现阶段对于 ES 复杂的搜索功能很多都用不上,最终选择了 Grafana 开源的 Loki 日志系统。

下面我们来介绍下 Loki 的一些基本概念和架构,当然 EFK 作为业界成熟的日志聚合解决方案也是大家应该需要熟悉和掌握的。

2、简介

Loki 是 Grafana Labs 团队最新的开源项目,是一个水平可扩展,高可用性,多租户的日志聚合系统。它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流编制一组标签,专门为 Prometheus 和 Kubernetes 用户做了相关优化。该项目受 Prometheus 启发,官方的介绍就是:Like Prometheus,But For Logs.,类似于 Prometheus 的日志系统;

项目地址:https://github.com/grafana/loki/

与其他日志聚合系统相比, Loki 具有下面的一些特性:

  • 不对日志进行全文索引。通过存储压缩非结构化日志和仅索引元数据,Loki 操作起来会更简单,更省成本。
  • 通过使用与 Prometheus 相同的标签记录流对日志进行索引和分组,这使得日志的扩展和操作效率更高,能对接 alertmanager;
  • 特别适合储存 Kubernetes Pod 日志;诸如 Pod 标签之类的元数据会被自动删除和编入索引;
  • 受 Grafana 原生支持,避免kibana和grafana来回切换;

3、架构说明

4d2aa5042899f2c32dbff32949c1792d.png

3.1 组件说明

  • Promtail 作为采集器,类比filebeat
  • loki 相当于服务端,类比es
  • querier 查询器
  • inester 日志存储器
  • query-frontend 前置查询器
  • distributor 写入分发器

可以通过 loki 二进制的 -target 参数指定运行角色

3.2 read path

查询器接受HTTP/1 数据请求
查询器将查询传递给所有ingesters请求内存中的数据
接收器接受读取的请求,并返回与查询匹配的数据(如果有)
如果没有接受者返回数据, 则查询器会从后备存储中延迟加载数据并对其执行查询;
查询器将迭代所有接收到的数据并进行重复数据删除, 从而通过HTTP/1连接返回最终数据集;

3.3 write path

001e53a5197c828f8fa91ae5132d994e.png

分发服务器收到一个HTTP/1请求,以存储流数据;
每个流都使用散列环散列;
分发程序将每个流发送到适当的inester和其副本(基于配置的复制因子);
每个实例将为流的数据创建一个块或将其追加到现有块中, 每个租户和每个标签集的块都是唯一的;
分发服务器通过HTTP/1链接以成功代码作为响应;

4、部署

4.1 本地化模式安装

下载 Promtail 和 Loki

wget https://github.com/grafana/loki/releases/download/v2.2.1/loki-linux-amd64.zip wget https://github.com/grafana/loki/releases/download/v2.2.1/promtail-linux-amd64.zip
安装 Promtail

$ mkdir /opt/app/{promtail,loki} -pv # promtail配置文件 $ cat <<EOF> /opt/app/promtail/promtail.yaml server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /var/log/positions.yaml # This location needs to be writeable by promtail. client: url: http://localhost:3100/loki/api/v1/push scrape_configs: - job_name: system pipeline_stages: static_configs: - targets: - localhost labels: job: varlogs host: yourhost __path__: /var/log/*.log EOF # 解压安装包 unzip promtail-linux-amd64.zip mv promtail-linux-amd64 /opt/app/promtail/promtail # service文件 $ cat <<EOF >/etc/systemd/system/promtail.service [Unit] Description=promtail server Wants=network-online.target After=network-online.target [Service] ExecStart=/opt/app/promtail/promtail -config.file=/opt/app/promtail/promtail.yaml StandardOutput=syslog StandardError=syslog SyslogIdentifier=promtail [Install] WantedBy=default.target EOF systemctl daemon-reload systemctl restart promtail systemctl status promtail
安装loki

$ mkdir /opt/app/{promtail,loki} -pv # promtail配置文件 $ cat <<EOF> /opt/app/loki/loki.yaml auth_enabled: false server: http_listen_port: 3100 grpc_listen_port: 9096 ingester: wal: enabled: true dir: /opt/app/loki/wal lifecycler: address: 127.0.0.1 ring: kvstore: store: inmemory replication_factor: 1 final_sleep: 0s chunk_idle_period: 1h # Any chunk not receiving new logs in this time will be flushed max_chunk_age: 1h # All chunks will be flushed when they hit this age, default is 1h chunk_target_size:  # Loki will attempt to build chunks up to 1.5MB, flushing first if chunk_idle_period or max_chunk_age is reached first chunk_retain_period: 30s # Must be greater than index read cache TTL if using an index cache (Default index read cache TTL is 5m) max_transfer_retries: 0 # Chunk transfers disabled schema_config: configs: - from: 2020-10-24 store: boltdb-shipper object_store: filesystem schema: v11 index: prefix: index_ period: 24h storage_config: boltdb_shipper: active_index_directory: /opt/app/loki/boltdb-shipper-active cache_location: /opt/app/loki/boltdb-shipper-cache cache_ttl: 24h # Can be increased for faster performance over longer query periods, uses more disk space shared_store: filesystem filesystem: directory: /opt/app/loki/chunks compactor: working_directory: /opt/app/loki/boltdb-shipper-compactor shared_store: filesystem limits_config: reject_old_samples: true reject_old_samples_max_age: 168h chunk_store_config: max_look_back_period: 0s table_manager: retention_deletes_enabled: false retention_period: 0s ruler: storage: type: local local: directory: /opt/app/loki/rules rule_path: /opt/app/loki/rules-temp alertmanager_url: http://localhost:9093 ring: kvstore: store: inmemory enable_api: true EOF # 解压包 unzip loki-linux-amd64.zip mv loki-linux-amd64 /opt/app/loki/loki # service文件 $ cat <<EOF >/etc/systemd/system/loki.service [Unit] Description=loki server Wants=network-online.target After=network-online.target [Service] ExecStart=/opt/app/loki/loki -config.file=/opt/app/loki/loki.yaml StandardOutput=syslog StandardError=syslog SyslogIdentifier=loki [Install] WantedBy=default.target EOF systemctl daemon-reload systemctl restart loki systemctl status loki

5、使用

5.1 grafana上配置loki数据源

66164d823461145309c7e9e32eba2dd6.png

32de9d3a27c1e31c1b95beb149d5e3fd.png

grafana-loki-dashsource-config
源地址配置 http://loki:3100 即可,保存。
保存完成后,切换到 grafana 左侧区域的 Explore,即可进入到 Loki 的页面

5d92f94268dc9095e58499ac15fa282e.png

1cbb8949e5de1fc4f7b83757f9801c9e.png

3c9605617bf3b4da1c853aa5cd0bb2cf.png

grafana-loki-logs
这里展示的是 promtail 容器里面 / var/log 目录中的日志
promtail 容器 /etc/promtail/config.yml


server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /tmp/positions.yaml clients: - url: http://loki:3100/loki/api/v1/push scrape_configs: - job_name: system static_configs: - targets: - localhost labels: job: varlogs __path__: /var/log/*log

这里的 job 就是 varlog,文件路径就是 /var/log/*log

5.2 在grafana explore上配置查看日志


查看日志 rate({job="message"} |="kubelet"

算 qps rate({job=”message”} |=”kubelet” [1m])

5.3 只索引标签

之前多次提到 loki 和 es 最大的不同是 loki 只对标签进行索引而不对内容索引 下面我们举例来看下

以简单的 promtail 配置举例

配置解读


scrape_configs: - job_name: system pipeline_stages: static_configs: - targets: - localhost labels: job: message __path__: /var/log/messages
  • 上面这段配置代表启动一个日志采集任务
  • 这个任务有 1 个固定标签job=”syslog”
  • 采集日志路径为 /var/log/messages,会以一个名为 filename 的固定标签
  • 在 promtail 的 web 页面上可以看到类似 prometheus 的 target 信息页面

可以和使用 Prometheus 一样的标签匹配语句进行查询


scrape_configs: - job_name: system pipeline_stages: static_configs: - targets: - localhost labels: job: syslog __path__: /var/log/syslog - job_name: system pipeline_stages: static_configs: - targets: - localhost labels: job: apache __path__: /var/log/apache.log

5.3 标签匹配模式的特点

原理

和 prometheus 一致,相同标签对应的是一个流 prometheus 处理 series 的模式
prometheus 中标签一致对应的同一个 hash 值和 refid(正整数递增的 id),也就是同一个 series
时序数据不断的 append 追加到这个 memseries 中
当有任意标签发生变化时会产生新的 hash 值和 refid,对应新的 series
loki 处理日志的模式 – 和 prometheus 一致,loki 一组标签值会生成一个 stream – 日志随着时间的递增会追加到这个 stream 中,最后压缩为 chunk – 当有任意标签发生变化时会产生新的 hash 值,对应新的 stream

查询过程
  • 所以 loki 先根据标签算出 hash 值在倒排索引中找到对应的 chunk?
  • 然后再根据查询语句中的关键词等进行过滤,这样能大大的提速
  • 因为这种根据标签算哈希在倒排中查找 id,对应找到存储的块在 prometheus 中已经被验证过了
  • 属于开销低
  • 速度快

5.5 动态标签和高基数

所以有了上述知识,那么就得谈谈动态标签的问题了

两个概念
何为动态标签:说白了就是标签的 value 不固定
何为高基数标签:说白了就是标签的 value 可能性太多了,达到 10 万,100 万甚至更多

比如 apache 的 access 日志


11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/ Firefox/3.5.7 GTB6"

在 Promtail 中使用 regex 想要匹配 action 和 status_code 两个标签


scrape_configs: - job_name: system pipeline_stages: static_configs: - targets: - localhost labels: job: syslog __path__: /var/log/syslog - job_name: system pipeline_stages: static_configs: - targets: - localhost labels: job: apache __path__: /var/log/apache.log - job_name: system pipeline_stages: - regex: expression: "^(?P<ip>\\S+) (?P<identd>\\S+) (?P<user>\\S+) \\[(?P<timestamp>[\\w:/]+\\s[+\\-]\\d{4})\\] \"(?P<action>\\S+)\\s?(?P<path>\\S+)?\\s?(?P<protocol>\\S+)?\" (?P<status_code>\\d{3}|-) (?P<size>\\d+|-)\\s?\"?(?P<referer>[^\"]*)\"?\\s?\"?(?P<useragent>[^\"]*)?\"?$" - labels: action: status_code: static_configs: - targets: - localhost labels: job: apache env: dev __path__: /var/log/apache.log

那么对应 action=get/post 和 status_code=200/400 则对应 4 个流


11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/ Firefox/3.5.7 GTB6" 11.11.11.12 - frank [25/Jan/2000:14:00:02 -0500] "POST /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/ Firefox/3.5.7 GTB6" 11.11.11.13 - frank [25/Jan/2000:14:00:03 -0500] "GET /1986.js HTTP/1.1" 400 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/ Firefox/3.5.7 GTB6" 11.11.11.14 - frank [25/Jan/2000:14:00:04 -0500] "POST /1986.js HTTP/1.1" 400 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/ Firefox/3.5.7 GTB6"
高基数问题

5.6 全文索引问题

大索引既复杂又昂贵。通常,日志数据的全文索引的大小等于或大于日志数据本身的大小
要查询日志数据,需要加载此索引,并且为了提高性能,它可能应该在内存中。这很难扩展,并且随着您摄入更多日志,索引会迅速变大。
Loki 的索引通常比摄取的日志量小一个数量级,索引的增长非常缓慢

加速查询没标签字段

以上边提到的 ip 字段为例 – 使用过滤器表达式查询


{job="apache"} |= "11.11.11.11"
loki查询时的分片(按时间范围分段grep)

Loki 将把查询分解成较小的分片,并为与标签匹配的流打开每个区块,并开始寻找该 IP 地址。
这些分片的大小和并行化的数量是可配置的,并取决于您提供的资源
如果需要,您可以将分片间隔配置为 5m,部署 20 个查询器,并在几秒钟内处理千兆字节的日志
或者,您可以发疯并设置 200 个查询器并处理 TB 的日志!

两种索引模式对比
日志量少时少加标签

因为每多加载一个 chunk 就有额外的开销
举例,如果该查询是 {app=”loki”,level!=”debug”}
在没加 level 标签的情况下只需加载一个 chunk 即 app=“loki” 的标签
如果加了 level 的情况,则需要把 level=info,warn,error,critical 5 个 chunk 都加载再查询

需要标签时再去添加
日志应当按时间递增

来源:https://www.cnblogs.com/you-men/p/14900249.html

精彩推荐: 现在大火的低代码是怎么回事?从实现原理谈谈低代码 VPN 的技术原理是什么? XXL-JOB分布式任务调度平台(真·保姆级教程) 别再自己瞎写工具类了,SpringBoot 内置工具类应有尽有, 建议收藏!! Redis高效实现点赞、取消点赞功能,太骚了! 亿级流量架构,服务器如何扩容?写得太好了!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/156951.html

(0)
上一篇 2025-02-09 13:45
下一篇 2025-02-09 14:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信