
1. 从一条产线停机说起智能工厂的底层到底在跑什么去年冬天我去一家做精密结构件的工厂做现场支持。上午十点三条产线同时停了。车间主任第一反应是网络又断了IT那边查了一圈说网络没问题PLC状态也正常。最后定位到的原因是采集层的一台工控机磁盘写满导致本地时序数据落盘失败上层MES拿不到实时数据触发了安全联锁停机。这件事给我触动很大。大家平时聊智能工厂聊的都是大屏、看板、AI质检、数字孪生但真正在底下扛事的是Linux 操作系统和数据库这两样看起来最不性感的东西。Linux 负责把设备、传感器、网关、边缘盒子这些异构硬件统一管起来数据库负责把每秒成千上万条带时间戳的数据稳稳接住、存下来、还能被快速查出来。这两层任何一层出问题上面所有的智能都是空中楼阁。这篇内容我想聊的就是这个底层组合Linux 数据库在智能工厂场景里到底怎么分工、怎么选型、怎么调优、怎么排障。关键词里提到的实时内核、时序数据库、嵌入式 Linux、国产 Linux、数据库同步这些我都会结合实际场景展开。适合正在做工业数据采集、边缘计算、MES/SCADA 对接的工程师也适合刚入行想搞清楚工厂里的数据到底怎么流的朋友。不管你是运维、后端还是自动化出身看完应该都能对这套底层架构有个能落地的认识。2. Linux 在工厂里扮演的三个角色以及为什么它成了默认答案2.1 边缘采集网关嵌入式 Linux 的主场工厂里最靠近设备的那一层通常是各种边缘网关或者工控机。它们要干的事很杂跑 Modbus、OPC UA、Profinet 这些工业协议栈做协议转换做本地缓存还要把数据往上传。这种场景下嵌入式 Linux几乎是默认选择。原因很实在。第一工业现场的设备五花八门ARM 架构的网关、x86 的工控机、甚至一些定制板卡Linux 的驱动生态覆盖最广换个硬件平台迁移成本低。第二Linux 可以裁剪一个只跑采集和转发的网关内核加根文件系统能做到几十兆跑在资源紧张的板子上毫无压力。第三也是最重要的一点Linux 的进程模型和网络栈足够稳长时间运行不容易出幺蛾子。我见过不少项目用 RTOS 做采集实时性确实好但一旦要加个 MQTT 上报、加个本地 SQLite 缓存、再加个远程升级RTOS 的开发效率就顶不住了。而 Linux 上这些都有现成的库Python、C、Go 随便挑。所以现在的趋势很明显实时性要求极高的控制回路留给 PLC 和 RTOS数据采集和边缘计算这一层交给 Linux。2.2 实时内核什么时候必须上 PREEMPT_RT说到实时性就绕不开实时内核。标准 Linux 内核在调度上做了很多吞吐优化但它的最坏情况延迟worst-case latency可能到几十毫秒甚至更高这对于某些运动控制、高速同步采集的场景是不够的。这时候就得上PREEMPT_RT补丁现在大部分已经合并进主线。它把内核里大部分不可抢占的区域改造成可抢占的把中断处理线程化能把最坏延迟压到几十微秒级别。我做过一个多轴同步采集的项目采样周期 1ms用标准内核偶尔会丢点换成 RT 内核之后抖动稳定在 50μs 以内问题就没了。但这里有个坑要提醒不是所有场景都需要 RT 内核。很多团队一上来就追求实时结果为了 RT 牺牲了吞吐和驱动兼容性得不偿失。判断标准很简单——你的控制周期是多少如果周期在 10ms 以上标准内核配合合理的优先级设置SCHED_FIFO、CPU 隔离、中断亲和性基本够用。只有周期进入亚毫秒级或者对抖动极其敏感才值得上 RT。2.3 国产 Linux 的落地现状关键词里出现了国产 Linuxlinux 国产这块我多说两句。现在工业现场用国产发行版的情况越来越多尤其是在一些对供应链有要求的项目里。主流的几个方向是基于 Debian 或 RHEL 体系做的衍生版本加上国产 CPU 平台ARM64、LoongArch、SW64 等的适配。实际用下来我的经验是选型时重点看三件事——内核版本是否够新关系到新硬件驱动和 RT 支持、软件源是否完整关系到能不能顺利装 Python、数据库客户端这些依赖、以及长期维护承诺。有些国产发行版界面做得漂亮但软件源里缺包装个 psycopg2 要自己编译半天这种在项目里就是隐形成本。建议在 POC 阶段就把你要用的所有依赖列个清单逐个验证能不能一键装上。3. 数据库选型为什么智能工厂里时序数据库和关系库要一起用3.1 先搞清楚工厂里的数据分几类很多人一上来就问智能工厂用什么数据库这个问题本身就问错了。工厂里的数据至少分三类每类的特征完全不同用同一个库硬扛必然出问题。第一类是时序数据温度、压力、振动、电流这些传感器读数特点是写多读少、量大、带时间戳、按时间范围查询。一条产线几千个测点1 秒采一次一天就是几亿条。第二类是关系型业务数据工单、物料、BOM、人员、设备台账特点是强一致性、有事务要求、数据量相对小但关系复杂。第三类是半结构化/日志数据设备日志、报警记录、操作审计特点是格式灵活、需要全文检索。所以现实中的架构基本都是组合拳时序数据库扛采集数据关系型数据库扛业务数据中间靠同步机制打通。3.2 时序数据库的选型逻辑时序数据库这块关键词里提到了松果时序数据库多模态数据库这些。选型时我一般看几个维度维度关注点为什么重要写入吞吐单节点每秒能写多少点产线测点多时这是硬指标压缩率原始数据压缩后占多少空间直接决定存储成本和保留周期查询能力降采样、聚合、插值是否原生支持大屏和报表全靠这个生态兼容是否支持标准 SQL、是否有主流语言驱动影响开发效率部署形态单机、集群、边缘轻量版边缘和中心需求不同像 InfluxDB、TimescaleDB、TDengine 这些是常见选择。TimescaleDB 的好处是它本身就是 PostgreSQL 的扩展业务数据和时序数据能放一个库里省掉了同步的麻烦适合中小规模场景。TDengine 在写入性能和压缩上很猛适合测点特别多的场景。至于一些国产时序库优势在于本地化支持和信创适配选的时候重点验证它的 SQL 兼容性和驱动成熟度。提示不要被写入百万点每秒这种宣传数字迷惑。一定要用你自己的真实数据模型做压测因为标签tag的基数对时序库性能影响极大。标签基数一高很多库的性能会断崖式下跌。3.3 关系库和时序库之间怎么打通这是实际项目里最容易出问题的地方。业务库比如 MySQL、人大金仓和时序库是两套系统数据要互相同步。常见做法有几种一种是应用层双写采集程序同时往两个库写。简单直接但一致性难保证一旦一边失败就容易脏数据。另一种是CDC变更数据捕获同步通过解析数据库日志把变更投递过去一致性更好但配置复杂。还有一种是定时批量同步用 ETL 工具或者自己写脚本适合对实时性要求不高的场景。关键词里提到的数据库同步软件就是干这个的。我的建议是核心业务数据用 CDC 保证准实时一致统计分析类数据用批量同步就够了。别为了追求全实时把架构搞得无比复杂最后维护成本高得吓人。4. 从裸机到上线一套可复现的部署与调优流程4.1 系统安装与基础环境拿到一台工控机或者边缘服务器第一步是装系统。关键词里linux 镜像安装虚拟机安装 linux 系统是高频问题我按物理机和虚拟机分别说。物理机装 Linux现在最省事的是用Ventoy做启动盘把 ISO 直接拷进去就能引导不用反复烧录。镜像选择上服务器场景推荐 Ubuntu Server LTS 或者 Rocky Linux长期支持有保障。安装时有个细节容易被忽略分区方案。工业场景我一般这样分/根分区50-100G放系统和应用/var单独分区这是重点因为数据库数据、日志默认都在/var下单独分区能防止日志写满拖垮整个系统前面那个停机事故就是栽在这/data单独分区专门放数据库数据文件用独立磁盘或者 SSDswap内存的 1-2 倍但数据库服务器上建议调小避免内存换出影响性能虚拟机安装的话关键词里虚拟机安装 linux 系统问的人多。VMware 和 VirtualBox 都行注意网卡选桥接模式不然和现场设备不在一个网段采集程序连不上。另外虚拟机的时钟同步要配好时序数据对时间戳极其敏感时间漂移会导致数据错乱。4.2 内核参数调优数据库服务器的必修课系统装完别急着装数据库先把内核参数调了。这些参数直接决定数据库能不能跑出应有性能。# /etc/sysctl.conf 关键参数 # 共享内存段PostgreSQL 等库依赖 kernel.shmmax 68719476736 kernel.shmall 16777216 # 文件句柄数高并发必备 fs.file-max 2097152 # 网络连接队列采集端并发高时重要 net.core.somaxconn 65535 net.ipv4.tcp_max_syn_backlog 65535 # TCP 连接复用减少 TIME_WAIT net.ipv4.tcp_tw_reuse 1 net.ipv4.tcp_fin_timeout 30 # 脏页刷盘策略影响写入性能和数据安全 vm.dirty_ratio 10 vm.dirty_background_ratio 5 vm.swappiness 10vm.swappiness调到 10 是为了尽量不用 swap数据库最怕内存被换出去。dirty_ratio调低是为了让数据更及时落盘工业场景丢数据的代价比性能损失大得多。文件句柄限制还要在/etc/security/limits.conf里配* soft nofile 65535 * hard nofile 65535改完记得ulimit -n验证一下很多too many open files的报错都是这里没配对。4.3 数据库部署与初始化以 PostgreSQL 为例它既能当业务库又能通过 TimescaleDB 当时序库很适合中小工厂# 安装 apt install postgresql-15 postgresql-contrib # 初始化后调整配置 # postgresql.conf 关键项 shared_buffers 4GB # 内存的 25% 左右 effective_cache_size 12GB # 内存的 75% work_mem 64MB maintenance_work_mem 1GB wal_buffers 16MB max_connections 500shared_buffers给内存的 25% 是经验值给太多反而因为双重缓存降低性能。work_mem影响排序和哈希操作报表查询多的话适当调大但注意它是按连接分配的别调太猛把内存吃光。装完数据库第一件事是建监控。我习惯用pg_stat_statements扩展抓慢查询配合 Prometheus Grafana 做可视化。工厂里最怕的就是数据库悄悄变慢没人发现等大屏卡了才去查往往已经积压一堆问题。4.4 采集程序的部署与守护采集程序怎么保证不因为终端退出就挂掉关键词里linux 让后台运行指令 不因界面退出而退出就是这个需求。最土的办法是nohupnohup python3 collector.py collector.log 21 但生产环境强烈建议用systemd管理好处是能自动重启、能配依赖、能统一管日志# /etc/systemd/system/collector.service [Unit] DescriptionFactory Data Collector Afternetwork.target postgresql.service [Service] Typesimple Userfactory WorkingDirectory/opt/collector ExecStart/usr/bin/python3 /opt/collector/collector.py Restartalways RestartSec5 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.targetRestartalways是关键程序崩了 5 秒后自动拉起来。工业现场无人值守这个配置能救命。配完systemctl daemon-reload systemctl enable --now collector就完事。5. 现场排障实录那些文档里不会写的坑5.1 磁盘写满引发的连锁停机回到开头那个事故。排查过程其实很有代表性我完整复盘一下。现象是三条产线同时停MES 报数据超时。第一步看网络ping和telnet都通排除网络。第二步看采集程序状态systemctl status collector显示进程在跑但日志里全是write failed: no space left on device。第三步df -h一看/var分区 100% 满了。根因是数据库的 WAL 日志和系统日志都堆在/var加上采集程序自己的日志没做轮转几天就把分区撑爆了。修复分三步先清理旧日志腾出空间让服务恢复再把数据库数据目录迁到独立的/data分区最后给所有日志配上 logrotate。# /etc/logrotate.d/collector /opt/collector/*.log { daily rotate 7 compress missingok notifempty copytruncate }copytruncate这个选项很重要它复制完日志后清空原文件不需要重启程序适合不能中断的采集服务。这个坑的教训是工业现场的磁盘规划一定要把数据、日志、系统分开。别图省事全塞一个分区出事就是连锁反应。5.2 时间不同步导致的数据错乱第二个坑更隐蔽。有段时间发现时序数据查出来顺序是乱的同一秒的数据时间戳能差好几秒。查了半天发现是几台采集网关的 NTP 没配好各自漂移。时序数据的命根子就是时间戳。时间一乱降采样、聚合、关联分析全废。解决办法是统一配 NTP而且要在采集程序里做时间校验# 检查时间同步状态 timedatectl status # 手动同步 chronyc sources -v更进一步采集程序写入时应该带上采集时刻和入库时刻两个时间戳一旦发现两者偏差过大就告警。这样能第一时间发现时间同步问题而不是等数据乱了才回头查。5.3 数据库连接池被打满第三个坑是连接数问题。采集端并发一高数据库报too many connections。表面看是连接数不够实际根因往往是连接没被正确释放。采集程序里如果异常处理没写好连接泄漏跑几天就把池子占满了。排查方法查pg_stat_activity看有多少空闲连接、它们的状态和持续时间。SELECT state, count(*), max(now() - state_change) AS max_idle FROM pg_stat_activity GROUP BY state;如果看到大量idle状态且max_idle很大基本就是泄漏。修复要靠代码层面保证连接在finally里释放同时数据库侧配idle_in_transaction_session_timeout兜底把长时间空闲的事务自动杀掉。注意连接池大小不是越大越好。数据库能扛的并发连接有限池子开太大反而拖垮数据库。一般按CPU核数 * 2 磁盘数估算再结合压测调整。6. 数据同步与多模态让数据在边缘和中心之间流动6.1 边缘缓存 断网续传的设计工厂网络不是永远可靠的边缘和中心之间断网是常态。所以采集架构必须支持断网续传边缘侧用轻量数据库SQLite 就很合适做本地缓存网络恢复后把积压的数据补传上去。SQLite 在这里是绝配单文件、零配置、嵌入式友好。关键词里sqllite 数据库sqlite 数据库 *.db 示例文件问的人多它在边缘场景的用法就是当本地队列import sqlite3 conn sqlite3.connect(/data/buffer.db) conn.execute(CREATE TABLE IF NOT EXISTS buffer (id INTEGER PRIMARY KEY AUTOINCREMENT, ts INTEGER, payload TEXT, synced INTEGER DEFAULT 0))采集时先写本地同步线程定期把synced0的记录推到中心库成功后再标记。这样即使断网几小时数据也不会丢。要注意的是本地缓存要有容量上限和淘汰策略不然磁盘又会被写满。6.2 多模态数据的统一管理现在工厂里的数据越来越杂结构化读数、图像、音频设备异响检测、日志文本。关键词里多模态数据库说的就是这个趋势。实际落地时我的建议是不要指望一个库解决所有问题而是用元数据 对象存储 专用库的组合。具体说图像、音频这类大文件放对象存储MinIO 之类数据库里只存路径和元数据结构化读数放时序库日志放 Elasticsearch 这类检索库。查询时通过统一的 ID 关联。这样每类数据都用最适合它的存储性能和成本都最优。6.3 同步链路的监控同步链路是隐形故障高发区。数据没同步过去两边都不报错等发现时已经积压几天。所以必须给同步链路配监控积压量、同步延迟、失败率这三个指标要实时盯着。我一般会在边缘和中心各写一条心跳记录中心侧定时比对两边的最新时间戳差值超过阈值就告警。这个简单的机制能提前发现 90% 的同步问题。7. 一些踩过坑之后总结的实操心得聊了这么多最后分享几条我在实际项目里反复验证过的经验都是文档里不太会写、但现场特别管用的。关于 Linux 运维工业现场的机器往往没人天天盯着所以自愈能力比什么都重要。systemd 的自动重启、磁盘空间的自动清理、关键服务的健康检查这些配置一次能省掉无数次半夜被叫起来。另外linux 运维故障案例里最常见的三类就是磁盘满、内存泄漏、时间漂移建议把这三个做成定时巡检脚本每天跑一次。关于数据库永远不要在生产库上直接改结构。关键词里mysql 数据库修改结构是高频操作但大表改结构会锁表工业场景锁几秒就是停线。正确做法是用在线 DDL 工具如 pt-online-schema-change、gh-ost或者在业务低峰期做并且提前在同等数据量的测试库上验证耗时。关于选型别追新。工业软件的寿命周期很长一套系统可能跑十年。选型时优先考虑社区活跃度、长期支持承诺、以及你自己团队能不能 hold 住。一个再先进但没人会维护的数据库不如一个普通但团队熟悉的。关于备份这是老生常谈但现场真的见过太多没备份的。数据库备份要满足3-2-1原则3 份副本、2 种介质、1 份异地。而且备份必须定期做恢复演练没验证过的备份等于没有备份。我见过备份文件损坏、恢复时才发现的情况那真是欲哭无泪。这套 Linux 数据库的底层组合说白了就是智能工厂的地基。上面的大屏、AI、数字孪生再花哨地基不稳一切都是零。把这两层做扎实把监控和自愈配好把数据同步链路盯住工厂的智能才真正跑得起来。