Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介
简介
Grafana Labs 简介
Grafana 是用于时序数据的事实上的仪表盘解决方案。它支持近百个数据源。
Grafana Labs 想从一个仪表盘解决方案转变成一个可观察性 (observability) 平台,成为你需要对系统进行调试时的首选之地。
完整的可观察性
可观察性。关于这意味着什么,有很多的定义。可观察性就是对你的系统以及它们的行为和表现的可见性。典型的是这种模式,即可观察性可以分成三个部分(或支柱):指标 (Metrics)、日志 (Logs) 和跟踪 (Traces);每个部分都相互补充,帮助你快速找出问题所在。
下面是在 Grafana Labs 博客和演讲中反复出现的一张图:

Slack 向我发出警告,说有问题,我就打开 Grafana 上服务的相关仪表盘。如果我发现某个面板或图表有异常,我会在 Prometheus 的用户界面中打开查询,进行更深入的研究。例如,如果我发现其中一个服务抛出了 500 个错误,我会尝试找出是否是某个特定的处理程序/路由抛出了这个错误,或者是否所有的实例都抛出了这个错误,等等。
接下来,一旦我有了一个模糊的心理模型,知道什么地方出了问题,我就会看一下日志(比如在 splunk 上)。在 Loki 之前,我习惯于使用 kubectl 来获取相关的日志,看看错误是什么,以及我是否可以做些什么。这对错误来说很有效,但有时我会因为高延迟而放弃。之后,我从 traces (比如 AppD) 中得到更多的信息,关于什么是慢的,哪个方法/操作/功能是慢的。或者使用 Jaeger 来获得追踪信息。
虽然它们并不总是直接告诉我哪里出了问题,但它们通常让我足够近距离地查看代码并找出哪里出了问题。然后,我可以扩展服务(如果服务超载)或部署修复。
Loki 项目背景
Prometheus 工作得很好,Jaeger 也渐入佳境,而 kubectl 也很不错。标签 (label) 模型很强大,足以让我找到出错服务的根源。如果我发现 ingester 服务在出错,我会做:kubectl --namespace prod logs -l name=ingester | grep XXX,以获得相关的日志,并通过它们进行 grep。
如果我发现某个特定的实例出错了,或者我想跟踪某个服务的日志,我必须使用单独的 pod 来跟踪,因为 kubectl 不允许你根据标签选择器来跟踪。这并不理想,但对于大多数的使用情况来说是可行的。
只要 pod 没有崩溃或者没有被替换,这就可以了。如果 pod 或节点被终止了,日志就会永远丢失。另外,kubectl 只存储最近的日志,所以当我们想要前一天或更早的日志时,我们是盲目的。此外,不得不从 Grafana 跳到 CLI 再跳回来的做法并不理想。我们需要一个能减少上下文切换的解决方案,而我们探索的许多解决方案都非常昂贵,或者不能很好地扩展。
这是意料之中的事,因为它们比 select + grep 做得更多,而这正是我们所需要的。在看了现有的解决方案后,Grafana Labs 决定建立自己的。
Loki
由于对任何开源的解决方案都不满意,Grafana Labs 开始与人交谈,发现很多人都有同样的问题。事实上,Grafana Labs 已经意识到,即使在今天,很多开发人员仍然在 SSH 和 grep/tail 机器上的日志。他们所使用的解决方案要么太贵,要么不够稳定。事实上,人们被要求减少日志,Grafana Labs 认为这是一种反模式的日志。Grafana Labs 认为可以建立一些 Grafana Labs 内部和更广泛的开源社区可以使用的东西。Grafana Labs 有一个主要目标:
- 保持简单。只支持 grep!

Grafana Labs 还瞄准了其他目标:
- 日志应该是便宜的。不应要求任何人少记录日志。
- 易于操作和扩展
- 指标 (Metrics)、日志 (Logs)(以及后来的追踪 (traces))需要一起工作
最后一点很重要。Grafana Labs 已经从 Prometheus 收集了指标的元数据,所以想利用这些元数据进行日志关联。例如,Prometheus 用 namespace、service name、实例 IP 等来标记每个指标。当收到警报时,使用元数据来找出寻找日志的位置。如果设法用同样的元数据来标记日志,我们就可以在度量和日志之间无缝切换。你可以在 这里 看到 Grafana Labs 写的内部设计文档。下面是 Loki 的演示视频链接:
架构
根据 Grafana Labs 建立和运行 Cortex 的经验--作为服务运行的 Prometheus 的水平可扩展的分布式版本--想出了以下架构:

指标和日志之间的元数据匹配对我们来说至关重要,Grafana Labs 最初决定只针对 Kubernetes。想法是在每个节点上运行一个日志收集代理,用它来收集日志,与 kubernetes 的 API 对话,为日志找出正确的元数据,并将它们发送到一个中央服务,可以用它来显示在 Grafana 内收集的日志。
该代理支持与 Prometheus 相同的配置(relabelling rules),以确保元数据的匹配。我们称这个代理为 promtail。
深入 Loki —— 可扩展的日志收集引擎:

写入路径和读取路径(查询)是相互脱钩的,分开说明:

Distributor(分发器)
一旦 promtail 收集并发送日志到 Loki,Distributor 是第一个接收日志的组件。现在,Loki 可能每秒收到数百万条写,我们不想在它们进来时就把它们写到数据库中。那会搞宕任何数据库。需要在数据进入时对其进行批处理和压缩。
Grafana Labs 通过构建压缩的数据块 (chunks),通过 gzip 压缩日志来实现这一点。ingester(采集器) 组件是一个有状态组件,负责构建块,然后再刷新块。Loki 有多个 ingester,属于每个流的日志应该总是在同一个 ingester 中结束,因为所有相关条目都在同一个块中结束。通过构建一个 ingester 环 (ring) 并使用一致性哈希来做到这一点。当有条目进入时,分 Distributor 对日志的标签进行哈希处理,然后根据哈希值查找将条目发送到哪个 ingester。

此外,为了实现冗余和弹性,Loki 将其复制了 n 次(默认为 3 次)。
Ingester(采集器)
现在,Ingester 将接收条目并开始构建块。

这基本上是对日志进行 gzip 处理并追加。一旦块 "填满 "了,我们就把它刷到数据库中。我们为块(ObjectStorage)和索引使用不同的数据库,因为它们存储的数据类型是不同的。

刷完一个块后,Ingester 会创建一个新的空块,并将新条目添加到该块中。
Querier(查询器)
读取路径非常简单,由 Querier 来完成大部分繁重的工作。给定一个时间范围和标签选择器,它查看索引以找出匹配的块,并通过它们进行搜索,给你结果。它还与 ingesters 对话,以获得尚未被刷到库中的最新数据。
请注意,在 2019 年版本中,对于每个查询,一个 Ingester 为你搜索所有相关的日志。Grafana Labs 已经在 Cortex 中使用前端实现了查询并行化,同样的方法可以扩展到 Loki,以提供分布式的 grep,这将使大型查询变得足够迅速。

可伸缩性
- Loki 把块的数据放到对象存储中,这样就可以扩展了。
- Loki 把索引放到 Cassandra/Bigtable/DynamoDB 或 Loki 内置的 index db 中,这也是可以扩展的。
- Distributors 和 Queriers 是无状态组件,可以横向扩展。
说到 ingester,它是一个有状态的组件,但 Loki 已经将完整的分片和重新分片的生命周期纳入其中。当 rollout 工作完成后,或者当 ingester 被扩大或缩小时,环形拓扑结构会发生变化,ingester 会重新分配它们的块,以匹配新的拓扑结构。这主要是取自 Cortex 的代码,它已经在生产中运行了 5 年多。
总结
Loki: like Prometheus, but for logs.
Loki 是一个水平可扩展、高可用、多租户的日志聚合系统,其灵感来自于 Prometheus。它被设计成非常具有成本效益和易于操作。它不对日志的内容进行索引,而是为每个日志流提供一组标签。
Grafana 系列文章
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介的更多相关文章
- 【视频】k8s套娃开发调试dapr应用 - 在6月11日【开源云原生开发者日】上的演示
这篇博客是在2022年6月11日的[开源云原生]大会上的演讲中的演示部分.k8s集群套娃(嵌套)是指在一个k8s的pod中运行另外一个k8s集群,这想法看上去很疯狂,实际上非常实用. k8s集群套娃( ...
- 云原生存储解决方案Rook-Ceph与Rainbond结合的实践
基础不牢,地动山摇.无论是何种体系架构,底层存储的选择都是一个值得探讨的话题.存储承载着业务的数据,其性能直接影响到业务应用的实际表现.也正因为存储和业务的数据关联紧密,其可靠性也必须得到关注,存储的 ...
- 全球首个开放应用模型 OAM 开源 | 云原生生态周报 Vol. 23
作者 | 临石.元毅.冬岛.衷源.天元 业界要闻 全球首个开放应用模型 OAM 开源 2019 年 10 月 17 日,阿里巴巴合伙人.阿里云智能基础产品事业部总经理蒋江伟(花名:小邪)在 Qcon ...
- NHibernate系列文章九:NHibernate对象二级缓存上
摘要 NHibernate的二级缓存由SessionFactory管理,由所有Session共享. NHibernate缓存读取顺序: 首先从一级缓存中读取,如果一级缓存对象存在,则读取一级缓存对象并 ...
- Node.js系列文章:利用console输出日志文件
通常我们在写Node.js程序时,都习惯使用console.log打印日志信息,但这也仅限于控制台输出,有时候我们需要将信息输出到日志文件中,实际上利用console也可以达到这个目的的,今天就来简单 ...
- 开源web终端ssh解决方案-gateone简介
好久都没来写博客,最近忙啥去了呢? 一是忙于saltstack的二次开发,二是云计算的学习研究中,所以就一直没写东西,今天给大家介绍个工具. 1. 首先来说一下为什么要 web ssh? 许多人不是说 ...
- 打造云原生大型分布式监控系统系列文章-腾讯工程师roc
附上本系列文章链接 打造云原生大型分布式监控系统(一): 大规模场景下 Prometheus 的优化手段 打造云原生大型分布式监控系统(二): Thanos 架构详解 打造云原生大型分布式监控系统(二 ...
- Clusternet:一款开源的跨云多集群云原生管控利器!
作者 徐迪,Clusternet 项目发起人,腾讯云容器技术专家. 摘要 Clusternet (Cluster Internet)是一个兼具多集群管理和跨集群应用编排的开源云原生管控平台,解决了跨云 ...
- 重磅 | 腾讯云服务网格开源项目 Aeraki Mesh 加入 CNCF 云原生全景图
作者 赵化冰,腾讯云工程师,Aeraki Mesh 创始人,Istio member,Envoy contributor,目前负责 Tencent Cloud Mesh 研发工作. 摘要 近日,腾讯云 ...
- 巨杉数据库加入CNCF云原生应用计算基金会,共建开源技术生态
近日,巨杉数据库正式加入全球顶级开源社区,云原生应用计算基金会 (Cloud Native Computing Foundation,以下简称CNCF),成为CNCF基金会会员,是中国最早加入的开源云 ...
随机推荐
- 说说switch关键字
Switch语法 switch作为Java内置关键字,却在项目中真正使用的比较少.关于switch,还是有那么一些奥秘的. 要什么switch,我有if-else 确实,项目中使用switch比较少的 ...
- JS数据结构与算法-栈结构
一.认识栈结构 栈也是一种非常常见的数据结构,并且在程序中的应用非常广泛 数组 我们知道数组是一种线性结构,并且可以在数组的任意位置插入和删除数据. 但是有时候,我们为了实现某些功能,必须对这种任意性 ...
- 【题解】UVA10228 A Star not a Tree?
题面传送门 解决思路 本题数据范围较小,可以使用模拟退火算法(随机化). 顾名思义,模拟退火就是一个类似于降温的过程.先设置一个较大的初温,每次随机改变状态,若使答案更优,则采取更优答案,否则根据其与 ...
- 直播CDN调度技术关键挑战与架构设计
作者:胡济麟 1.背景介绍 1.1 直播业务特点 互联网视频直播是一种消息媒介形态,提供时产时消的内容,经过多年,已经发展出秀场.游戏.电商.体育等多种业务形态.主要特点是:内容实时产生实时消费,对时 ...
- 【DL论文精读笔记】VGGNet
VGGNet(Very Deep Convolutional Networks) 1.introduction ● 采用3x3的小卷积核应用在比较深的网络里 ● 结果不错,赢得了2014 Imagen ...
- 网络编程:多进程实现TCP服务端并发、互斥锁代码实操、线程理论、创建线程的两种方式、线程的诸多特性、GIL全局解释器锁、验证GIL的存在
目录 多进程实现TCP服务端并发 互斥锁代码实操 线程理论 创建线程的两种方式 线程的诸多特性 GIL全局解释器锁 验证GIL的存在 GIL与普通互斥锁 python多线程是否有用 死锁现象 多进程实 ...
- C++ 动态规划:一维动态规划,背包问题,区间动态规划
C++ 动态规划 动态规划的定义 动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程.动态规划是一种在数学.管理科学.计算机科学.经济学和生物信息学 ...
- Codeforces Round #836 (Div. 2) A-D
比赛链接 A 题意 给一个字符串 \(s\) ,对其加倍,即每个字符后面追加一个相同字符. 加倍后可以重排列,要求构造一个回文串. 题解 知识点:构造. 既然可以重排列了,那顺序是随意的了,直接翻转加 ...
- pagehelper踩坑记之分页乱套
我们在使用数据库进行查询时,很多时候会用到分页展示功能,因此除了像mybatis这样的完善的orm框架之外,还有pagehelper这样的插件帮助减轻我们的工作. pagehelper的实现方式是,不 ...
- SSH(二)框架配置文件
在引入了宽假所需要的jar包后,引入相应配置文件. 一.Struts2的配置文件: 1.Struts2的黑心过滤器,在web.xml中引入: <!-- struts2框架的核心过滤器 clas ...