还在用笨重的ELK?日志系统新贵Loki 了解一下

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

每天 14:00 更新文章,每天掉亿点点头发...

源码精品专栏

 

来源:www.cnblogs.com/you-men/

p/14900249.html

279fc5b40d0e8d5f7af88fa4e0d4073f.jpeg


前言

在对公司容器云的应用中,Elasticsearch 的搜索功能,Elasticsearch 的多种搜索功能都用不上,最终选择了Grafana开源的Loki日志系统。

下面来介绍下 Loki 的基本概念和,当然 EFK 作为众多业内人士的一些日志,我们聚合解决方案需要有和掌握的。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。

项目地址:https://github.com/YunaiV/ruoyi-vue-pro

简介

Loki Grafana Labs 的开源项目,是一个团队的开源项目,可扩展性高,是一个多级别的开源系统。

它的设计非常经济且易于操作,因为它不会为日志编制内容索引,而是为每个流编组标签,为我们和Kubernetes用户制作]相关的优化标签。

该项目受 Prometheus 的启发,官方的介绍就是:Like Prometheus,But For Logs。类似于 Prometheus 的日志系统。

项目地址:

https://github.com/grafana/loki/

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

  • 通过存储非日志记录和非索引元数据,Loki操作起来更简单,更省索引。

  • 通过使用与 Promethe 相同的标签进行索引和团队记录,这对记录日志对我们的记录者的扩展和操作日志有更大的影响,能够更好地响应警报人。

  • 特别适合索引存储 Kubernetes Pod 日志;诸如 Pod 标签之类的数据元会被自动删除和进入。

  • 受 Grafana 枣,避免 kibana 和 grafana 来回切换。

基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

项目地址:https://github.com/YunaiV/onemall

架构说明

4c421e0af15407378214d5a8e6741ce9.png

组件说明

说明如下:

  • Promtail 采集器,类比文件节拍

  • Loki 相当于服务端,类比 es

Loki进程包含四个角色:

  • 查询器 查询器

  • 内政声明

  • 查询前端分类查询器

  • 分销商写入分发器

可以通过 Loki 路由器的 -target 参数指定运行角色。

读取路径

如下:

  • 接受器接受 HTTP/1 数据查询请求

  • 查询器将查询传递给所有摄取者请求内存中的数据

  • 接收器接受读取的请求,并返回与查询匹配的数据(如果有)

  • 如果接受返回数据时,会从备存储中延迟加载数据,然后执行查询者并没有执行查询

  • 设备将通过所有接收到的数据并进行重复数据删除,重新通过HTTP/1连接查询返回最终数据集

写入路径
3c759954e8d194d47ebc12623fe6bc8b.png

如上图:

  • 分发服务器收到一个 HTTP/1 请求,以存储流数据

  • 流都使用散列环散列

  • 程序将每个和发送到适当的释放因子(基于配置的复制因子)

  • 实体流动中的所有实体都是其集中的个体,将创建一个和一个或多个现有标签的唯一的数据集

  • 分发服务器通过 HTTP/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
安装提示:
$ 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: 1048576  # 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

使用

grafana 上配置 loki 数据源

如下图:

86cc7d78a912a4693b73c482a53d4ee7.png

grafana-loki-dashsource

在数据源列表中选择 Loki,配置 Loki 源地址:

e6ea8b8b7fef65f16c8ac6eb386f47f3.png

grafana-loki-dashsource-config

源地址配置 http://loki:3100 智能,保存。

保存完成后,切换到grafana到左侧区域的探索,会进入Loki的页面:

d6ff4c6d9161c79c574640d4f09a57d7.png

格拉法纳洛基

然后我们点击系统采集日志的标签就可以把日志标签显示出来,可以根据这些标签进行的过滤查询:

a64d3ad9250672581b262c50fdeb1a0c.png

grafana-loki-日志标签

在这里选择 /var/log/messages,只要把该文件下面的日志过滤展示出来,不过,可能需要设置下一段时间才能看到数据:

0d80f77b1dc035117526326bd745d6b6.png

grafana-loki-日志

这里展示的是promtail Container里面/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

这里的工作就是varlog,文件路径就是/var/log/*log。

在 grafana explore 上配置查看日志
查看日志 rate({job="message"} |="kubelet"

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

仅索引标签

只是之前的索引内容是不同的索引 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,会以一个文件名的固定标签

  • 在promtail的网页上可以看到类似prometheus的目标信息页面

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

{job="系统日志"}:

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=~”apachesyslog”进行多个作业匹配

  • 也支持正则和正则非匹配

标签匹配模式的特点

原理如下:
  • 和 prometheus 一致,相同的标签是一个流 prometheus 处理系列的模式

  • prometheus 中标签一致的同一个 hash 值和 refid(正好递增就是同一个 id),也有一个系列

  • 将数据不断的追加到这个我的系列中

  • 当有任意标签发生变化时会产生新的哈希值和 refid,新的系列

loki 处理模式和 prometheus 一致,loki 等一系列日志的产生到会生成一个日志流。随着时间的增长会产生一个哈希值流中,最后压缩为块。有任意的标签变化时会新发生,188金宝搏下流。

查询过程
  • 所以 loki 先根据标签算出哈希值在倒排索引中找到的块?

  • 然后再根据语句中的等关键词进行过滤,这样可以更大的提速

  • 因为这种根据标签算哈希在倒排中查找id,找到存储的块在prometheus中已经被验证过了

  • 属于类别低

  • 速度快

动态标签和高基数

所以上面有知识,那么就得聊聊标签的问题了。

两个概念:

  • 何为动态标签:说白了就是标签的价值不固定

  • 何为高基数标签:说白了标签的值更多就是,达到10万,100万甚至更多

apache的访问日志:

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/20091221 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/20091221 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/20091221 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/20091221 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/20091221 Firefox/3.5.7 GTB6"

四个日志行将变成四个单独的流动,并开始填充四个单独的块。

如果出现另一个特殊的代码组合(例如“500”),创建另一个新流。

高基数问题

就像上面,如果给 ip 标签,给了一个预览的标签。高基数,这可以杀死Loki。

现场没有被标记,不会很容易被查询日志,你可以查询命令查询会为小块并当分发,以便在查询大量查询。

全文索引问题

大索引既复杂又完整。通常,日志的索引的大小或日志大于数据本身的大小。

要日志加载此索引,并且为了提高性能,它可能应该在内存扩展中,随着查询中的更多数据变化,这个索引需要更大的日志,然后索引会。

Loki 的索引量通常比简单的日志小一个,索引量的增长非常缓慢。

加速没有字段:上面提到的ip字段查询标签-使用过滤器表达式。
{job="apache"} |= "11.11.11.11"
loki 时的分片(按时间范围分段查询grep):
  • Loki将把分割成该片段与该分片的匹配,并标签的每个区块,并开始寻找IP地址。

  • 这些片子的大小和并行化的数量,并列出您可以提供的资源

  • 需要,如果部署间隔配置为20个5m,就可以在几个内查询,并且您可以在需要处理的分片日志

  • 或者,您可以发疯并设置 200 个查询器并处理 TB 的日志!

索引模式对比:
  • es 的大索引,不管你查不查询,他都必须时刻存在。比如长时间占用过多的内存

  • loki 逻辑是查询时再启动多个并行查询

日志量少时少加标签:
  • 因为每一个额外的额外的一个块

  • 例子,如果该查询是 {app=”loki”,level!=”debug”}

  • 在没加level标签的情况下只加载一个chunk 即app=“loki”的标签

  • 如果加了level的情况,则需要把level=info,warn,error,critical 5个chunk 都加载再查询

需要标签时再去添加:
  • 当 chunk_target_size=1MB 时代表以 1MB 的压缩大小来切割块

  • 原来的日志大小在5MB,如果日志max_chunk_age在10MB,可以达到10MB,可以考虑添加标签

应该按时间递增:
  • 这个和 tsdb 中处理旧数据是一样的道理

  • 目前 loki 为了性能考虑直接拒绝掉旧数据



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

c1702b0898e3ef58bc4b5d84ee712d28.png

已在知识星球更新源码解析如下:

49eece1e7680cd1a6259742b6a4cd7d0.jpeg

4a3f93067ce02de83c8c7ce5ab49bef2.jpeg

20ca1158db29ec5cc506f897a214e508.jpeg

706da9411ea716984b87de1d34bf6b47.jpeg

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值