分桶:
文章插图
以天分割:bucketID = timestamp / secondsInDay 。
以小时分割:bucketID = timestamp / secondsInHour 。
分片:将不同日志流的索引分散到不同分片 , shard = seriesID% 分片数 。
Chunk 状态:Chunk 作为在 Ingester 中重要的数据单元 , 其在内存中的生命周期内分如下四种状态:
- Writing:正在写入新数据 。
- Waiting flush:停止写入新数据 , 等待写入到存储 。
- Retain:已经写入存储 , 等待销毁 。
- Destroy:已经销毁 。
状态转换时机:
- 协作触发:有新的数据写入请求 。
- 定时触发:刷写周期触发将 chunk 写入存储 , 回收周期触发将 chunk 销毁 。
- chunk 空间满(协作触发) 。
- chunk 的存活时间(首末两条数据时间差)超过阈值 (定时触发) 。
- chunk 的空闲时间(连续未写入数据时长)超过设置 (定时触发) 。
destroy , 被回收等待 GC 销毁:总体上 , Loki 由于针对日志的使用场景 , 采用了顺序追加方式写入 , 只索引元信息 , 极大程度上简化了它的数据结构和处理逻辑 , 这也为 Ingester 能够应对高速写入提供了基础 。
Querier:查询服务的执行组件 , 其负责从底层存储拉取数据并按照 LogQL 语言所描述的筛选条件过滤 。它可以直接通过 API 提供查询服务 , 也可以与 queryFrontend 结合使用实现分布式并发查询 。
⑥查询类型
查询类型如下:
- 范围日志查询
- 单日志查询
- 统计查询
- 元信息查询
并发查询:对于单个查询请求 , 虽然可以直接调用 Querier 的 API 进行查询 , 但很容易会由于大查询导致 OOM , 为应对此种问题 querier 与 queryFrontend 结合一起实现查询分解与多 querier 并发执行 。
文章插图
每个 querier 都与所有 queryFrontend 建立 grpc 双向流式连接 , 实时从 queryFrontend 中获取已经分割的子查询求 , 执行后将结果发送回 queryFrontend 。
具体如何分割查询及在 querier 间调度子查询将在 queryFrontend 环节介绍 。
⑧查询流程
先解析 logQL 指令 , 然后查询日志流 ID 列表 。
Loki 根据不同的标签选择器语法使用了不同的索引查询逻辑 , 大体分为两种:
= , 或多值的正则匹配=~ , 工作过程如下:
以类似下 SQL 所描述的语义查询出标签选择器里引用的每个标签键值对所对应的日志流 ID(seriesID)的集合 。
SELECT * FROM Table_N WHERE hash=? AND range>=? AND value=https://www.isolves.com/it/cxkf/bk/2020-12-23/labelValue
hash 为租户 ID(userID)、分桶(bucketID)、标签名(labelName)组合计算的哈希值;range 为标签值(labelValue)计算的哈希值 。将根据标签键值对所查询的多个 seriesID 集合取并集或交集求最终集合 。
比如 , 标签选择器{file="app.log", level=~"debug|error"}的工作过程如下:
- 查询出 file="app.log" , level="debug", level="error" 三个标签键值所对应的 seriesID 集合 , S1 、S2、S3 。
- 根据三个集合计算最终 seriesID 集合 S = S1∩cap (S2∪S3) 。
推荐阅读
- 运维日志分析工具ELK:Windows与Linux皆可安装
- 张震岳再见歌词介绍
- 腾讯游戏|再见了!腾讯《QQ堂》今日正式停运:运营17年终落幕
- 亿级 ELK 日志平台构建实践
- 掌握CSS3新特性,跟低效率说再见
- 再见HTML ! 用纯Python就能写一个漂亮的网页
- 日志系统新贵Loki,确实比笨重的ELK轻
- ELK有坑,千万别踩
- 高清多图 利用ELK分析Nginx日志生产实战
- 迅雷再见!在全球交友网站Github,找到的6款神软件