據(jù)庫:從高可用到國產(chǎn)化的運維實踐)
很多人對智能工廠的印象還停留在機械臂揮舞、AGV小車穿梭、大屏上跳動著的各種生產(chǎn)數(shù)據(jù)。但作為一個常年泡在車間信息化項目里的老運維我想說一句大實話那些炫酷的畫面背后真正支撐整條產(chǎn)線跑起來的往往是一排不起眼的Linux服務器和一群默默扛著千萬級數(shù)據(jù)讀寫的數(shù)據(jù)庫實例。高端制造能不能“加速”很多時候取決于Linux跑得穩(wěn)不穩(wěn)、數(shù)據(jù)庫扛不扛得住。這篇文章我想從一個親歷者的角度聊聊智能工廠背后這套“看不見的基座”為什么工業(yè)現(xiàn)場越來越依賴Linux數(shù)據(jù)庫在制造環(huán)節(jié)里到底承擔了多重的活以及我們在一線部署、運維、救火過程中踩過的坑和總結出來的經(jīng)驗。不管你是有意進入智能制造領域的運維新人還是在工廠IT部門做系統(tǒng)支持的工程師這篇文章都值得花幾分鐘讀完。1. 智能工廠的控制中樞為什么偏偏是Linux在跑先說一個容易被忽視的事實工廠里的核心系統(tǒng)遠比你想象中更依賴Linux。從數(shù)控機床的嵌入式系統(tǒng)、PLC的通信網(wǎng)關、機器人的控制柜到MES制造執(zhí)行系統(tǒng)應用服務器、SCADA數(shù)據(jù)采集與監(jiān)控的歷史數(shù)據(jù)庫再到邊緣側的人工智能推理盒子Linux幾乎無處不在。有人會問Windows在老工業(yè)自動化里不也挺多的嗎確實有早期很多組態(tài)軟件、HMI人機界面跑在Windows上但最近五六年新改擴建的產(chǎn)線項目里Linux的占比肉眼可見地在提升。我參與過好幾個整車零部件工廠和3C電子產(chǎn)線的項目新上的邊緣網(wǎng)關、工業(yè)協(xié)議解析服務、數(shù)據(jù)中臺節(jié)點幾乎清一色是Linux環(huán)境。1.1 車間里那些你看不見的Linux很多讀者可能沒機會下車間我描述幾個真實場景你就明白Linux在工廠里無處不在。第一類是嵌入式工控機比如機器人控制柜里的主控單元。很多主流機器人品牌的控制器底層就是定制的Linux內核甚至是實時擴展后的Linux也就是帶PREEMPT_RT補丁的內核。它要在一個控制周期內完成運動學解算、插補運算和伺服指令下發(fā)對確定性要求極高。第二類是邊緣數(shù)據(jù)采集網(wǎng)關。產(chǎn)線上幾十臺PLC每臺每秒可能產(chǎn)生幾十乃至上百個點位數(shù)據(jù)網(wǎng)關要同時用Modbus TCP、OPC UA、S7comm等協(xié)議去采集再做一些清洗、緩存和轉發(fā)。這種活路Windows能干但穩(wěn)定性和資源占用都不如Linux來得省心。第三類是服務器集群包括數(shù)據(jù)庫服務器、應用服務器、文件服務器。MES、WMS、QMS這些業(yè)務系統(tǒng)大概率部署在Linux上的容器環(huán)境或虛擬機里。原因也很直白穩(wěn)定、省內存、好維護。所以當你站在智能工廠的中控大屏前感慨數(shù)據(jù)多炫的時候請記住背后是無數(shù)個Linux進程在默默干活。1.2 工控場景選Linux的三個硬理由很多非技術背景的管理者不理解為什么非要LinuxWindows Server不是也能用嗎我通常用三個理由來回答這三點是制造業(yè)客戶最關心的第一是穩(wěn)定性。整車廠往往是7×24小時不間斷生產(chǎn)設備窗口極其緊張。Windows更新機制偶爾會給你來個重啟這在產(chǎn)線環(huán)境里是不可接受的。而Linux服務器只要不打內核升級跑上一兩年不重啟是家常便飯。第二是資源效率。同樣的4核8G配置裝Windows Server光系統(tǒng)就吃掉兩三個G內存跑幾個服務就捉襟見肘。而換成精簡過的Linux同樣配置能跑起完整的數(shù)據(jù)庫加應用集群。工廠的IT預算往往摳得很細能用同樣的硬件干更多活這事本身就很有說服力。第三是可裁剪性。工業(yè)環(huán)境五花八門有些場景需要極小系統(tǒng)比如一個只有幾十兆的嵌入式系統(tǒng)有些場景需要極強的實時性需要編譯帶實時補丁的內核有些場景需要安全加固需要按等保要求裁剪不必要的服務和端口。這種靈活度Linux是唯一的選擇。1.3 從鏡像安裝到國產(chǎn)化Linux選型那些事這里順帶聊聊Linux的發(fā)行版選型因為很多剛入行的朋友喜歡在這上面糾結。如果是云端或者純測試環(huán)境用Ubuntu Server或者Debian都挺舒服軟件源豐富遇到問題搜索引擎一抓一大把。如果是要長期運維的生產(chǎn)環(huán)境我更傾向于RHEL系的發(fā)行版比如Rocky Linux或AlmaLinux他們對內核參數(shù)、SELinux、防火墻這些生產(chǎn)級特性的支持更成熟。至于網(wǎng)上常說的那些“Linux命令大全”說真的你不用死記硬背但下面幾個命令是生產(chǎn)環(huán)境高頻使用的# 查看系統(tǒng)負載和CPU核心數(shù)的關系 top # 查看內存和Swap使用情況 free -h # 查看磁盤I/O是否成為瓶頸 iostat -x 1 # 查看網(wǎng)絡連接數(shù) ss -tunap # 查看特定進程的線程數(shù) ps -eLf | grep java | wc -l鏡像安裝這塊現(xiàn)在主流做法是PXE網(wǎng)絡引導批量部署或者用云平臺的鏡像模板直接拉起來。工廠內網(wǎng)環(huán)境一般沒有外網(wǎng)所以提前準備好本地Yum源或Apt源是必須的不然裝個軟件包等半天極其影響效率。還有一點值得注意的是國產(chǎn)化趨勢。近幾年我們在政企和國企工廠項目里越來越多地接觸到麒麟、統(tǒng)信UOS這類國產(chǎn)Linux數(shù)據(jù)庫這塊也會要求適配人大金倉、達夢等國產(chǎn)數(shù)據(jù)庫。技術??赡茏兞说讓舆壿嫑]變——它們依然是Linux內核依然用SQL依然逃不開系統(tǒng)運維的基本功。與其焦慮學哪個不如把Linux的通用能力打扎實。2. 數(shù)據(jù)庫在智能工廠里到底“扛”什么講完Linux聊聊真正的重頭戲數(shù)據(jù)庫。如果說Linux是智能工廠的神經(jīng)系統(tǒng)那數(shù)據(jù)庫就是它的記憶中樞。設備數(shù)據(jù)、生產(chǎn)數(shù)據(jù)、質量數(shù)據(jù)、物料數(shù)據(jù)、人員數(shù)據(jù)最終都要落到數(shù)據(jù)庫里變成可以被查詢、被分析、被追溯的資產(chǎn)。不少做業(yè)務系統(tǒng)開發(fā)的同學對數(shù)據(jù)庫的理解停留在“增刪改查”這個層面。但在工業(yè)現(xiàn)場數(shù)據(jù)庫的挑戰(zhàn)完全不是一回事。我常說普通互聯(lián)網(wǎng)應用講究的是“高并發(fā)、大流量”而工業(yè)數(shù)據(jù)庫講究的是“高寫入、強時序、長歷史、可追溯”。這兩個方向的技術側重差異很大。2.1 工業(yè)數(shù)據(jù)從哪來裹著什么樣的體量先看數(shù)據(jù)源頭。一條典型的自動化產(chǎn)線傳感器包括溫度、壓力、振動、電流、位移、視覺檢測等等。這些信號經(jīng)過PLC采集后會通過OPC UA等服務送上邊緣網(wǎng)關再寫入車間級的實時數(shù)據(jù)庫或時序數(shù)據(jù)庫。舉個具體的例子一條發(fā)動機缸體機加工線大概有20多臺加工中心每臺機床配置幾十個關鍵監(jiān)控點位包括主軸負載、進給倍率、刀具壽命、冷卻液溫度等。如果每臺設備每秒采集一個點位整條線每秒產(chǎn)生的數(shù)據(jù)量就是幾百到上千條。這還只是一條線一個工廠動輒十幾條線再加上能源計量、環(huán)境監(jiān)測、質檢數(shù)據(jù)數(shù)據(jù)量很容易一天破億條。傳統(tǒng)的關系型數(shù)據(jù)庫比如MySQL在這種寫入壓力下會非常吃力。不是說不能寫而是寫入大量索引后的隨機I/O會成為瓶頸同時歷史數(shù)據(jù)膨脹后查詢也越來越慢。所以工業(yè)場景里需要仔細地為不同類型的數(shù)據(jù)挑選不同的數(shù)據(jù)庫。2.2 關系型數(shù)據(jù)庫MES與ERP的“賬房先生”MySQL和PostgreSQL這類關系型數(shù)據(jù)庫在智能工廠中負責的是業(yè)務型數(shù)據(jù)也就是那些結構化程度高、一致性要求強、需要復雜事務的數(shù)據(jù)。比如MES里的工單狀態(tài)流轉一個工單從“已創(chuàng)建”變成“生產(chǎn)中”再變成“已完成”中間涉及批次拆分、物料扣減、工序報工一步都不能錯。再比如ERP里的庫存賬、財務賬那更是分毫不差。這類數(shù)據(jù)用關系型數(shù)據(jù)庫的ACID特性來保證是最穩(wěn)妥的選擇。在部署上工廠內部的MES數(shù)據(jù)庫通常不會開在公網(wǎng)而是在內網(wǎng)用主從架構保證高可用。我經(jīng)手的項目里MySQL主從加半同步復制或者PostgreSQL的流復制是比較常見的方案。這里要特別提醒一句工業(yè)環(huán)境經(jīng)常有突然斷電、網(wǎng)絡瞬斷的情況數(shù)據(jù)庫的binlog或WAL日志的可靠性一定要重點配置sync_binlog和innodb_flush_log_at_trx_commit這兩個參數(shù)在允許的情況下盡量調高。另外很多工廠IT手里都攢著一些老系統(tǒng)比如2008年的SQL Server或者早期的Oracle。這類老庫耦合深、遷移難短期內只能繼續(xù)維護。但也別死扛做好備份策略在適當?shù)臅r候向開源庫或國產(chǎn)庫演進長期來看是趨勢。2.3 時序數(shù)據(jù)庫一秒一條數(shù)據(jù)時MySQL就不好使了大規(guī)模設備數(shù)據(jù)采集場景我強烈建議交給時序數(shù)據(jù)庫Time Series DatabaseTSDB。這類數(shù)據(jù)庫專門為時間戳數(shù)值點這種數(shù)據(jù)模型優(yōu)化寫入性能和處理海量歷史數(shù)據(jù)的能力遠超傳統(tǒng)關系庫。目前工業(yè)圈里用得比較多的有TDengine、InfluxDB、TimescaleDB等特別是TDengine因為國產(chǎn)、開源、性能亮眼這幾年在制造企業(yè)的出鏡率相當高。我自己的項目里就用它存儲機床主軸負載和振動數(shù)據(jù)。TDengine的超級表、子表設計很貼合工業(yè)場景——每臺設備建一張子表設備屬性放標簽采集值放普通列查詢起來干凈利落。提到TDengine就不得不提它的C/C接口。邊緣采集程序大多用C或C開發(fā)通過taos_stmt_prepare來做參數(shù)綁定寫入可以顯著減少重復解析SQL的開銷。我最早接觸這個接口時還不太習慣用下來才發(fā)現(xiàn)針對高頻、固定模式的寫入需求這種預處理方式比逐條拼SQL性能好一個檔次。taos_stmt *stmt taos_stmt_init(taos); taos_stmt_prepare(stmt, INSERT INTO ? USING meters TAGS (?) VALUES (?, ?, ?), 0); TAOS_BIND tags[1] {0}; tags[0].buffer_type TSDB_DATA_TYPE_INT; int32_t deviceId 101; tags[0].buffer deviceId; taos_stmt_set_tbname_tags(stmt, deviceId, tags); TAOS_BIND params[3] {0}; // 綁定時間、數(shù)值等參數(shù)后執(zhí)行批量寫入 taos_stmt_bind_param(stmt, params); taos_stmt_execute(stmt);這里不展開講完整代碼但要記住一個原則高頻數(shù)據(jù)采集永遠優(yōu)先考慮批量寫入和預編譯綁定別一條一條地insert。3. 一套典型智能工廠數(shù)據(jù)鏈路的落地過程理論扯了不少我把一套真實項目里反復驗證過的數(shù)據(jù)鏈路架構畫個文字版給你看然后分環(huán)節(jié)講落地細節(jié)。整個鏈路大致是設備層PLC/傳感器→ 邊緣采集網(wǎng)關 → 消息中間件或直連 → 數(shù)據(jù)清洗與規(guī)則引擎 → 分布式存儲時序庫關系庫→ 數(shù)據(jù)服務API → MES/可視化大屏/算法平臺。我在做項目時習慣先畫清楚這張數(shù)據(jù)流圖再決定每個環(huán)節(jié)用什么技術而不是一上來就裝數(shù)據(jù)庫。3.1 邊緣層數(shù)據(jù)采集網(wǎng)關怎么部署邊緣網(wǎng)關在Linux上的部署是整個鏈路里坑最多的地方。硬件上我們常用的是研華、戴爾或國產(chǎn)廠家的工控機系統(tǒng)安裝Rocky Linux或Ubuntu Server裁剪掉不必要的圖形組件。軟件上一般會用開源的Node-RED或自研的采集程序來跑協(xié)議解析。PLC協(xié)議接入只講一個容易踩的坑西門子S7協(xié)議走的是102端口很多安全人員默認覺得非Web端口不危險就不加防護了。但在工業(yè)內網(wǎng)這類端口恰恰是橫向移動的高發(fā)通道。建議用防火墻限制只能由白名單網(wǎng)關訪問PLC別把整個網(wǎng)段都放進來。網(wǎng)關程序寫數(shù)據(jù)到數(shù)據(jù)庫時最容易犯的錯是內存暴漲。很多新手喜歡在程序里做一把梭等內存爆了就找原因。正確做法是采集線程和寫入線程分離中間用有界隊列解耦。隊列長度超過閾值就丟棄老點位并記錄告警寧可丟采樣點也不能讓網(wǎng)關進程崩潰。3.2 數(shù)據(jù)入庫建表、結構變更與同步策略數(shù)據(jù)到了存儲層建表設計直接決定后續(xù)查詢爽不爽。我用MySQL存業(yè)務數(shù)據(jù)時遵循幾個原則主鍵用自增ID但配合業(yè)務唯一索引金額、重量等字段用DECIMAL避免浮點誤差文本字段長度要克制別一上來就是TEXT所有表都要有create_time和update_time后面排查問題會省很多事。MySQL修改表結構這事看起來簡單但生產(chǎn)環(huán)境執(zhí)行起來要格外小心。千萬行級別的表直接ALTER TABLE加索引可能鎖表幾分鐘產(chǎn)線報工全部堵住。比較穩(wěn)妥的做法是借助工具如pt-online-schema-change或gh-ost來做在線變更最大限度降低鎖表時間。我在車間項目里用gh-ost改過一張幾千萬行的報工表業(yè)務幾乎無感知。至于數(shù)據(jù)庫同步很多工廠不止一套系統(tǒng)比如MES數(shù)據(jù)庫要跟ERP數(shù)據(jù)庫同步物料主數(shù)據(jù)或者從數(shù)據(jù)中心同步到分廠的報表庫。常用方案包括基于binlog的Canal訂閱同步、基于主從復制的直連同步或者用DataX等批同步工具。選型邏輯很簡單要實時就選Canal或主從復制能接受分鐘級延遲就選批同步。3.3 數(shù)據(jù)消費從SQL到API別讓業(yè)務裸奔數(shù)據(jù)存好了最終要給人用、給系統(tǒng)用、給AI用。最忌諱的做法是讓每個業(yè)務系統(tǒng)直連數(shù)據(jù)庫。我曾經(jīng)接手過一個項目可視化大屏的程序直接用賬號密碼連接生產(chǎn)庫寫了一個幾百行的SQL去查實時產(chǎn)量。開發(fā)一時爽運維火葬場。后來幾條報表SQL把生產(chǎn)庫的連接池打滿了MES直接連不上數(shù)據(jù)庫產(chǎn)線停產(chǎn)了十分鐘。正確的做法是數(shù)據(jù)服務化也就是在數(shù)據(jù)庫前面加一層API服務。業(yè)務系統(tǒng)、大屏、算法平臺都通過REST API或gRPC去取數(shù)由API層做鑒權、限流、緩存。這樣即使某個報表SQL寫得不怎么樣最多拖垮API服務也不會直接把生產(chǎn)庫拖死。對于常見的增刪改查需求可以通過API網(wǎng)關統(tǒng)一封裝對于分析類需求則把數(shù)據(jù)導出到分析型數(shù)據(jù)庫或數(shù)據(jù)倉庫里跑別在生產(chǎn)庫上執(zhí)行重型聚合。4. 數(shù)據(jù)庫扛不住時運維人怎么救場在智能工廠做運維最怕的就是半夜電話響。因為工廠一旦停線每一分鐘損失都是真金白銀。我總結過的數(shù)據(jù)庫故障案例幾乎都集中在幾個固定的坑里。這里把典型場景和排查思路分享出來方便兄弟們按圖索驥。4.1 典型故障一數(shù)據(jù)庫連接池被打滿癥狀非常直接業(yè)務系統(tǒng)報“無法獲取連接”或者連接數(shù)飆到上限。原因十有八九是某個應用忘了釋放連接或者并發(fā)量突增導致的應用側連接池配置不合理。排查步驟按順序來第一先看數(shù)據(jù)庫側當前連接數(shù)show processlist;看有沒有大量Sleep狀態(tài)的連接。如果有基本就是應用側沒釋放連接去查代碼、查連接池配置。第二看連接來自哪些應用IP用防火墻或數(shù)據(jù)庫賬號權限按應用隔離連接上限別讓一個應用把數(shù)據(jù)庫拖死。第三調連接池參數(shù)初始連接數(shù)、最小空閑、最大連接、連接超時時間都要結合應用的實際QPS來設置。補充一句MySQL默認的max_connections是151在工廠里幾十個應用一起接的話這個值通常要往上調。但是調高之前先算一下每個連接可能的排序緩沖、臨時表內存不然連接數(shù)上去了內存頂不住更加難看。4.2 典型故障二慢查詢拖垮一切另一個高頻故障是慢查詢。平時業(yè)務量小的時候一條爛SQL跑兩秒也不覺得有問題。一旦月底產(chǎn)量沖高數(shù)據(jù)量上來這條SQL突然變成50秒把CPU和I/O全部吃滿整個數(shù)據(jù)庫性能雪崩。所以數(shù)據(jù)庫維護有一條鐵律慢查詢日志長期開啟閾值設置到1秒甚至0.5秒然后每周定期分析這些慢SQL。-- 查看當前慢查詢相關設置 SHOW VARIABLES LIKE slow_query_log%; SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 0.5;拿到了具體的慢SQL先別急著改代碼用EXPLAIN看執(zhí)行計劃。重點看三個東西是否走了索引、掃描行數(shù)是多少、有沒有文件排序或臨時表。工業(yè)軟件里最典型的問題是查設備點位的時候在歷史數(shù)據(jù)表上沒用上時間索引導致全表掃描。解決方法是建好聯(lián)合索引比如(device_id, ts)這類組合索引而不是只建單列索引。有一說一我見過太多所謂“數(shù)據(jù)庫性能優(yōu)化”最后就是給查詢加個索引了事。真正要治本還得從數(shù)據(jù)模型設計、讀寫分離、歷史數(shù)據(jù)歸檔幾個層面一起搞。4.3 高可用與容災主從、同步和備份的平衡高端制造對數(shù)據(jù)連續(xù)性的要求特別高一臺數(shù)據(jù)庫掛了如果沒能及時切換產(chǎn)線上的數(shù)據(jù)就會斷檔。這塊我們常用的方案是主從復制加自動故障切換。MySQL半同步復制是主流。它的原理是主庫提交事務后至少要等一個從庫確認收到binlog才返回成功這樣主從切換時數(shù)據(jù)丟失的概率極低。當然半同步復制也有一個副作用如果從庫故障主庫的寫入會阻塞。所以還要配合監(jiān)控告警一旦半同步退化為異步立刻通知運維處理。備份策略也值得展開。很多工廠只做邏輯備份用mysqldump每天凌晨跑一次。對于小庫沒問題到大庫就是災難——且不說導出和導入的時間光是備份期間對數(shù)據(jù)庫的性能影響就夠喝一壺的。更好的方案是物理備份用xtrabackup或者數(shù)據(jù)庫原生的物理備份工具速度比mysqldump快一個數(shù)量級而且能基于binlog做時間點恢復。我自己的備份習慣是“3-2-1”原則三份數(shù)據(jù)兩種介質一份異地。工廠環(huán)境里異地可以是另一個車間機房也可以是云上的對象存儲總之不能和主庫待在同一個機柜里。4.4 國產(chǎn)數(shù)據(jù)庫與信創(chuàng)適配的一點叮囑既然熱搜里反復出現(xiàn)人大金倉、達夢這些詞我多說兩句國產(chǎn)數(shù)據(jù)庫適配的事。它們從功能上兼容主流SQL語法但深挖下去差異還是存在的。比如某些函數(shù)的行為、事務隔離級別的默認值、分區(qū)表語法、主從同步的實現(xiàn)方式都跟MySQL或Oracle有微妙的不同。做信創(chuàng)項目時我會建議團隊提前準備一個“語法兼容性清單”把項目里常用的SQL語句拉出來在目標數(shù)據(jù)庫上逐個跑一遍。不要等系統(tǒng)上線了才發(fā)現(xiàn)某個復雜報表語法不支持。還有性能問題國產(chǎn)庫在簡單增刪改查上和MySQL差距不大但復雜分析查詢可能性能差異明顯該優(yōu)化的還是要優(yōu)化。另外工業(yè)場景里向量數(shù)據(jù)庫也開始露臉。隨著AI質檢、知識庫問答在工廠里落地像文本、圖像特征向量這類非結構化數(shù)據(jù)越來越多地存儲到向量數(shù)據(jù)庫里做語義檢索。未來智能工廠的數(shù)據(jù)底座大概率是“關系庫時序庫向量庫”多引擎并存運維人員的技術面也得跟著拓寬。5. 寫在最后給智能工廠IT人的幾句心里話這個行業(yè)這些年變化太快從數(shù)字化車間到智能工廠從自動化到智能化概念一個接一個。但我始終覺得無論上層業(yè)務怎么變底層技術基座的邏輯沒有變過——穩(wěn)定的操作系統(tǒng)可靠的數(shù)據(jù)存儲清晰的數(shù)據(jù)流。說句實在話做工廠IT和做互聯(lián)網(wǎng)運維的最大區(qū)別在于互聯(lián)網(wǎng)掛了用戶頂多罵兩句工廠系統(tǒng)掛了那是實實在在的產(chǎn)線停擺、訂單延誤、設備空轉。這種壓力逼著我們必須把系統(tǒng)和數(shù)據(jù)庫的功課做得更細。如果你正在入行或者已經(jīng)在路上建議從三件事入手積累第一把Linux常用命令和系統(tǒng)排查方法論練扎實這是所有上層技術的底座第二吃透至少一種數(shù)據(jù)庫的運行原理包括事務、索引、鎖、復制而不是只停留在寫SQL第三多下車間、多看產(chǎn)線理解業(yè)務比理解技術更重要。踩過幾次數(shù)據(jù)庫連接池被打滿的坑之后我現(xiàn)在寫任何代碼都會自動帶上一句連接必須釋放查詢必須帶LIMIT關鍵SQL必須過一遍EXPLAIN。這些習慣都是工廠的產(chǎn)線替我們養(yǎng)成的。