作者 | 浪子燕青燕小乙

来源 | https://zhuanlan.zhihu.com/p/371510010

总结下 loki 的优点

低索引开销

  • loki 和 es 最大的不同是 loki 只对标签进行索引而不对内容索引

  • 这样做可以大幅降低索引资源开销 (es 无论你查不查,巨大的索引开销必须时刻承担)

并发查询 + 使用 cache

  • 同时为了弥补没有全文索引带来的查询降速使用,Loki 将把查询分解成较小的分片,可以理解为并发的 grep

和 prometheus 采用相同的标签,对接 alertmanager

  • Loki 和 Prometheus 之间的标签一致是 Loki 的超级能力之一

使用 grafana 作为前端,避免在 kibana 和 grafana 来回切换

架构说明

Dubbo 3.0.0正式发布:应用级服务注册,跨语言的RPC协议、更好支持Kubernetes!

组件说明

promtail 作为采集器,类比 filebeat

loki 相当于服务端,类比 es

loki 进程包含 四种角色

  • querier 查询器

  • ingester 日志存储器

  • query-frontend 前置查询器

  • distributor 写入分发器

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

read path

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

  • 查询器将查询传递给所有 ingesters 请求内存中的数据。

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

  • 如果没有接收者返回数据,则查询器会从后备存储中延迟加载数据并对其执行查询。

  • 查询器将迭代所有接收到的数据并进行重复数据删除,从而通过 HTTP / 1 连接返回最终数据集。

write path

Spring Boot的各种漏洞,值得好好研究一番!

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

  • 每个流都使用散列环散列。

  • 分发程序将每个流发送到适当的 inester 和其副本(基于配置的复制因子)。

  • 每个实例将为流的数据创建一个块或将其追加到现有块中。每个租户和每个标签集的块都是唯一的。

  • 分发服务器通过 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

找一台 linux 机器做测试

安装 promtail

$ mkdir /opt/app/{promtail,loki} -pv# promtail配置文件
$ cat <<EOF> /opt/app/promtail/promtail.yaml
server:http_listen_port: 9080grpc_listen_port: 0positions:filename: /var/log/positions.yaml # This location needs to be writeable by promtail.client:url: http://localhost:3100/loki/api/v1/pushscrape_configs:- job_name: systempipeline_stages:static_configs:- targets:- localhostlabels:job: varlogs  # A `job` label is fairly standard in prometheus and useful for linking metrics and logs.host: yourhost # A `host` label will help identify logs from this machine vs others__path__: /var/log/*.log  # The path matching uses a third party library: https://github.com/bmatcuk/doublestar
EOF# 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: falseserver:http_listen_port: 3100grpc_listen_port: 9096ingester:wal:enabled: truedir: /opt/app/loki/wallifecycler:address: 127.0.0.1ring:kvstore:store: inmemoryreplication_factor: 1final_sleep: 0schunk_idle_period: 1h       # Any chunk not receiving new logs in this time will be flushedmax_chunk_age: 1h           # All chunks will be flushed when they hit this age, default is 1hchunk_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 firstchunk_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 disabledschema_config:configs:- from: 2020-10-24store: boltdb-shipperobject_store: filesystemschema: v11index:prefix: index_period: 24hstorage_config:boltdb_shipper:active_index_directory: /opt/app/loki/boltdb-shipper-activecache_location: /opt/app/loki/boltdb-shipper-cachecache_ttl: 24h         # Can be increased for faster performance over longer query periods, uses more disk spaceshared_store: filesystemfilesystem:directory: /opt/app/loki/chunkscompactor:working_directory: /opt/app/loki/boltdb-shipper-compactorshared_store: filesystemlimits_config:reject_old_samples: truereject_old_samples_max_age: 168hchunk_store_config:max_look_back_period: 0stable_manager:retention_deletes_enabled: falseretention_period: 0sruler:storage:type: locallocal:directory: /opt/app/loki/rulesrule_path: /opt/app/loki/rules-tempalertmanager_url: http://localhost:9093ring:kvstore:store: inmemoryenable_api: true
EOF# 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 数据源

在 grafana explore 上配置查看日志

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

超级任天堂模拟器 bsnes 开发者自杀(文末附模拟器及ROM)

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

深圳一普通中学老师工资单曝光,秒杀程序员

只索引标签

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

静态标签匹配模式

以简单的 promtail 配置举例

配置解读

scrape_configs:- job_name: systempipeline_stages:static_configs:- targets:- localhostlabels:job: message__path__: /var/log/messages
  • 上面这段配置代表启动一个日志采集任务

  • 这个任务有 1 个固定标签job="syslog"

  • 采集日志路径为 /var/log/messages , 会以一个名为 filename 的固定标签

  • 在 promtail 的 web 页面上可以看到类似 prometheus 的 target 信息页面

我来出个题:这些事务会不会回滚?大概率你会错!

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

  • {job="syslog"}

scrape_configs:- job_name: systempipeline_stages:static_configs:- targets:- localhostlabels:job: syslog__path__: /var/log/syslog- job_name: systempipeline_stages:static_configs:- targets:- localhostlabels:job: apache__path__: /var/log/apache.log
  • 如果我们配置了两个 job,则可以使用{job=~”apache|syslog”} 进行多 job 匹配

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

标签匹配模式的特点

原理

  • 和 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 中已经被验证过了

  • 属于开销低

  • 速度快

动态标签和高基数

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

两个概念

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

promtail 支持在 pipline_stages 中用正则匹配动态标签

  • 比如 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/20091221 Firefox/3.5.7 GTB6"
  • 在 promtail 中使用 regex 想要匹配 actionstatus_code两个标签

- job_name: systempipeline_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:- localhostlabels:job: apacheenv: 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"
  • 那四个日志行将变成四个单独的流,并开始填充四个单独的块。

  • 如果出现另一个独特的标签组合(例如 status_code =“500”),则会创建另一个新流

高基数问题

  • 就像上面,如果给 ip 设置一个标签,现在想象一下,如果您为设置了标签 ip,来自用户的每个不同的 ip 请求不仅成为唯一的流

  • 可以快速生成成千上万的流,这是高基数,这可以杀死 Loki

  • 所以为了避免高基数则应该避免使用这种取值分位太大的标签

如果字段没有被当做标签被索引,会不会导致查询很慢

Loki 的超级能力是将查询分解为小块并并行分发,以便您可以在短时间内查询大量日志数据

全文索引问题

  • 大索引既复杂又昂贵。通常,日志数据的全文索引的大小等于或大于日志数据本身的大小

  • 要查询日志数据,需要加载此索引,并且为了提高性能,它可能应该在内存中。这很难扩展,并且随着您摄入更多日志,索引会迅速变大。

  • Loki 的索引通常比摄取的日志量小一个数量级,索引的增长非常缓慢

那么如何加速查询没有标签的字段

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

{job="apache"} |= "11.11.11.11"

loki 查询时的分片 (按时间范围分段 grep)

  • Loki 将把查询分解成较小的分片,并为与标签匹配的流打开每个区块,并开始寻找该 IP 地址。

  • 这些分片的大小和并行化的数量是可配置的,并取决于您提供的资源

  • 如果需要,您可以将分片间隔配置为 5m,部署 20 个查询器,并在几秒钟内处理千兆字节的日志

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

两种索引模式对比

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

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

在日志量少的时候少加标签

  • 因为每多加载一个 chunk 就有额外的开销

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

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

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

在需要标签时再去添加

  • 当 chunk_target_size=1MB 时代表 以 1MB 的压缩大小来切割块

  • 对应的原始日志大小在 5MB-10MB,如果日志在 max_chunk_age 时间内能达到 10MB,考虑添加标签

日志应当按时间递增

  • 这个问题和 tsdb 中处理旧数据是一样的道理

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

往期推荐

Dubbo 3.0.0正式发布:应用级服务注册,跨语言的RPC协议、更好支持Kubernetes!

我来出个题:这些事务会不会回滚?大概率你会错!

警惕 Spring Boot Actuator 引发的安全问题

来活儿了!赶紧检查下代码里有没有脏话...

Windows 11,一个新功能,一场新屠杀!

喜欢本文欢迎转发,关注我订阅更多精彩

关注我回复「加群」,加入Spring技术交流群

不对全文内容进行索引的 Loki 到底优秀在哪里相关推荐

  1. 日志系统新贵,Loki到底优秀在哪里?

    点击关注公众号,利用碎片时间学习 总结下 loki 的优点 低索引开销 loki 和 es 最大的不同是 loki 只对标签进行索引而不对内容索引 这样做可以大幅降低索引资源开销 (es 无论你查不查 ...

  2. 写入文件python并用序号_Python和excel表合成示例:向表中添加序列号,向表的现有内容添加索引,与,Excel,表格,综合,实例,给,增加,序号,对,已有...

    Python 与 Excel 表格综合实例(一):给表格增加序号,根据表格已有内容增加索引 前言: 前面我们花了6篇博客,把Python的xlwt与xlrd两个第三方模块对Excel表格的基础操作讲完 ...

  3. Python 与 Excel 表格综合实例:给表格增加序号,对表格已有内容增加索引

    Python 与 Excel 表格综合实例(一):给表格增加序号,根据表格已有内容增加索引 前言: 需求一:增加序列号 需求二:按已有内容新增列 结尾: [Python与Office]专栏 前言: 前 ...

  4. 从 byte 数组中查找匹配内容的索引

    从 byte 数组中查找匹配内容的索引 在处理串口数据时,我们一般会这么处理: 先用一个缓存 byte 数组来缓存接收到的串口数据,然后在另一个处理线程中,再从缓存 byte 数组中查找特定标识(报文 ...

  5. 全文搜索引擎,索引库

    全文搜索引擎的工作原理理论上很简单,关键技术就是"分词", "索引库":使用分词技术把"文档数据"按分词拆分,也就是一个文档拆分为多个分词( ...

  6. 物权法全文内容有哪些呢-广告外链_网站SEO优化中,关键词内链与外链如何规划?...

    原创:白杨 全文2156字 预计阅读5分钟 大纲如下: 1.关键词是什么及分类说明 2.网站关键词内链如何规划布局? 3.网站关键词外链建设如何规划? 4.如何检测是否布局好? 关键词是什么及分类说明 ...

  7. 如何实现Word、PDF,TXT文件的全文内容检索?

    作者 | HENG 来源 | https://www.cnblogs.com/strongchenyu/p/13777596.html 简单介绍一下需求 能支持文件的上传,下载 要能根据关键字,搜索出 ...

  8. 如何实现Word、PDF、TXT文件的全文内容检索?

    简单介绍一下需求 能支持文件的上传,下载 要能根据关键字,搜索出文件,要求要能搜索到文件里的文字,文件类型要支持word,pdf,txt 文件上传,下载比较简单,要能检索到文件里的文字,并且要尽量精确 ...

  9. elasticsearch ingest-attachment 对于 word、pdf等文件内容的索引

    [转]ElasticSearch 全文检索实战 [转]ElasticSearch 5.3 载入PDF数据 1.简介 ElasticSearch只能处理文本,不能直接处理文档.要实现 ElasticSe ...

最新文章

  1. Javascript调试技巧整理
  2. Tomcat 的 catalina.out 日志分割
  3. linux dev_info,Linux命令集-xfs_info
  4. SQL注入之堆叠注入(sql-lab第38关)
  5. mysql启动主机挂了_docker 启动mysql 挂载宿主机目录
  6. php添加jpeg,PHP-如何将JPEG图像保存为渐进JPEG?
  7. Spring Boot实战:数据库操作
  8. pythonjava app切出后无网络连接_写了一个java的Server 用python的client访问却访问不通问题。...
  9. 广州.Net俱乐部第二次聚会报道
  10. linux驱动编写(虚拟字符设备编写)
  11. 小小的 Python 编程故事
  12. Primavera P6 数据字典分享
  13. adobe acrobat pro字体很怪,有点发虚,不整齐,调整方法
  14. MAC下学习UNIX网络编程
  15. 前端五个拿来就能用的炫酷动画登录页面
  16. 数字水印 改进的patchwork算法 实现
  17. 汉北地(安定、三水)属国
  18. 网络安全第一课--信息收集(一)
  19. 设置代理服务器(谷歌+IE)
  20. 2008系统更改计算机名,用Windows server 2008 R2更改计算机名的方法

热门文章

  1. js+jQuery获取全选并用ajax进行批量删除
  2. maven 学习笔记(一)eclipse+android+maven
  3. linux shell 判断文件 修改时间和系统时间差
  4. docker api 基本介绍和使用
  5. java Proxy.newProxyInstance 动态代理 简介
  6. centos7 yum 错误 This system is not registered with an entitlement server
  7. python3 中递归的最大次数
  8. suricata规则
  9. Linux System Programming --Chapter Nine
  10. Android 如何退出程序