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

推荐大家关注一个公众号

点击上方 "编程技术圈"关注, 星标或置顶一起成长

后台回复“大礼包”有惊喜礼包!

日英文

Sometimes you gotta accept the fact that certain things will NEVER go back to how they use to be. 

有时候你需要接受现实,有些事永远也回不去以前的样子了。

每日掏心话

每次遇见都会惊醒一个未知的自己,每个伤害都能炼狱成长。
责编:乐乐 | 来自:浪子燕青燕小乙链接:zhuanlan.zhihu.com/p/371510010

编程技术圈(ID:study_tech)第 1304次推文

往日回顾:腾讯员工吐槽:团队来了个阿里高p,瞬间会议变多,群多了

     

   正文   

总结下 loki 的优点
低索引开销loki 和 es 最大的不同是 loki 只对标签进行索引而不对内容索引这样做可以大幅降低索引资源开销 (es 无论你查不查,巨大的索引开销必须时刻承担)并发查询 + 使用 cache同时为了弥补没有全文索引带来的查询降速使用,Loki 将把查询分解成较小的分片,可以理解为并发的 grep和 prometheus 采用相同的标签,对接 alertmanagerLoki 和 Prometheus 之间的标签一致是 Loki 的超级能力之一使用 grafana 作为前端,避免在 kibana 和 grafana 来回切换架构说明Dubbo 3.0.0正式发布:应用级服务注册,跨语言的RPC协议、更好支持Kubernetes!
组件说明promtail 作为采集器,类比 filebeatloki 相当于服务端,类比 esloki 进程包含 四种角色
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 机器做测试
搜索公众号Java架构师技术后台回复“面试”,获取一份惊喜礼包。
安装 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  # 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: 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

# 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: 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 一样的标签匹配语句进行查询{job="syslog"}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,则可以使用{job=~”apache|syslog”} 进行多 job 匹配同时也支持正则和正则非匹配标签匹配模式的特点原理和 prometheus 一致,相同标签对应的是一个流 prometheus 处理 series 的模式prometheus 中标签一致对应的同一个 hash 值和 refid(正整数递增的 id),也就是同一个 series时序数据不断的 append 追加到这个 memseries 中当有任意标签发生变化时会产生新的 hash 值和 refid,对应新的 seriesloki 处理日志的模式 - 和 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 想要匹配 action和status_code两个标签- 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"
那四个日志行将变成四个单独的流,并开始填充四个单独的块。如果出现另一个独特的标签组合(例如 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 为了性能考虑直接拒绝掉旧数据你还有什么想要补充的吗?
PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。


版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

欢迎加入后端架构师交流群,在后台回复“学习”即可。

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。在这里,我为大家准备了一份2021年最新最全BAT等大厂Java面试经验总结。
别找了,想获取史上最简单的Java大厂面试题学习资料
扫下方二维码回复「面试」就好了


猜你还想看
阿里、腾讯、百度、华为、京东最新面试题汇集
优雅的阅读框架源码

历史上第一个网页它长啥样???

详解MQ消息队列及四大主流MQ的优缺点

嘿,你在看吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值