使用 k6 与 xk6-loki 对 Loki 日志查询(读路径)进行压测的完整指南
使用 k6 与 xk6-loki 对 Loki 日志查询读路径进行压测的完整指南【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki本篇技术指南围绕 Loki 读路径查询的负载测试展开讲解如何基于 Grafana k6 与 xk6-loki 扩展对 Loki 安装实例的五种查询类型instant、range、labels、label values、series进行压测。你将掌握每一种查询的 xk6-loki JavaScript API 用法、对应的 Loki HTTP 端点与底层实现原理、压测指标的含义以及如何通过标签池和查询比例配置构建接近真实场景的读路径压测脚本。前置准备构建带 xk6-loki 扩展的 k6xk6-loki是 k6 的扩展它充当 Loki 客户端既可向 Loki 推送日志也可从 Loki 查询日志从而模拟真实负载来测试 Loki 安装实例的可扩展性、可靠性与性能。在使用查询场景之前需要先构建一个包含该扩展的自定义 k6 二进制详见 k6 压测总览安装xk6扩展打包工具k6 使用 Go 编写需先准备好 Go 环境go install go.k6.io/xk6/cmd/xk6latest克隆grafana/xk6-loki仓库并进入目录git clone https://github.com/grafana/xk6-loki cd xk6-loki构建带扩展的 k6 二进制make k6构建完成后在压测脚本中通过import loki from k6/x/loki;导入模块。该模块暴露两个核心类ConfigClient的配置与Client读写 Loki 的客户端。Config和Client必须在 k6 的 init 上下文default 函数之外中实例化保证客户端只配置一次、并在所有 VU虚拟用户迭代间共享。Loki 读路径的五种查询类型在设计 Loki 读路径压测场景之前必须先明确你预期会遇到哪些类型的查询。Loki 一共有 5 种查询类型查询类型xk6-loki API对应 Loki HTTP 端点instant query瞬时查询instantQuery(query, limit)GET /loki/api/v1/queryrange query范围查询rangeQuery(query, duration, limit)GET /loki/api/v1/query_rangelabels query标签名查询labelsQuery(duration)GET /loki/api/v1/labelslabel values query标签值查询labelValuesQuery(label, duration)GET /loki/api/v1/label/name/valuesseries query序列查询seriesQuery(matcher, range)GET /loki/api/v1/series在真实场景中例如把 Loki 作为 Grafana 数据源进行查询这五类查询都会被用到且每一类都对应不同的 API 端点。xk6-loki 扩展为所有这些查询类型提供了对应的 JavaScript API。这些端点路径可以在仓库的查询路由实现中确认例如 pkg/querier/queryrange/codec.go 中注册了/loki/api/v1/query_range、/loki/api/v1/series、/loki/api/v1/query以及/loki/api/v1/label/{name}/values等路径pkg/loghttp/versions_test.go 中的测试也验证了这些路径归属于VersionV1API 版本。Instant query瞬时查询瞬时查询返回单个时间点上的查询结果通过loki.Client实例上的instantQuery(query, limit)函数执行其中limit为可选参数export default () { client.instantQuery(rate({appmy-app-name} | logfmt | levelerror [5m])); }从源码实现看瞬时查询走的是 QuerierAPI 的InstantQueryHandler见 pkg/querier/http.go。值得注意的一个细节是该处理器只允许指标查询SampleExpr不允许纯日志选择器表达式作为瞬时查询否则会返回ErrUnsupportedSyntaxForInstantQuery错误。因此在编写瞬时查询压测语句时应使用rate()、count_over_time()这类聚合/范围向量表达式而不是裸的{app...}日志选择器。Range query范围查询范围查询返回一个时间区间内的查询结果通过rangeQuery(query, duration, limit)执行duration用于指定查询的时间跨度limit为可选参数export default () { client.rangeQuery({appmy-app-name} | logfmt | levelerror, 15m); }范围查询对应的处理函数是RangeQueryHandler见 pkg/querier/http.go它是压测中最接近 Grafana 仪表盘真实查询形态的一类请求。Labels query标签名查询标签名查询返回某个时间范围内出现的所有标签名通过labelsQuery(duration)执行export default () { client.labelsQuery(10m); }Label values query标签值查询标签值查询返回指定标签在某个时间范围内的取值通过labelValuesQuery(label, duration)执行export default () { client.labelValuesQuery(app, 10m); }在 Loki 服务端标签名查询与标签值查询都由LabelHandler处理见 pkg/querier/http.go其底层通过querier.Label()查询索引并使用logql.QueryTime中QueryTypeLabels类别的计时器记录耗时。Series query序列查询序列查询返回与某个标签匹配器匹配的时间序列列表通过seriesQuery(matcher, range)执行export default () { client.seriesQuery(match[]{app~loki-.*}, 10m); }注意示例中match[]前缀用于传递标签匹配器。服务端对应的处理函数是SeriesHandler见 pkg/querier/http.go其注释明确说明该端点返回“匹配特定标签集的 time series 列表”并引用 Prometheus 的 Finding series by label matchers API 语义。压测指标Metricsxk6-loki 扩展会额外收集以下指标并打印在 k6 测试结束时的 end-of-test summary 中与 k6 内置指标并列展示。这些指标仅为 instant query 和 range query 收集指标名称说明loki_bytes_processed_per_secondLoki 每秒处理的字节数loki_bytes_processed_totalLoki 处理的字节总数loki_lines_processed_per_secondLoki 每秒处理的行数loki_lines_processed_totalLoki 处理的行总数这些指标来自 Loki 查询响应中携带的统计信息stats直接反映读路径上 Loki 实际扫描与处理的数据量是评估查询压测是否真正打满存储与计算资源的关键依据。标签池Labels poolxk6-loki 允许你在Config对象上使用labels字段它包含以可复现方式生成的标签名与标签值集合。压测时应保证write写入测试与read读取测试使用相同的标签基数配置这样才能保证读路径压测命中的流streams确实存在于被压测的 Loki 实例中压测结果才具有真实参考意义。JavaScript 示例代码片段const labelCardinality { app: 5, namespace: 2, }; const conf new loki.Config(BASE_URL, 10000, 1.0, labelCardinality); const client new loki.Client(conf); function randomChoice(items) { return items[Math.floor(Math.random() * items.length)]; } export default() { let app randomChoice(conf.labels.app); let namespace randomChoice(conf.labels.namespace); client.rangeQuery({app${app}, namespace${namespace}} | logfmt | levelerror, 15m); }这里new loki.Config(BASE_URL, timeout, ratio, labelCardinality)的第二个参数是请求超时毫秒第三个参数是 Protobuf 编码请求占比0.0~1.0默认 0.9详见 log-generation.md第四个参数即标签基数。由于标签值是确定性地生成每次压测产生相同的标签名与取值组合从而保证测试可复现、可对比。除此之外你也可以自定义自己的标签名与标签值池然后从自己的池中随机选择标签而不是使用生成的池。这在高保真模拟生产环境标签分布时非常有用。需要提醒的是不同标签值的笛卡尔积决定了活跃流streams的总量标签基数过高会对 Loki 实例性能产生负面影响详见 log-generation.md 中的标签说明压测时应从较小的基数起步。综合读场景按比例混合五种查询在 xk6-loki 仓库中提供了一个更完整的读场景示例read-scenario.js测试文件可直接复用并扩展。它允许你为每种查询类型配置比例也可以配置时间范围的比例。JavaScript 示例const queryTypeRatioConfig [ { ratio: 0.1, item: readLabels }, { ratio: 0.15, item: readLabelValues }, { ratio: 0.05, item: readSeries }, { ratio: 0.5, item: readRange }, { ratio: 0.2, item: readInstant }, ];在上述配置下一次压测运行期间大约会执行10% 的 labels 请求15% 的 label values 请求5% 的 series 请求50% 的 range 查询20% 的 instant 查询这种按比例混合的方式能很好地模拟 Grafana 面板加载、变量刷新、日志流切换等真实交互行为——例如 Grafana 变量下拉框会触发 labels 与 label values 查询日志浏览与面板会触发 range/instant 查询。你可以参考 write-scenario.md 中的完整脚本骨架包含ramping-vus场景、thresholds、check断言等要素将上述比例配置嵌入其中构建读写一体的压测流程。压测实战建议明确目标查询画像压测前先梳理你的 Grafana 数据源或其他客户端实际发出的查询构成类型占比、时间范围、标签基数再据此设置queryTypeRatioConfig避免只压单一查询类型导致结论失真。控制标签基数从少量标签值起步例如app5 个、namespace2 个确认集群能承受后再逐步放大因为高基数标签会显著影响索引与查询性能。关注处理指标而非仅看延迟loki_bytes_processed_per_second与loki_lines_processed_per_second能直观反映读路径实际吞吐结合 k6 内置的http_req_duration、http_req_failed等指标才能全面评估查询性能与稳定性。读写压测保持一致读路径命中的流必须由写路径产生务必让 read 与 write 测试共享相同的labelCardinality配置必要时可先运行写场景预热数据再进行读场景压测。VU 数量与资源匹配与写路径类似读路径压测中 VU 数量决定了并发查询压力可根据 k6 工作机 CPU 核数经验上 1~1.5 倍核数设置 VU 上限避免压测机自身成为瓶颈详见 write-scenario.md 的讨论。通过上述方法你可以在本地或 CI 环境中复现接近真实的查询负载系统性地评估 Loki 读路径在预期查询画像下的吞吐、延迟与资源消耗为容量规划与性能调优提供可靠依据。【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

MT管理器:安卓文件管理神器,APK编辑与局域网传输实战详解

MT管理器:安卓文件管理神器,APK编辑与局域网传输实战详解

我用安卓手机这么多年,折腾过不少花样,最离不开的其实就是一两个趁手的工具。今天想聊的这款文件管理工具,圈内人称“MT管理器”,在玩机党眼里它早就是标配了,但如果你只是把它当成一个普通的“看文件”App&#xff0c…

2026/10/26 10:15:57 阅读更多 →
基于SpringBoot+SSM的课程评价管理系统设计与实现全解析

基于SpringBoot+SSM的课程评价管理系统设计与实现全解析

做课程评价管理系统,不管是本科毕设还是课程设计,用JavaSpringBootSSM这套技术栈去实现,在我接触到的学生项目里几乎是最常见的组合了。它覆盖面广、资料多、面试还能拿去讲,最关键的是这套系统本身业务脉络清楚,既有用…

2026/10/25 12:35:03 阅读更多 →
qwen-code Headless Fork Subagents:让无头场景完整继承父会话上下文的统一 Fork 派发设计

qwen-code Headless Fork Subagents:让无头场景完整继承父会话上下文的统一 Fork 派发设计

qwen-code Headless Fork Subagents:让无头场景完整继承父会话上下文的统一 Fork 派发设计 【免费下载链接】qwen-code An open-source AI coding agent that lives in your terminal. 项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code 导读 本…

2026/10/26 10:16:07 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →