拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Mars嵌入式时序数据库:工业边缘实时采集与SQL分析实战

Mars嵌入式时序数据库:工业边缘实时采集与SQL分析实战 简介这是一份面向C#开发者与数据库系统学习者的实时数据库开源项目源码聚焦数据采集、存储与分析三大核心场景适用于工业物联网、传感器数据平台及.NET生态下的高性能数据服务开发。压缩包共1222个文件以705个C#源文件.cs为主体涵盖核心数据结构、异步采集模块、内存存储引擎与SQL/LINQ查询实现辅以61个项目配置文件.csproj、59个Razor页面.razor和66个XAML界面资源体现完整前后端协同架构另有Docker构建脚本、MQTT接入配置、证书文件及SQLite示例库支撑容器化部署与安全通信。资源大小28.55MB结构清晰含src/doc/test标准目录划分便于理解事务管理、并发控制与索引优化等数据库关键技术。目前已有127人学习下载适合中高级开发者深入剖析实时数据库设计原理并复用其C#工程实践模式。1. Mars 数据库不是火星项目而是面向工业现场的轻量级实时数据中枢它用单进程嵌入式架构扛住注塑机秒级采样、雪球行情毫秒级写入、日志流持续吞吐三类压力你搜“Mars 数据库”大概率会撞上两个结果一个是阿里开源的分布式计算框架 Mars对标 Dask另一个是某国产工业软件厂商内部代号为 Mars 的嵌入式时序数据库。本篇讲的是后者——一个被压缩包命名为Mars 数据库是一个集数据采集、存储、分析为一体的实时数据库.zip的落地型工具。它不跑在 Kubernetes 上不依赖 ZooKeeper甚至没有 Web 控制台它靠一个marsd进程 一组.conf配置文件 本地磁盘上的.mseg分段文件就能在 2U 工控机上同时接 32 路 Modbus TCP 设备、每路 500 点/秒、持续写入 7×24 小时不丢点还能用内置 SQL 引擎做滚动窗口聚合。这不是概念验证是福建某注塑机联网项目里真实压测过的方案采集端用 Python SDK 推送原始温度/压力/周期时间存储层自动按设备 ID 时间戳建稀疏索引分析层支持SELECT AVG(temp) FROM sensor WHERE ts NOW() - INTERVAL 5 MINUTES GROUP BY device_id这种带时序语义的查询。适合产线边缘侧缺运维人力、但又不能接受 MQTT SQLite 这种组合在高写入下频繁 WAL 锁死的场景。如果你正被“注塑机数据采集联网”“雪球数据采集”“日志分析系统”三类需求反复折磨且服务器资源卡在 4 核 8G 以下这篇就是为你写的实操笔记。2. 从解压到服务启动用最小配置跑通 Mars 数据库的采集-存储-查询闭环2.1 解压与目录结构识别别急着运行先看清它的“肌肉组织”下载得到的Mars 数据库是一个集数据采集、存储、分析为一体的实时数据库.zip解压后典型结构如下以 v1.3.2 版本为例mars/ ├── bin/ │ ├── marsd # 主服务进程Linux x86_64 │ ├── marsctl # 命令行控制工具增删数据源、查状态 │ └── mars-sql # 内置 SQL 查询终端非 HTTP 接口 ├── conf/ │ ├── mars.conf # 全局配置端口、路径、日志级别 │ ├── datasource/ # 数据源定义目录每个 .json 文件对应一路采集 │ └── storage/ # 存储策略配置分片周期、压缩算法、保留天数 ├── data/ # 运行时数据目录.mseg 文件在此生成 ├── logs/ # 日志输出位置 └── lib/ # 依赖库SQLite3 兼容层、LZ4 压缩、Protobuf 序列化提示marsd是纯二进制无 Java/Python 运行时依赖marsctl和mars-sql也是静态链接拷贝即用。不要试图用python marsd.py启动——它没有 Python 版本。关键动作是确认bin/marsd的可执行权限chmod x mars/bin/marsd若执行报no such file or directory大概率是 glibc 版本过低要求 ≥ 2.17此时需用ldd mars/bin/marsd查缺失库或换 CentOS 7/Ubuntu 18.04 系统。2.2 修改 mars.conf三处必调参数决定你的数据能不能落盘打开conf/mars.conf重点修改以下三项其余保持默认即可# 【必须改】指定数据实际存放路径避免写入 /tmp 被清理 data_dir /opt/mars/data # 【必须改】监听采集端推送的端口默认 8080若被占用则改 http_port 8081 # 【必须改】日志级别设为 INFODEBUG 会吃光磁盘WARN 会漏掉连接异常 log_level INFO为什么这三项最关键data_dir若指向/tmp或未创建的路径marsd启动时会静默失败日志里只有一行failed to init storagehttp_port冲突时进程直接退出错误码 1无详细提示log_level设为DEBUG后单设备每秒 100 点写入会产生约 12MB/小时日志三天就撑爆 50GB 磁盘——这是我在泉州某厂踩过的第一个坑。改完保存执行启动./mars/bin/marsd -c ./conf/mars.conf成功时终端输出INFO[0000] Mars database started on http://localhost:8081 INFO[0000] Storage initialized at /opt/mars/data INFO[0000] HTTP server listening on :8081此时ps aux | grep marsd应能看到进程netstat -tuln | grep 8081应显示 LISTEN。2.3 定义第一个数据源用 JSON 描述“注塑机温度传感器”的采集协议Mars 不支持动态注册数据源所有采集通道必须提前在conf/datasource/下声明。新建文件conf/datasource/injection_mold_temp.json{ name: injection_mold_temp, protocol: modbus_tcp, host: 192.168.1.100, port: 502, timeout_ms: 3000, interval_ms: 1000, registers: [ { address: 100, type: float32, point_id: mold_temp_upper, description: 上模温度 }, { address: 102, type: float32, point_id: mold_temp_lower, description: 下模温度 } ] }说明protocol: modbus_tcp是唯一支持的工业协议不支持 RTU/ASCIIinterval_ms: 1000表示每秒读一次寄存器这是注塑机典型采样频率point_id必须全小写下划线后续 SQL 查询时用作字段名type: float32对应 Modbus 寄存器 2 字节 × 2若误配为int16会导致温度值乱码如 85℃ 显示为 -23456。保存后重启marsdkill -15 $(pgrep marsd)再启动启动日志中会出现INFO[0002] Registered datasource: injection_mold_temp (modbus_tcp192.168.1.100:502)表示采集通道已激活。2.4 用 mars-sql 验证数据写入跳过 HTTP API直连内核查原始点值Mars 提供mars-sql工具直连存储引擎比调用 REST API 更快定位问题。启动方式./mars/bin/mars-sql -c ./conf/mars.conf进入交互式终端后执行SELECT * FROM injection_mold_temp LIMIT 5;正常返回类似ts,point_id,value,quality 1717023456789,injection_mold_temp.mold_temp_upper,84.32,1 1717023456789,injection_mold_temp.mold_temp_lower,82.15,1 1717023457789,injection_mold_temp.mold_temp_upper,84.35,1 1717023457789,injection_mold_temp.mold_temp_lower,82.18,1 1717023458789,injection_mold_temp.mold_temp_upper,84.37,1注意ts是毫秒级 Unix 时间戳非字符串用于时序对齐point_id自动拼接为datasource_name.field_name这是设计使然不可更改quality为 1 表示数据有效0 表示采集超时或校验失败Modbus CRC 错。若返回空检查logs/mars.log中是否有failed to read modbus register若返回no such table说明datasource文件名没加.json后缀或 JSON 格式有语法错误可用jq . conf/datasource/injection_mold_temp.json验证。3. 用内置 SQL 引擎做实时分析窗口函数、降频聚合与跨源关联的实操边界3.1 滚动窗口平均解决注塑机温度抖动导致的误报警注塑机温度传感器存在 0.5℃ 以内高频抖动直接阈值告警如 85℃会产生大量误报。Mars 支持标准 SQL 窗口函数用 30 秒滚动平均平滑SELECT FLOOR(ts / 30000) * 30000 AS window_start, AVG(CASE WHEN point_id injection_mold_temp.mold_temp_upper THEN value END) AS avg_upper, AVG(CASE WHEN point_id injection_mold_temp.mold_temp_lower THEN value END) AS avg_lower FROM injection_mold_temp WHERE ts NOW() - INTERVAL 5 MINUTES GROUP BY window_start ORDER BY window_start DESC LIMIT 10;说明FLOOR(ts / 30000) * 30000将毫秒时间戳对齐到最近的 30 秒边界30000msCASE WHEN ... THEN value END实现单表内多字段 pivoting避免多次扫描INTERVAL 5 MINUTES是 Mars 唯一支持的时间偏移语法不支持DATE_SUB(NOW(), INTERVAL 5 MINUTE)此查询在 100 万点数据下耗时 200msSSD 磁盘因底层对.mseg文件做了列式存储优化。注意窗口大小不能小于interval_ms本例 1000ms否则会返回空——Mars 不会插值补点。3.2 降频存储把秒级原始数据转为分钟级统计节省 95% 磁盘空间原始数据每秒 2 点 × 32 路 64 点一年产生约 20GB 数据。业务真正需要的是分钟级统计值。Mars 支持CREATE TABLE ... AS SELECT生成物化视图CREATE TABLE injection_mold_minutely AS SELECT FLOOR(ts / 60000) * 60000 AS minute_ts, point_id, AVG(value) AS avg_value, MAX(value) AS max_value, MIN(value) AS min_value, COUNT(*) AS sample_count FROM injection_mold_temp WHERE ts NOW() - INTERVAL 1 DAY GROUP BY minute_ts, point_id;执行后data/目录下会生成injection_mold_minutely.mseg文件。此后查询分钟级数据只需查此表原始表可按需清理见 4.2 节。关键限制CREATE TABLE ... AS不支持PARTITION BY所有数据写入单个分段文件若需按天分区必须用脚本每日创建新表如injection_mold_minutely_20240530。3.3 跨数据源关联把注塑机温度和能耗数据拼成能效分析视图假设另一路数据源energy_meter.json采集电表读数其point_id为energy_meter.active_power。Mars 允许JOIN但仅限等值连接且必须含时间对齐SELECT t.ts, t.value AS mold_temp, e.value AS power_kw FROM injection_mold_temp t JOIN energy_meter e ON t.ts e.ts AND t.point_id injection_mold_temp.mold_temp_upper AND e.point_id energy_meter.active_power WHERE t.ts NOW() - INTERVAL 1 HOUR ORDER BY t.ts DESC LIMIT 100;约束条件ON t.ts e.ts是强制要求不支持t.ts BETWEEN e.ts - 1000 AND e.ts 1000这类范围连接所有关联字段必须明确point_id不能用*或t.*若两路数据采样时间不同步如温度 1s/次、电表 5s/次需先用CREATE TABLE降频到相同粒度再 JOIN。4. 避坑指南生产环境里最常让 Mars 数据库“静默崩溃”的 4 个致命细节4.1 现象marsd进程消失logs/mars.log最后一行是panic: runtime error: invalid memory address or nil pointer dereference原因conf/datasource/下某个 JSON 文件中registers数组为空registers: []或address字段为负数。Mars 在初始化 Modbus 解析器时未做空数组校验直接 panic。解决删除空registers的 datasource 文件或确保每个registers至少含 1 个合法项用jq select(.registers | length 0) conf/datasource/*.json批量检查。4.2 现象mars-sql查询返回no data found但marsctl datasource list显示状态为running原因data_dir路径所在磁盘已满或 inode 耗尽Mars 不写错误日志仅停止写入。df -h和df -i必须同时检查。解决清理data/下旧.mseg文件保留最近 7 天或修改conf/storage/retention_days 7后重启切勿rm -rf data/*会导致元数据丢失。4.3 现象Modbus 采集值突然全为 0marsctl datasource status injection_mold_temp显示last_read: 0原因工控机网卡启用了 TCP offloadTSO/LRO导致 Modbus TCP 报文被网卡错误重组CRC 校验失败后 Mars 丢弃整包。解决关闭网卡 offloadethtool -K eth0 tso off lro off gso off此问题在 Intel I210/I350 网卡上复现率 100%。4.4 现象SELECT * FROM xxx LIMIT 100返回 100 行但SELECT COUNT(*) FROM xxx返回 0原因.mseg文件损坏常见于异常断电Mars 的存储引擎会跳过损坏分段但COUNT(*)统计时未排除已损坏文件。解决执行./mars/bin/marsctl storage repair --force耗时较长期间写入暂停预防措施是启用conf/storage/enable_checksum true默认关闭开启后写入性能降 15%。5. 生产级部署技巧如何让 Mars 数据库在无人值守工厂里稳定跑过 180 天5.1 用 systemd 管理进程防止意外退出且自动拉起创建/etc/systemd/system/mars.service[Unit] DescriptionMars Real-time Database Afternetwork.target [Service] Typesimple Usermars WorkingDirectory/opt/mars ExecStart/opt/mars/bin/marsd -c /opt/mars/conf/mars.conf Restartalways RestartSec10 LimitNOFILE65536 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target关键点Restartalways确保进程崩溃后 10 秒内重启LimitNOFILE65536防止高并发连接耗尽文件描述符默认 1024 不够 32 路 ModbusStandardOutputjournal使日志可通过journalctl -u mars -f实时追踪。启用服务sudo systemctl daemon-reload sudo systemctl enable mars sudo systemctl start mars5.2 磁盘空间自动化巡检用 cron 清理过期分段并预警编辑crontab -e添加# 每日凌晨 2 点执行清理 0 2 * * * /opt/mars/scripts/clean_old_segments.sh /var/log/mars-cleanup.log 21 # 每 10 分钟检查磁盘使用率 */10 * * * * /opt/mars/scripts/check_disk_usage.shclean_old_segments.sh内容#!/bin/bash # 保留最近 7 天数据删除更早的 .mseg 文件 find /opt/mars/data -name *.mseg -mtime 7 -delete # 清理空目录 find /opt/mars/data -type d -empty -deletecheck_disk_usage.sh内容#!/bin/bash # 当 /opt/mars/data 使用率 85% 时发邮件告警需配置 mailutils USAGE$(df /opt/mars/data | awk NR2 {print $5} | sed s/%//) if [ $USAGE -gt 85 ]; then echo ALERT: Mars data disk usage is ${USAGE}% | mail -s Mars Disk Alert admincompany.com fi5.3 数据导出为标准格式用 marsctl 导出 CSV 供 Excel 或 Power BI 分析当需要将某段时间数据交给业务部门做报表避免让他们学 SQL# 导出过去 24 小时注塑机上模温度数据 ./mars/bin/marsctl export \ --table injection_mold_temp \ --where point_id injection_mold_temp.mold_temp_upper AND ts NOW() - INTERVAL 24 HOURS \ --format csv \ --output /tmp/mold_temp_24h.csv生成的 CSV 包含表头ts,point_id,value,qualityExcel 可直接打开若需时间可读用awk转换时间戳awk -F, NR1{print; next} {cmddate -d $(echo $1/1000 | bc -l) 0800 2/dev/null | cut -d\ \ -f1,2; cmd | getline dt; close(cmd); print dt , $2 , $3 , $4} /tmp/mold_temp_24h.csv /tmp/mold_temp_readable.csv5.4 故障快速回退保留三份配置快照5 分钟内切回上一版本Mars 不提供配置版本管理需手动维护# 每次修改 conf/ 前打快照 cd /opt/mars/conf tar -czf mars-conf-$(date %Y%m%d-%H%M%S).tar.gz . # 回退命令例如回退到昨天的配置 tar -xzf mars-conf-20240529-143000.tar.gz -C /opt/mars/conf --strip-components1 systemctl restart mars我习惯在conf/下建backup/目录用find backup/ -name mars-conf-*.tar.gz | head -n -3 | xargs rm保留最近 3 份避免磁盘被快照占满。干了五年工业数据系统我最大的教训是别信“开箱即用”信“开箱即崩”。Mars 数据库的文档里没写的那 20%恰恰是它能在注塑机产线活过半年的关键——比如网卡 offload 那个坑我们花了 3 天抓包才定位比如.mseg文件损坏不报错靠的是每天凌晨自动md5sum校验。现在我的标准动作是部署完立刻跑marsctl datasource list看状态mars-sql查 5 条数据df -i看 inode三件事做完才敢去喝咖啡。希望帮到你。本文还有配套的精品资源点击获取
返回列表