楊 坤 李 夏 王 勇 都書剛
( 煤炭科學技術(shù)研究院有限公司,北京100013)
為實現(xiàn)人員定位管理系統(tǒng)的可靠性, 煤炭行業(yè)監(jiān)管部門制定的相關(guān)行業(yè)標準要求: 煤礦井下作業(yè)人員管理系統(tǒng)應(yīng)具有雙機切換功能, 并且從工作主機故障到備用主機投入正常工作時間應(yīng)不大于5min。 因此,井下作業(yè)人員管理系統(tǒng)必須具有穩(wěn)定、可靠的雙機熱備解決方案?;诿旱V生產(chǎn)場景的實際,目前的煤礦井下人員定位系統(tǒng)主要是采用純軟件的方式實現(xiàn)。 純軟件的雙機熱備系統(tǒng)具有節(jié)約成本與部署方便的優(yōu)點, 但現(xiàn)有的純軟件的雙機熱備系統(tǒng)也存在著一些缺陷:(1) 監(jiān)控服務(wù)狀態(tài)的流程復雜,造成可靠性差;(2)數(shù)據(jù)同步采用通信程序分發(fā)機制,易造成數(shù)據(jù)混亂;(3)界面復雜,操作困難。 針對現(xiàn)有純軟件方式實現(xiàn)的雙機熱備存在的問題, 筆者設(shè)計了一套基于有限狀態(tài)機的雙機熱備系統(tǒng),能夠同時監(jiān)測PostgreSQL、Redis 與通訊服務(wù)的工作狀態(tài),形成一個穩(wěn)定的解決方案,提高了雙機熱備的可靠性。
有限狀態(tài)機是指系統(tǒng)中的有限個狀態(tài)以及狀態(tài)之間的遷移移活動,并通過狀態(tài)、條件、動作與次態(tài)四個要素構(gòu)建對應(yīng)的數(shù)學模型。 狀態(tài):系統(tǒng)具有一組狀態(tài),并且系統(tǒng)可以在這些狀態(tài)之間切換;但是,系統(tǒng)在某一時刻只能處于一個狀態(tài)。 條件:觸發(fā)系統(tǒng)進行狀態(tài)切換的事件;當系統(tǒng)處于某一個穩(wěn)定狀態(tài)時,發(fā)生能夠觸發(fā)系統(tǒng)進行狀態(tài)切換的事件, 系統(tǒng)去執(zhí)行具體的動作來完成狀態(tài)的切換。
動作:系統(tǒng)狀態(tài)變更需要執(zhí)行的具體的操作。
次態(tài):系統(tǒng)完成變更后的狀態(tài)。
綜合上述表示,有限狀態(tài)機可以表示為五元數(shù)學符號:

在進行理論研究時, 有限狀態(tài)機一般以數(shù)學表達式的方式抽象出來。 此外,有限狀態(tài)機還具有狀態(tài)轉(zhuǎn)移圖、轉(zhuǎn)移表和狀態(tài)轉(zhuǎn)移矩陣三種直觀的表示方法。 本文中主要采用狀態(tài)轉(zhuǎn)移圖的表示方法。如圖1 所示,圓圈表示狀態(tài),有向弧線表示狀態(tài)變遷過程,弧線上的字符表示條件,具有開始箭頭標注的圓圈表示初始狀態(tài),雙圓圈表示最終狀態(tài)。該表示方法可以直觀的表示系統(tǒng)的狀態(tài)集合、狀態(tài)切換過程以及切換條件。

圖1 有限狀態(tài)機狀態(tài)轉(zhuǎn)移圖
基于有限狀態(tài)機的雙機熱備系統(tǒng)的總體架構(gòu)如圖2 所示,在兩臺機器中分別運行一套控制系統(tǒng), 包括UI 界面、 應(yīng)用服務(wù)、PostgreSQL、Redis、通訊服務(wù)與熱備服務(wù)。 其中,UI 界面主要是展示展示各模塊的狀態(tài)與操作按鈕; 應(yīng)用服務(wù)主要是用來獲取PostgreSQL 數(shù)據(jù)庫、Redis 數(shù)據(jù)庫、 通訊服務(wù)以及熱備服務(wù)的各模塊的狀態(tài); 熱備服務(wù)主要是用來監(jiān)測各服務(wù)的狀態(tài)與控制A機和B 機的狀態(tài)切換。

圖2 系統(tǒng)架構(gòu)圖
熱備服務(wù)的內(nèi)部架構(gòu)設(shè)計為4 個單元與3 個外圍受控組件,通過4 個單元與組件構(gòu)成了完整的熱備服務(wù)。
3.2.1 通信單元
通信單元的設(shè)計主要是實現(xiàn)A 機與B 機的狀態(tài)信息的交換。 狀態(tài)信息的交換主要是通過keepalived 的vrrp 協(xié)議的報文處理實現(xiàn)。
3.2.2 PostgreSQL
PostgreSQL 是實現(xiàn)終端數(shù)據(jù)與配置數(shù)據(jù)的持久化存儲的數(shù)據(jù)庫系統(tǒng)。
3.2.3 Redis
Redis 是為減輕PostgreSQL 數(shù)據(jù)庫的訪問壓力,存放常用讀取數(shù)據(jù)的數(shù)據(jù)庫系統(tǒng)。
3.2.4 通訊服務(wù)
通訊服務(wù)主要是接收終端的數(shù)據(jù), 并保存至PostgreSQL 數(shù)據(jù)庫,其中工作狀態(tài)包含“ 主模式”與“ 備模式”。
3.2.5 監(jiān)控單元
監(jiān)控單元主要監(jiān)控A 機與B 機的狀態(tài),并根據(jù)A 機與B 機的狀態(tài)進行工作狀態(tài)的遷移, 其中機器的工作狀態(tài)包含通訊服務(wù)的工作狀態(tài)、PostgreSQL 的工作狀態(tài)與Redis 的工作狀態(tài)。 機器的狀態(tài)轉(zhuǎn)移,包含遷移狀態(tài)與終態(tài),其中,遷移狀態(tài)包含:待協(xié)商、待確認、嘗試進入主模式、嘗試進入備模式、嘗試提升為主模式,終態(tài)包括:主模式與備模式。 為進一步說明狀態(tài)遷移的流程,如圖3 所示,為A 機機器啟動的完整工作流程:

圖3 機器啟動流程圖
其中,條件a:返回的B 機狀態(tài)未知或未獲取到B 機的狀態(tài);條件b: 返回的B 機的狀態(tài)屬于狀態(tài)集2; 條件c: A 機的PostgreSQL 以備模式啟動、Redis 以備模式啟動與通訊服務(wù)為備模式; 條件d:A 機的PostgreSQL 以主模式啟動、Redis 以主模式啟動與通訊服務(wù)為主模式;條件e:返回的B 機的狀態(tài)屬于狀態(tài)集1;條件f:返回B 機的PostgreSQL 數(shù)據(jù)庫狀態(tài)(某表的數(shù)據(jù)量),確定A 機的優(yōu)先級比B 機的優(yōu)先級高; 條件g: 返回B 機的PostgreSQL 數(shù)據(jù)庫狀態(tài)(某表的數(shù)據(jù)量),確定A 機的優(yōu)先級比B機的優(yōu)先級低;條件h:A 機的優(yōu)先級比B 機的優(yōu)先級高;條件i:A 機的PostgreSQL 以主模式啟動、Redis 以主模式啟動與通訊服務(wù)為主模式;其中:狀態(tài)集1 包含:“ 協(xié)商”與“ 確認”;狀態(tài)集2 包含:“ 嘗試進入主模式”、“ 切換為主模式”與“ 主模式”;狀態(tài)集3 包含:“ 嘗試進入備模式”與“ 備模式”;初始狀態(tài):“ 協(xié)商”;最終狀態(tài):“ 主模式”與“ 備模式”。
3.2.6 控制單元
控制單元主要是完成機器狀態(tài)的切換與虛擬IP 的切換,其主要功能是基于keepalived 實現(xiàn)。 其中,機器狀態(tài)的切換是通過在keepalived 中定義切換到相應(yīng)模式時的執(zhí)行腳本來實現(xiàn),虛擬IP 的切換通過keepalived 的工作優(yōu)先級來確定建立虛擬IP 的機器。
3.2.7 同步單元
同步的單元包含PostgreSQL 數(shù)據(jù)庫與Redis 數(shù)據(jù)庫的數(shù)據(jù)同步。 PostgreSQL 數(shù)據(jù)庫的同步是基于異步流復制傳遞預(yù)寫日志的方式來實現(xiàn)的。 A 機與B 機的PostgreSQL 數(shù)據(jù)庫在使用流復制時, 只要處于主模式工作的機器的PostgreSQL 數(shù)據(jù)庫一產(chǎn)生日志, 就會馬上傳遞到處于備模式工作的機器的PostgreSQL數(shù)據(jù)庫。 假設(shè)A 機器原來工作在主模式,當A 機的數(shù)據(jù)庫工作異?;蛘弑豢刂茊卧袚Q為備模式工作狀態(tài)時, 機器B 上以主模式重啟數(shù)據(jù)庫,在數(shù)據(jù)庫剛重啟時,會重放B 機的數(shù)據(jù)庫狀態(tài)切換之前最后一個checkpoint 點之后的WAL 日志,把數(shù)據(jù)庫推導到自動進入工作狀態(tài), 數(shù)據(jù)庫在完成恢復后會自動進入正常狀態(tài),此時的A 機器在控制單元的協(xié)助下重新啟動,以備模式啟動,一直等待A 機的新的WAL 日志,如果有新的日志過來,則自定進行重放,直到A 機器工作異常,B 機以主模式狀態(tài)工作,再讓B 機的數(shù)據(jù)庫進入主模式工作, 實現(xiàn)了A 機器上的數(shù)據(jù)庫出故障時,B 機器的上的數(shù)據(jù)庫能夠接管的功能。
Redis 的數(shù)據(jù)同步分為全量同步與增量同步兩個過程, 其中全量同步主要是指從模式的Redis 數(shù)據(jù)庫啟動的時候的初始化過程,增量同步指的是主模式的Redis 每執(zhí)行一個寫命令就像從模式的Redis 發(fā)送相同的寫命令,從模式的Redis 接收并執(zhí)行收到的寫命令。 假設(shè)A 機的Redis 數(shù)據(jù)庫以master 模式啟動,B 機的Redis 數(shù)據(jù)庫以slave 模式啟動, 此時當B 機的Redis 數(shù)據(jù)庫在啟動的初始化階段需要將A 機的Redis 數(shù)據(jù)庫的數(shù)據(jù)全部復制一遍。 具體步驟如下:a. B 機的Redis 數(shù)據(jù)庫連接A 機的Redis,并發(fā)送同步命令;b. A 機的Redis 接收到同步命令后,開始執(zhí)行數(shù)據(jù)保存命令, 生成快照文件并使用緩沖區(qū)記錄此后執(zhí)行的所有寫命令;c. A 機的Redis 數(shù)據(jù)庫將快照文件發(fā)送至B 機的Redis 數(shù)據(jù)庫, 并在發(fā)送期間記錄被執(zhí)行的寫命令;d. B 機的Redis 數(shù)據(jù)庫接收到快照文件后丟棄所有數(shù)據(jù),載入收到的快照;e. A 機的Redis 發(fā)送完快照文件,繼續(xù)向B 機的Redis 發(fā)送緩沖區(qū)的寫命令;f. B 機的Redis 完成快照文件的載入后, 開始接收命令請求,并持續(xù)接收來自A 機的緩沖區(qū)的寫命令。
基于有限狀態(tài)機機制的雙機熱備系統(tǒng)采用傳軟件的方式實現(xiàn),具有節(jié)約成本與部署方便優(yōu)點,并且對外提供了一系列的信息交互接口, 使得現(xiàn)有的人員定位系統(tǒng)的雙機熱備運行更加簡單、穩(wěn)定、可靠。