← 文档目录

3 亿条 / 30 天规模测试

测试日期 2026-10-12 · 单机 6 核 11 GB 内存 · Osmanthe 网关 + VictoriaLogs v1.53.0 · 合成数据 · 以后每次规模测试都追加到这一页

3.0 亿写入条数(0 错误)
11.9 万/秒持续写入速率
41 分钟写入 2.95 亿条用时
26.8 GB磁盘占用(约 91 字节/条)
4.5 倍压缩比(相对原始 HEC JSON)
10 ms30 天 stats count(热)

一句话结论:3 亿条在这台小机器上写得进、存得下,每 10 分钟左右记录一次的累计平均速率基本不变。计数、按低基数字段统计、按字段精确查找都在毫秒到 2 秒内;但有 3 类查询在 30 天全量上不行:按高基数字段(带随机参数的 URL)分组会超内存失败,不写字段名的全文关键字搜索会超过 30 秒上限,去重计数 dc() 要 17–18 秒。这些是上 10 亿条之前要先解决的。

数据来源说明(2026-10-12 更正):

1. 测试环境和数据

项目值
机器6 核 CPU、11 GB 内存、3 GB swap、单块系统盘;测试开始时空闲磁盘 60.8 GB
部署docker compose(项目名 coding):网关 coding-gateway-1 + VictoriaLogs v1.53.0,均不设 CPU/内存限制;VictoriaLogs 保留期临时改为 31 天(原来 7 天)
数据生成tools/scale_test.py,在同一台机器上运行(与被测服务抢 CPU),5 个进程,每个 HTTP 请求 2000 条,走网关的 Splunk HEC 接口 /services/collector/event
租户专用租户 bench(account 4),不和 demo 数据混在一起
时间范围2026-09-12 16:07 到 2026-10-12 16:07 UTC,30 天均匀分布,每个进程按时间从旧到新写
数据内容80% nginx 访问日志(index=web,40 台主机,50 万用户,16 种状态码,30% 的 URL 带随机查询参数,每条一个随机 128 位 trace_id);20% 应用日志(index=app,6 个服务,5 个日志级别)。平均每条约 410 字节 JSON
条数正式写入 2.95 亿条,加上之前 3 次探测写入共 500 万条,bench 租户共 299,999,848 条(差的 152 条是探测数据中刚好落在 30 天外的)

2. 写入:速率和资源消耗

速率

阶段已写入平均速率网络流量
9 分钟6,492 万119,039 条/秒48.8 MB/s
20 分钟1.42 亿117,650 条/秒48.2 MB/s
30 分钟2.14 亿118,428 条/秒48.5 MB/s
40 分钟2.87 亿119,314 条/秒48.9 MB/s
全程 41.3 分钟2.95 亿119,155 条/秒48.8 MB/s(共 120.9 GB)

以上是累计平均(从开始到该时刻的总条数 ÷ 用时),来自运行时的进度输出。4 个累计平均值基本一致,说明没有明显的整体变慢;但累计平均会抹平短时波动,原始的逐时样本已丢失,无法确认每个时段的速率。汇总输出里失败 0 条、VictoriaLogs 丢弃 0 条(注意:当时的脚本遇到 HTTP 4xx 不会计入失败,这个缺陷已修;2026-10-12 复核:bench 租户全部时间范围内 index=web 240,003,566 条、index=app 59,996,434 条,合计正好 3.00 亿条,等于写入目标,说明没有漏写也没有重复;另有 1 条不带 index 的事件,来源不明,应是手工测试写入的)。网关只在 VictoriaLogs 确认写入后才返回成功,所以这是真正落盘的速率。

探测阶段:3 个进程 98,830 条/秒;5 或 6 个进程约 132,000 条/秒(短时间,200 万条)。再加进程不再变快,因为整机 CPU 已经用满。

资源消耗(运行时每 15 秒采样一次;样本文件已丢失,下表的平均值和峰值来自结束时打印的汇总)

指标平均峰值说明
整机 CPU5.3 核5.6 核6 核基本用满,是瓶颈
VictoriaLogs CPU3.4 核3.95 核压缩、建索引、合并
网关 CPU0.9 核1.2 核解析 HEC JSON、转发
数据生成器 CPU0.8 核—共 2056 CPU 秒;正式环境不存在这部分
VictoriaLogs 内存(进程本身)1.66 GB1.94 GB不含页缓存
VictoriaLogs 内存(含页缓存)5.8 GB7.6 GB页缓存可被系统回收
网关内存95 MB109 MB不随数据量增长
磁盘写28.4 MB/s117 MB/s峰值来自后台合并
磁盘读1.6 MB/s22.9 MB/s合并时读回

换算:每 1 核网关 CPU 约处理 13 万条/秒,每 1 核 VictoriaLogs CPU 约 3.5 万条/秒。这台机器如果不跑数据生成器,估计能到 13–14 万条/秒;要更快就要加核或把网关和存储分开部署。

3. 存储:磁盘和压缩

指标写入前写入后增加
VictoriaLogs 总条数(所有租户)1,161 万3.066 亿2.95 亿
数据卷实际占用(du)0.57 GB27.4 GB26.8 GB
压缩后数据0.55 GB27.4 GB26.8 GB
未压缩数据(VictoriaLogs 统计)3.3 GB128.2 GB124.9 GB
空闲磁盘60.8 GB33.8 GB−27.0 GB

4. 查询:19 条 SPL 的冷、热耗时

全部通过网关用 SPL 查询,时间范围以数据最后一条(10-12 16:07)为终点。“冷”是重启 VictoriaLogs 后第一次运行(清空了它自己的缓存,但系统页缓存还在,没有 root 权限清不掉;数据 27 GB 大于内存,所以大部分数据仍要从磁盘读);“热”是不重启再跑一轮、每条连跑 3 次的中位数。单位毫秒,含网关翻译和 HTTP 往返。数字是 2026-10-12 重跑的结果(原始文件见 scale-results/300m-queries-20261012/ 里的 query_cold.json、query_hot.json、query_samples.jsonl;最后两条不在脚本清单里的手工查询见 extra.json),和第一次跑的结果相差在 10% 以内。带 * 的是不重启时的第一次,不是冷启动。

查询SPL冷 ms热 ms结果
stats count,1 小时index=web | stats count161133.3 万
stats count,24 小时index=web | stats count178800 万
stats count,7 天index=web | stats count21135600 万
stats count,30 天全部* | stats count20103.0 亿
tstats 按 index 计数,30 天| tstats count where index=* by index37242 行
最新 100 条 500 错误,30 天index=web status=500 | head 100447203100 条
stats by status,24 小时index=web | stats count by status1057916 行
stats by status,30 天index=web | stats count by status1,6731,60516 行
timechart 1 小时粒度,7 天index=web status>=500 | timechart span=1h count429370168 点
timechart 按天 by status,30 天index=web | timechart span=1d count by status3,2903,24230×16
ERROR 按服务统计,30 天index=app level=ERROR | stats count by service4212826 行
where + eval + stats,24 小时index=web | where bytes > 80000 | eval kb=round(bytes/1024,1) | stats max(kb) as max_kb by host966540 行
dc(user) 去重计数,24 小时index=web | stats dc(user) as users99089650 万
dc(user) 去重计数,30 天index=web | stats dc(user) as users18,21317,14250 万
按字段找一个 trace_id,30 天index=web trace_id=50d337e9…489*682 条
全文找一个 trace_id(限定 index=web),30 天index=web 50d337e9…28,45227,7592 条
全文找一个 trace_id(不限 index),30 天50d337e9…>30,000>30,000超时
top uri_path,30 天index=web | top limit=10 uri_path8,1727,966失败
avg/p95 by uri_path,7 天index=web | stats avg(response_time) as avg, perc95(response_time) as p95 by uri_path7,8497,862失败

查询期间资源

怎么看这些数字

5. 发现的问题

问题现象原因建议
高基数字段分组失败top uri_path(30 天)和 stats … by uri_path(7 天)返回 400:“需要超过 2801 MB 内存”。top uri_path 1 天 1.1 秒、7 天 11 秒能成功30% 的 URL 带随机参数,30 天有约 7000 万个不同值;VictoriaLogs 单查询内存上限 = 可用内存 60% 的一部分,不会落盘1) 写入时把 URL 拆成路径和参数(Splunk 用户本来就常这么做);2) top 先按块近似取前 N;3) 给出能看懂的中文报错,提示缩短时间或换字段
全文关键字搜索慢、会超时限定 index=web 时 28–30 秒;不限 index 时超过 VictoriaLogs 默认 30 秒上限,网关返回 “storage unavailable”VictoriaLogs 没有按词的倒排索引,只靠每块的 bloom 过滤,随机值多时要扫全部数据1) 网关把超时翻译成“查询超时,请缩小时间范围或写字段名”;2) 文档引导用 字段=值;3) 评估给常查的 ID 类字段做专门索引(写入时建)
dc() 慢30 天 50 万个用户去重 17–18 秒精确去重,要扫全部 user 值提供近似去重(类似 Splunk 的 estdc)或按天预聚合
结果条数上限timechart 30 天 × 16 个状态码应有 480 行,测试脚本只取了 100 行测试脚本自己传了 limit=100,不是产品问题无需修改,记录以免误读

6. 10 亿条测试估算

项目按本次结果推算
磁盘约 91 GB(每条 91 字节);本机只剩 33.8 GB,放不下,需要先扩盘到 150 GB 以上(留合并空间)
写入时间同样配置约 2.3 小时(11.9 万条/秒);数据生成器放到另一台机器可缩短到约 2 小时
计数、tstats预计仍在 50 ms 以内
30 天 stats by 低基数字段约 5–6 秒
30 天 dc()、全文搜索会超过 30 秒上限,必须先做第 5 节的改进或拆成按天查询
内存写入时 VictoriaLogs 进程约 2 GB,不随数据量明显增长;高基数分组查询需要更多内存

建议:先做第 5 节的前两条改进(中文超时提示、URL 拆字段),扩盘后再跑 10 亿条,查询清单不变,结果追加到本页。

7. 怎么复现

# 1. 启动服务(保留期已是 31 天),起一个能读数据卷和指标的探针容器
docker compose -p coding -f deploy/docker-compose.yml up -d --build
docker run -d --name coding-probe --network coding_default \
    -v coding_vlogs:/vlogs:ro docker.io/library/alpine:3.20 sleep 172800

# 2. 写入(结果放 scale-results/,已在 .gitignore 里,不进仓库;不要放 /tmp)
#    有任何失败(HTTP 4xx、重试 8 次仍失败、条数不足)就以状态 1 退出
python3 tools/scale_test.py ingest --events 295000000 --days 30 \
    --workers 5 --out scale-results/300m

# 3. 查询:先冷后热;--end 填 ingest_summary.json 里 time_range 的第二个值
python3 tools/scale_test.py query --out scale-results/300m --restart --end 1791821241
python3 tools/scale_test.py query --out scale-results/300m --end 1791821241

输出:ingest_summary.json(ok 和 problems 字段表示是否全部成功;速率、前后磁盘、资源平均和峰值)、ingest_samples.jsonl(每 15 秒的样本)、query_cold.json、query_hot.json。CPU 和内存直接读容器的 cgroup,磁盘读写来自 /proc/diskstats,存储大小来自 VictoriaLogs 的 /metrics 和 du。

测试数据目前还留在 bench 租户(约 27 GB),31 天后自动过期;要提前删可以删 bench 租户的数据或整个数据卷。