
上周接了个现场改造一台 4 核 8G 的工控机要承担风力发电场的数据采集与存储。单台设备每秒产生一条运行记录一天下来大概 3000 多万个数据点原来那套 MySQL 方案在千万级行之后查询延迟直奔十几秒单表体积已经快把磁盘塞满。换分布式时序库吧三节点起配现场只有一台机器实在犯不上继续用 MySQL 硬扛下一批设备接入之后基本就是等死。就在这种大库太重、小库太少的尴尬里我找到了 KaiwuDB-Lite一个主打轻量化部署的时序数据库。这篇文章不打算写成产品说明书我想从实际项目角度聊聊KaiwuDB-Lite 到底解决什么问题、部署时有哪些关键决策、跑真实数据时表现如何以及我踩过的几个坑。如果你也在为边缘机、单机服务器或者中小规模的物联网时序数据发愁这篇应该能帮你省点弯路。1. 为什么单机场景反而最挑时序库1.1 那个不大不小的数据规模很多人觉得时序库是给大数据量准备的数据量小用 MySQL 就行。但在真实项目里最难受的反而是几千台设备以下的规模。简单算笔账每台设备每 5 秒上报一条数据一年产生的记录大约 630 万条。10 台设备就是 6300 万条这个量级 MySQL 还能勉强扛但一旦涉及聚合查询比如过去 30 天每台设备的平均温度SQL 里 group by 加上时间范围过滤走不上合适索引就直接全表扫描响应时间肉眼可见地变长。我在现场遇到的情况更麻烦一点设备是连续运行的数据没有平峰低谷存储必须稳定扛住持续写入。MySQL 的单表在千万级之后写入性能也会因为索引维护和行锁显著下滑。这时候你需要的是能高效处理时间范围 设备维度这类典型查询的存储引擎而不是一张张堆满历史数据的普通关系表。1.2 主流时序库在我这套环境里的现实问题决定换时序库之后我先把市面常见的几个方案过了一遍对比项InfluxDB单机TDengineTimescaleDBKaiwuDB-Lite部署复杂度中等单二进制需要 taosAdapter 等组件基于 PostgreSQL整体偏重单二进制解压即用内存占用默认配置偏大常驻 1G 以上中等视缓冲而定依赖 PostgreSQL 开销实测约 300M 左右SQL 支持类 SQL不是标准 SQL类 SQL完整 PostgreSQL兼容 PostgreSQL 协议写入协议InfluxDB 行协议自研协议适配器SQL同时支持 SQL 和 InfluxDB 行协议与 Grafana 集成原生支持通过插件通过 PostgreSQL两种路径都行InfluxDB 的老版本内存控制确实是个问题数据量上来之后如果没做 retention policy 和 continuous query磁盘和内存会同步告急TDengine 整体架构偏向集群化单机版虽然也能跑但周围配套组件对一台边缘工控机来说还不够轻TimescaleDB 本身很好但它是 PostgreSQL 扩展底子就不是为资源受限场景设计的4G 内存跑起来有点紧。1.3 KaiwuDB-Lite 出现在眼前的理由后来在开源社区翻到 KaiwuDB-Lite。先说结论它就是 KaiwuDB 的单机形态砍掉了分布式集群那套东西保留时序引擎本身。对于只有一台机器、又要时序能力、又希望操作习惯贴近传统数据库的场景这个定位非常对路。尤其吸引我的是两点。第一它对外提供 PostgreSQL 协议我的 DBA 同事不需要学一套新语法psql 连上去就能干活第二它同时支持 InfluxDB 行协议写入这意味着现场大量基于 Telegraf 采集的存量链路只要改一下写入地址就能无缝迁过来不用重写采集脚本。有了这两点我决定直接拿真实业务数据做一轮完整测试。2. Lite 到底砍了什么又保留了什么2.1 单机形态下的架构取舍开始之前我特意确认了 KaiwuDB-Lite 的定位。它跟 KaiwuDB 的分布式版本相比主要砍掉的是多节点协调、数据分片、跨节点查询这些能力。对于单机场景这些能力本来就用不上砍掉反而是好事——没有网络协调开销没有副本同步延迟资源全部留给本地读写。保留下来的是时序数据库最核心的几件事高效的列式存储、压缩、时间分区、标签索引以及完整的 SQL 查询能力。用一句话概括它把分布式的部分拿掉把数据库的部分留住了。2.2 存储与压缩数据量直接少了七成我的测试数据是用模拟程序生成的模拟 50 台设备连续上报电压、电流、温度三个指标数据点格式类似2025-06-01 00:00:00 设备A 220.5 12.3 45.6。原始 CSV 落盘约 2.1GB导入 KaiwuDB-Lite 之后磁盘占用只有大约 580MB压缩比接近 4:1。这个效果来自两方面的叠加。一是列式存储让同类型数据连续存放电压、电流、温度各自独立压缩数值型数据在列式存储里的重复模式远比行式存储明显二是时序数据天然适合压缩算法相邻时间点的数值往往只有小幅波动去掉不需要的精度后压缩效率更高。对于磁盘紧张的边缘设备来说这个收益是实打实的——意味着同样一块硬盘能存下原来三四倍的数据。2.3 标准 SQL 和时序函数的协同KaiwuDB-Lite 的 SQL 兼容性不是贴个标签而是真的能干活。我在测试里跑过嵌套子查询、窗口函数、JOIN 操作基本没有遇到语法阻碍。真正体现时序特性的还是它内置的时间处理函数比如 date_bin 用于将时间戳对齐到指定时间桶SELECT device_id, date_bin(5 minutes, ts, TIMESTAMP 2024-01-01) AS time_bucket, avg(temperature) AS avg_temp FROM sensor_data WHERE ts now() - INTERVAL 1 day GROUP BY device_id, time_bucket ORDER BY time_bucket;这条查询把一天的数据按 5 分钟粒度切片统计每台设备在每个时间桶内的平均温度。在 MySQL 里要写 DATE_FORMAT 然后手工对齐在 KaiwuDB-Lite 里就是一行函数的事。这种标准 SQL 时间语义的组合让后端开发几乎零成本上手。3. 下载、部署与首次启动的完整过程3.1 单机部署的三种姿势KaiwuDB-Lite 的部署方式很符合轻量的定位我实际尝试了三种姿势各有适用场景。第一种是直接下载官方二进制包解压后运行可执行文件。我当时拿到的社区版大约几十 MB解压到 /opt/kaiwudb-lite配置好数据目录就能启动。这种方式最适合跑测试和学习。第二种是使用 systemd 配置成系统服务。现场环境需要开机自启、崩溃自动拉起我把启动命令写进 systemd unit 文件配合日志轮转维护起来很省心。配置内容不复杂就是标准的 ExecStart、Restartalways 和 WorkingDirectory 指向数据目录。第三种是容器化部署。官方镜像可以直接用适合对交付一致性要求高的团队。不过我在现场工控机上没用容器因为那台机器资源有限不想再额外跑一层容器运行时。3.2 启动前必须确认的三个配置项部署过程中有两个容易忽略但影响很大的配置项这里单独拿出来说。第一是数据目录的磁盘空间。时序库的数据目录只增不减KaiwuDB-Lite 虽然有自动清理旧数据的保留策略但默认周期可能不是你想要的。我在测试环境里把保留周期调成了 90 天确保不超出磁盘容量。第二是内存上限。KaiwuDB-Lite 有几个和缓存、SQL 执行相关的内存参数如果用户不主动设置某些版本会使用操作系统可用内存的较大比例。在 4G 内存的工控机上我不希望它跟采集程序抢内存所以把 SQL 层内存和缓存都做了限制建议给时序库单独留出 1G 左右其余留给系统和其他进程。第三是监听地址。默认配置可能只监听本地回环地址 127.0.0.1现场需要接受局域网内采集盒子的写入必须手动把监听地址改成 0.0.0.0 或者具体的网卡地址。这个改完之后要马上确认防火墙状态否则外部请求根本进不来。3.3 客户端接入与初始化检查KaiwuDB-Lite 的对外协议是 PostgreSQL所以 psql 可以直接连接。默认端口在我当时的版本里是 26257连接命令大概是这样的psql -h 192.168.1.100 -p 26257 -U root -d defaultdb连接之后先跑几个基础查询确认服务正常比如查看当前版本、确认存储容量、列出所有数据库。第一次接触时序库的同学建议先做两步一是确认时区设置时序数据的时区错乱会造成聚合结果偏差二是设置一个足够大的 max_connections 或者保持默认因为后面接 Grafana、接采集脚本都会占用连接。这一步做实了后续的建表和写入就不会因为环境问题反复折腾。4. 建表、写入和查询的全流程实操4.1 表设计时间戳、标签和字段的分工时序数据的表设计思路和普通业务表有本质区别。业务表强调实体关系时序表强调一个时间点的一批指标。以我的测试表为例CREATE TABLE IF NOT EXISTS sensor_data ( ts TIMESTAMP NOT NULL, device_id VARCHAR(64) NOT NULL, voltage DOUBLE PRECISION, current DOUBLE PRECISION, temperature DOUBLE PRECISION, PRIMARY KEY (device_id, ts) );这里有个细节值得展开。多数传统数据库的主键设计习惯是唯一标识一条记录而时序表的主键通常由标签 时间戳组成原因是实际场景中同一设备同一时刻只会有一条记录。把 device_id 放在 ts 前面还符合时序库底层按标签维度组织数据的逻辑——同一设备的记录在物理存储上更紧凑查询时按设备过滤能直接落到连续数据块上。我在测试中也试过不带主键、完全由数据库自动生成记录 ID 的方式但后续按设备和时间范围做聚合查询时效率偏低。所以强烈建议建表时明确设计复合主键。4.2 写入测试从手动 INSERT 到批量导入建表后第一件事是单条写入验证链路。直接用 INSERT 语句插入一条模拟数据确认能正常返回、查询能查到说明连接和表结构都没问题。实际生产环境不可能一条条插我测试了几种批量方式。第一种是扩展 INSERT 语法一次插入多行比如一次插入 500 行到 1000 行网络往返次数大幅减少写入吞吐立刻上来。第二种是使用数据导入工具把 CSV 文件导入表适合初始化历史数据。第三种是走 InfluxDB 行协议接口用现成的 Telegraf 配置文件对准 KaiwuDB-Lite 的写入端点采集链路可以直接复用。实测下来单机环境使用批量 INSERT每批 5000 条记录左右持续写入可以达到每秒数万个数据点具体数值取决于 CPU 和磁盘能力。对 50 台设备、3 个指标、每秒一次的采集频率来说这个吞吐绰绰有余。4.3 查询实战降采样和保留策略时序查询的乐趣在于聚合。我在测试里专门验证了一个高频场景设备过去 24 小时的温度曲线。原始数据每秒一条画 24 小时曲线如果直接查原始点会非常密集可读性差、查询又慢。正确做法是先降采样按 5 分钟取平均值也就是前面展示过的那条 date_bin 查询。这类查询执行一次之后还可以进一步物化成定时任务的结果表让 Grafana 直接读预聚合表大幅降低查询延迟。KaiwuDB-Lite 的保留策略则可以自动删除超过 90 天的旧数据免去手工清理的麻烦。这套降采样 保留策略 物化结果的组合拳是时序库日常运营的核心路径。4.4 关于什么软件能访问松果时序数据库的说明前阵子在技术群里有人问某种叫松果时序的数据库该用什么客户端访问。这里我多说一句任何时序库的生态接入先看它对外暴露什么协议。如果走 PostgreSQL 协议那 psql、DBeaver、Navicat、Grafana 的 PostgreSQL 数据源都能直接连如果走 InfluxDB 行协议那 Telegraf、InfluxDB 的 SDK、Grafana 的 InfluxDB 数据源也都通用。我拿 KaiwuDB-Lite 的连接信息去试了试自家常用的几个工具基本是填上 IP、端口、用户名、数据库名就能通。这也是我选型时比较看重的——不希望某个库只能配它自家的客户端那是给自己找麻烦。5. 真实数据下的性能与资源占用5.1 测试环境与数据规模为了贴近现场我用的测试环境就是那台工控机4 核 CPU、8G 内存、普通 SATA SSD操作系统是 CentOS 7。测试数据模拟了 50 台设备、每台 3 个指标、持续 30 天的连续上报总数据点约 1.3 亿条。这样的数据规模在分布式时序库里根本算不上什么但对单机部署来说已经能说明不少问题。5.2 磁盘占用与写入吞吐导入完成后我检查了磁盘占用表文件合计约 580MB相比原始 CSV 的 2.1GB压缩比相当理想。写入吞吐方面使用批量 INSERT 请求数据点每秒稳定在 5 万到 8 万的区间峰值能达到 10 万以上。对边缘工控机来说这已经是超出预期的成绩。有一点需要提醒写入吞吐受 fsync 策略影响很大追求吞吐可以放宽磁盘同步策略但会降低异常断电时的数据安全性。生产环境建议保持默认别为了跑分牺牲可靠性。5.3 查询延迟表现我把线上常见的三类查询各跑了一遍。第一类是单设备最近一小时的原始数据返回 3600 条记录耗时在几十毫秒量级第二类是对全部设备做 24 小时聚合按 5 分钟分组计算均值数据量几十万行耗时在几百毫秒到一秒左右第三类是跨 30 天做设备维度的统计报表查询范围大、聚合层次深耗时数秒但通过预聚合表可以优化到秒级以内。整体来看KaiwuDB-Lite 在单机场景下的查询响应足以支撑中小规模的业务看板。基础设施运维相关的 Grafana 监控、能源数据的历史趋势、设备运行状态审计这类应用都能在秒回的水平上完成。6. 实战中踩过的几个坑6.1 内存参数默认值引发的重启第一次在工控机上启动 KaiwuDB-Lite 后跑了不到半天就发现服务进程消失系统日志显示 OOM。排查之后发现是内存相关配置用了默认值在 8G 机器上会尝试使用较大比例的可用内存结果和同机运行的采集程序争抢资源最终被系统杀掉。解决方式是显式设置内存上限把 SQL 执行内存和缓存相关的参数分别调到 512M 和 256M 左右并对 systemd 服务设置 MemoryLimit。之后持续运行一周内存占用稳定在 300M 附近再没出现被系统杀掉的情况。如果你也要在资源受限的机器上部署启动前第一件事就是确认内存配置。6.2 时间戳精度和时区问题导致的幽灵数据另一件印象深刻的事是时间戳错位。用 InfluxDB 行协议写入数据时客户端的时间戳精度不同默认解析精度也可能不同如果不显式声明会导致某些数据的时间被解释成了另一个时间。故障现象非常隐蔽写入时一切正常查询某个时间范围时却有个别数据点出现在完全无关的时间窗口。解决方法是所有写入端统一规定时间戳精度和时区比如统一使用毫秒时间戳、UTC 存储在查询端转换到北京时间展示。时序数据如果时区混乱任何聚合统计都是错的。这是我这次实战里最值得记住的一条。6.3 大批量数据导入时的小文件问题初版导入我是一次性分成多个小批次执行结果数据目录里产生了大量小文件。这样做的代价是后续查询的元数据开销变大。后来我改成合并成更大的批次、控制并发导入的线程数文件数量明显减少查询性能也有提升。在处理千万以上级别的历史数据回填时注意导入方式对底层文件布局的影响能减少很多后来才暴露的性能问题。7. 哪些场景适合选它哪些场景要慎重7.1 适合场景边缘服务器和中小规模物联网平台从这次实战体验来看KaiwuDB-Lite 最合适的场景就是单机部署的边缘节点以及数据量在千万到数亿点级别的中小规模平台。它占资源少、维护成本低、SQL 上手快现场工程师要查数据直接用数据库工具连上去写 SQL 就行不需要专门学一套查询语言。配电房采集、环境监测、楼宇自控、中小型产线这类现场往往只有一台服务器数据量没有大到需要分布式但单表查询必须快。KaiwuDB-Lite 正好卡在这个需求缺口上。运维也很顺畅升级就是换二进制备份就是拷贝数据目录很适合不太愿意折腾基础设施的小团队。7.2 不适合场景大规模集群和超高吞吐场景如果你要管理几十万台设备、每天产生几十亿个数据点或者需要跨地域多节点容灾那 KaiwuDB-Lite 就超出能力范围了应该去看完整版的 KaiwuDB 分布式方案或者其他分布式时序数据库。另外如果团队非常依赖 InfluxDB 特有的连续查询自动调度能力迁移前需要确认你用的版本是否具备等价功能我用的版本没有自动连续查询需要外部定时任务配合这个差异值得关注。7.3 我的几个运维习惯沉淀最后沉淀几条实际操作中的小习惯。一是定期做数据完整性抽查。时序库最容易出现写入丢点的问题我写了个小脚本每天统计各设备的数据点数和采集端的日志计数做对比超过阈值就告警。别过分相信采集端的上报成功响应真的会丢。二是控制单批次写入大小。KaiwuDB-Lite 支持很大的批量写入但批次太大会占用较多内存批次太小吞吐又上不去。我用下来 2000 到 5000 条一批比较顺滑大家可以按自己机器的性能做一个简单的梯度测试。三是建表前先想清楚数据生命周期提前规划好保留策略、降采样任务和预聚合表别让原始数据无限堆积。时序库虽然压缩率高但如果不做任何清理磁盘总会被写满。我把这套方案在两台现场机器上跑了一段时间数据采集链路稳定、Grafana 看板秒级刷新、运维告警也正常。如果你手头正好有一台机器存时序数据的需求KaiwuDB-Lite 值得花一个下午测一测至少它能帮你彻底告别千万行 MySQL 查询像蜗牛的老问题。