周 帆
(中國(guó)兵器工業(yè)第203研究所,西安 710065)
隨著精確制導(dǎo)武器的信息化程度不斷提高,制導(dǎo)部件、控制系統(tǒng)以及火控、偵指系統(tǒng)之間相互交換的數(shù)據(jù)量也隨之激增。半實(shí)物仿真中需要對(duì)過(guò)程變量進(jìn)行實(shí)時(shí)記錄并存儲(chǔ),便于設(shè)計(jì)人員進(jìn)行事后分析。目前,一般的做法是,整個(gè)仿真實(shí)驗(yàn)系統(tǒng)部署一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器,數(shù)據(jù)采集單元將采集到的數(shù)據(jù)以文件形式保存,在實(shí)驗(yàn)完成后將所有的數(shù)據(jù)文件通過(guò)特定的格式轉(zhuǎn)換腳本或轉(zhuǎn)換軟件導(dǎo)入數(shù)據(jù)庫(kù)。
這種應(yīng)用模式的問(wèn)題是:1)應(yīng)用復(fù)雜度高。目前系統(tǒng)中一般都采用微軟的SQL Server、MySQL等數(shù)據(jù)庫(kù)產(chǎn)品,但這些產(chǎn)品都是面向大型企業(yè)級(jí)應(yīng)用,雖然其功能非常強(qiáng)大、成熟度很高,但配置復(fù)雜、使用難度較高以及需要專(zhuān)門(mén)的維護(hù)人員等約束使得部分實(shí)驗(yàn)系統(tǒng)中的數(shù)據(jù)庫(kù)利用率極低,沒(méi)有起到應(yīng)有的作用。2)操作流程復(fù)雜。各種數(shù)據(jù)采集節(jié)點(diǎn)將數(shù)據(jù)按一定的格式保存,在導(dǎo)入數(shù)據(jù)庫(kù)時(shí),需要針對(duì)不同的格式提供專(zhuān)門(mén)的工具進(jìn)行數(shù)據(jù)抓取后錄入,增加了操作復(fù)雜度。3)價(jià)格昂貴,性?xún)r(jià)比低??紤]到半實(shí)物仿真實(shí)驗(yàn)系統(tǒng)中一般只能用到數(shù)據(jù)庫(kù)系統(tǒng)相當(dāng)小的一個(gè)功能子集,其性?xún)r(jià)比是相當(dāng)?shù)偷摹?/p>
鑒于以上三點(diǎn),文中提出了采用輕量級(jí)的嵌入式數(shù)據(jù)庫(kù)系統(tǒng)SQLite為基礎(chǔ)的半實(shí)物仿真系統(tǒng)設(shè)計(jì)方案。
SQLite是一款輕量級(jí)的開(kāi)放源碼數(shù)據(jù)管理系統(tǒng),支持絕大多數(shù)SQL92標(biāo)準(zhǔn)操作。最初是由D.Richard Hipp為美國(guó)海軍艦載反導(dǎo)系統(tǒng)設(shè)計(jì),提供免安裝、免維護(hù)的數(shù)據(jù)存儲(chǔ)、管理能力,用于取代反導(dǎo)系統(tǒng)中龐大、復(fù)雜的Informix后端數(shù)據(jù)庫(kù)服務(wù)器。2000年夏天SQLite推出1.0版本,到目前為止,SQLite已經(jīng)發(fā)布3.7.11 版。
1)免維護(hù)。SQLite數(shù)據(jù)庫(kù)管理系統(tǒng)無(wú)需安裝即可直接使用,用戶(hù)可以直接對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,不需要專(zhuān)門(mén)的數(shù)據(jù)庫(kù)管理員首先去創(chuàng)建相應(yīng)的數(shù)據(jù)庫(kù)實(shí)例。系統(tǒng)宕機(jī)或斷電不會(huì)導(dǎo)致數(shù)據(jù)丟失的問(wèn)題。
2)無(wú)需服務(wù)器,通常使用的各種數(shù)據(jù)庫(kù)產(chǎn)品都有一個(gè)服務(wù)器進(jìn)程,用戶(hù)需要對(duì)數(shù)據(jù)庫(kù)操作時(shí)都要用到一些進(jìn)程間通信的方式來(lái)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)。而對(duì)于SQLite來(lái)說(shuō),用戶(hù)進(jìn)程可以對(duì)存儲(chǔ)在硬盤(pán)上的數(shù)據(jù)庫(kù)文件直接進(jìn)行操作,不需要任何中間環(huán)節(jié)。
3)單一數(shù)據(jù)庫(kù)文件。SQLite數(shù)據(jù)庫(kù)和硬盤(pán)上的一個(gè)普通文件沒(méi)有任何區(qū)別,可以直接刪除,或移動(dòng)到其它任何目錄或載體中。而普通的數(shù)據(jù)庫(kù)管理系統(tǒng)一般都把數(shù)據(jù)庫(kù)文件放在一個(gè)特定的目錄下,只有數(shù)據(jù)庫(kù)管理系統(tǒng)可以訪(fǎng)問(wèn)它,雖然這增加了數(shù)據(jù)的安全性,但是隨之而來(lái)的建立和維護(hù)復(fù)雜度卻大大提高。
4)穩(wěn)定的跨平臺(tái)支持能力。SQLite數(shù)據(jù)庫(kù)文件格式是跨平臺(tái)的,一旦數(shù)據(jù)庫(kù)文件創(chuàng)建后,不論是Windows、類(lèi)Unix平臺(tái),32位或64位平臺(tái)都可以直接使用。
5)占用資源少,處理速度快,經(jīng)過(guò)優(yōu)化的SQLite僅為350KiB左右。
某型精確制導(dǎo)武器半實(shí)物仿真系統(tǒng)中,采用SQLite取代原先的SQL Server 2000數(shù)據(jù)庫(kù),系統(tǒng)部署圖如圖1所示。
圖1 SQLite在仿真系統(tǒng)中的部署圖
SQLite數(shù)據(jù)庫(kù)直接部署在數(shù)據(jù)采集節(jié)點(diǎn)上,采集節(jié)點(diǎn)的業(yè)務(wù)邏輯不用發(fā)生任何改變,只需要將對(duì)文件的操作替換為對(duì)本地SQLite數(shù)據(jù)庫(kù)的操作即可。下面給出使用SQLite實(shí)現(xiàn)采集節(jié)點(diǎn)業(yè)務(wù)邏輯的代碼片段:
至此,數(shù)據(jù)庫(kù)就已準(zhǔn)備就緒可以通過(guò)SQL語(yǔ)句進(jìn)行操作了。在數(shù)據(jù)記錄線(xiàn)程中,首先從數(shù)據(jù)總線(xiàn)或數(shù)據(jù)緩沖區(qū)讀取一幀數(shù)據(jù),然后將數(shù)據(jù)組幀到一條SQL的insert語(yǔ)句中,再通過(guò)SQLite3_exec執(zhí)行這條insert語(yǔ)句即可數(shù)據(jù)的入庫(kù)操作:
最后,使用SQLite3_close(db)關(guān)閉數(shù)據(jù)庫(kù)即完成了一次數(shù)據(jù)記錄與入庫(kù)的操作。
在該半實(shí)物仿真系統(tǒng)中,需記錄的過(guò)程變量為60~80個(gè),這里以80個(gè)為例,即每次向數(shù)據(jù)庫(kù)中插入80個(gè)變量,進(jìn)行100次插入操作考察數(shù)據(jù)錄入的時(shí)間。圖2給出了將數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)的時(shí)間測(cè)試結(jié)果(測(cè)試平臺(tái):硬件:Intel Pentium Dual 2.2GHz,1GB DDR2內(nèi)存,7200RPM SATA-II硬盤(pán),軟件:Windows XP sp2 ,visual studio C++6.0 sp6,SQLite 3.7.11)。
圖2 數(shù)據(jù)庫(kù)插入操作時(shí)間
從圖2可以看出,直接使用SQLite執(zhí)行一條SQL的插入語(yǔ)句時(shí)延范圍在78~157ms,均值為98.29ms。數(shù)據(jù)表明這樣的數(shù)據(jù)錄入效率將嚴(yán)重影響記錄節(jié)點(diǎn)的運(yùn)行,對(duì)于項(xiàng)目采樣頻率為1kHz的需求而言,一次數(shù)據(jù)錄入將導(dǎo)致丟失100幀的數(shù)據(jù)。這種情況下,如果要使用SQLite數(shù)據(jù)庫(kù),只能在采集任務(wù)開(kāi)始前,開(kāi)辟足夠的內(nèi)存空間,所有的數(shù)據(jù)先記錄在內(nèi)存中,待一次采集任務(wù)完成后將所有數(shù)據(jù)再插入數(shù)據(jù)庫(kù)中。這種方案有兩個(gè)問(wèn)題:1)采集任務(wù)完成后的數(shù)據(jù)錄入過(guò)程耗時(shí)過(guò)長(zhǎng),這里還是以每幀80個(gè)變量為例,數(shù)據(jù)采集時(shí)間為20s,采集完成后的數(shù)據(jù)入庫(kù)時(shí)延如圖3所示,橫坐標(biāo)為測(cè)試次數(shù),縱坐標(biāo)為數(shù)據(jù)錄入時(shí)間(單位:min)。雖然對(duì)數(shù)據(jù)采集與保存本身沒(méi)影響,但30min左右的數(shù)據(jù)入庫(kù)時(shí)間是無(wú)法容忍的。2)對(duì)于長(zhǎng)時(shí)間的數(shù)據(jù)采集任務(wù),有內(nèi)存耗盡的潛在問(wèn)題。
這里提出兩種解決方案。1)對(duì)大批量數(shù)據(jù)入庫(kù)操作進(jìn)行優(yōu)化,縮短數(shù)據(jù)錄取時(shí)間;2)優(yōu)化數(shù)據(jù)庫(kù)單次插入數(shù)據(jù)的延時(shí),采用多線(xiàn)程技術(shù)在數(shù)據(jù)采集的同時(shí)完成數(shù)據(jù)的入庫(kù)工作。
圖3 批量數(shù)據(jù)入庫(kù)時(shí)間
在數(shù)據(jù)庫(kù)管理系統(tǒng)中,事務(wù)(Transaction)被定義為對(duì)特定數(shù)據(jù)庫(kù)的一組SQL操作,這組對(duì)數(shù)據(jù)庫(kù)的操作要么全部執(zhí)行,要么都不執(zhí)行。在SQLite中每一條INSERT/UPDATE語(yǔ)句都默認(rèn)的被當(dāng)作一個(gè)事務(wù)被執(zhí)行,每一次執(zhí)行就涉及一次數(shù)據(jù)庫(kù)的打開(kāi)-寫(xiě)數(shù)據(jù)庫(kù)-關(guān)閉數(shù)據(jù)庫(kù)的操作,因此大大延長(zhǎng)了數(shù)據(jù)庫(kù)操作的時(shí)間。因此,可以將批量的INSERT/UPDATE語(yǔ)句顯式的定義為一組事務(wù),代碼如下所示:
圖4為使用事務(wù)處理批量插入后的系統(tǒng)數(shù)據(jù)錄入所需的時(shí)間。
對(duì)比圖3可以看出,使用事務(wù)處理后,系統(tǒng)的數(shù)據(jù)錄入時(shí)間縮短到優(yōu)化前的約1/900。以達(dá)到用戶(hù)可接受的范圍。
圖4 采用事務(wù)后批量數(shù)據(jù)入庫(kù)時(shí)間
SQLite的同步(synchronous)選項(xiàng)相當(dāng)于一種同步IO機(jī)制,所有對(duì)數(shù)據(jù)庫(kù)的修改都必須等待本次操作寫(xiě)入到磁盤(pán)上后才返回。當(dāng)頻繁的對(duì)數(shù)據(jù)庫(kù)進(jìn)行INSERT/UPDATE時(shí),可以選擇關(guān)閉同步選項(xiàng),進(jìn)一步提高數(shù)據(jù)入庫(kù)的速度:
圖5是關(guān)閉同步選項(xiàng)前后,批量數(shù)據(jù)錄入時(shí)間的對(duì)比。
可以看到關(guān)閉同步選項(xiàng)后,數(shù)據(jù)錄入操作時(shí)間可再縮短100ms左右。
圖5 同步選項(xiàng)對(duì)批量數(shù)據(jù)錄入時(shí)間影響對(duì)比
上面針對(duì)數(shù)據(jù)采集完成后,數(shù)據(jù)批量入庫(kù)時(shí)的性能進(jìn)行了優(yōu)化。如果希望在數(shù)據(jù)采集的同時(shí)進(jìn)行數(shù)據(jù)的入庫(kù)工作,那么可以組合使用關(guān)閉同步選項(xiàng)以及更改 SQLite默認(rèn)日志模式的方式來(lái)提高單次INSERT操作的效率。SQLite中日志是在系統(tǒng)遇到宕機(jī)或斷電時(shí)用來(lái)恢復(fù)數(shù)據(jù)庫(kù),保持?jǐn)?shù)據(jù)庫(kù)完整性的措施,默認(rèn)情況下日志是隨著對(duì)數(shù)據(jù)庫(kù)的操作一起寫(xiě)入磁盤(pán)的,這里可以將其修改為內(nèi)存記錄模式:
圖6 優(yōu)化后單次數(shù)據(jù)插入時(shí)間對(duì)比
);
圖6為針對(duì)單次插入數(shù)據(jù)庫(kù)操作使用不同優(yōu)化選項(xiàng)的測(cè)試結(jié)果。
結(jié)合以上提到的集中優(yōu)化策略,向SQLite中單次插入數(shù)據(jù)的時(shí)間可以控制在0.2ms以?xún)?nèi),是優(yōu)化前的1/500。對(duì)于采樣周期為1ms的采集節(jié)點(diǎn),完全能夠?qū)崿F(xiàn)邊采樣邊入庫(kù)的操作模式。
SQLite的內(nèi)存數(shù)據(jù)庫(kù)模式就是直接將數(shù)據(jù)庫(kù)創(chuàng)建在主存中,相對(duì)于磁盤(pán),內(nèi)存的數(shù)據(jù)讀寫(xiě)速度要高出幾個(gè)數(shù)量級(jí),將數(shù)據(jù)保存在內(nèi)存中相比從磁盤(pán)上訪(fǎng)問(wèn)能夠極大的提高應(yīng)用的性能。圖7是采用內(nèi)存數(shù)據(jù)庫(kù)模式時(shí),數(shù)據(jù)入庫(kù)的時(shí)間與優(yōu)化后的磁盤(pán)數(shù)據(jù)庫(kù)單次插入數(shù)據(jù)時(shí)間對(duì)比曲線(xiàn)。
采用內(nèi)存數(shù)據(jù)庫(kù),在不進(jìn)行任何優(yōu)化時(shí)的單次數(shù)據(jù)錄入時(shí)間與優(yōu)化后的磁盤(pán)數(shù)據(jù)庫(kù)基本相當(dāng)。因此在采集節(jié)點(diǎn)也可采用內(nèi)存數(shù)據(jù)庫(kù)的模式實(shí)現(xiàn)數(shù)據(jù)的邊采集邊錄入。
圖7 內(nèi)存數(shù)據(jù)庫(kù)模式數(shù)據(jù)入庫(kù)時(shí)間
以上幾點(diǎn)優(yōu)化方法都是通過(guò)對(duì)SQLite本身進(jìn)行各種優(yōu)化選項(xiàng)的組合,從而提高其數(shù)據(jù)錄入效率來(lái)滿(mǎn)足實(shí)際需求。磁盤(pán)數(shù)據(jù)庫(kù)之所以操作時(shí)延長(zhǎng),其瓶頸在于硬盤(pán)的訪(fǎng)問(wèn)速度。如果更換為SSD固態(tài)硬盤(pán),其操作效率將大大提高,圖8為在SSD固態(tài)硬盤(pán)上相應(yīng)的測(cè)試曲線(xiàn)。
使用SSD硬盤(pán)后,同樣在未經(jīng)任何優(yōu)化的條件下,SSD硬盤(pán)上的插入性能較傳統(tǒng)硬盤(pán)提高了近200倍。而經(jīng)過(guò)優(yōu)化后,SSD硬盤(pán)上的插入性能也提高了近2倍多??梢?jiàn)SSD硬盤(pán)的使用對(duì)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)性能的提高還是很明顯的。
圖8 SSD與普通硬盤(pán)數(shù)據(jù)錄入時(shí)間對(duì)比
文中通過(guò)5點(diǎn)優(yōu)化策略切實(shí)的提高SQLite數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)速度的方案,使SQLite數(shù)據(jù)庫(kù)的性能滿(mǎn)足半實(shí)物仿真實(shí)驗(yàn)中實(shí)時(shí)數(shù)據(jù)錄入需求。同時(shí)也證明了SQLite在功能和性能上可以很好的取代目前使用傳統(tǒng)商業(yè)數(shù)據(jù)庫(kù),解決半實(shí)物仿真系統(tǒng)中數(shù)據(jù)庫(kù)投入大、維護(hù)難、利用率低的問(wèn)題。
[1](美)Grant Allen,Mike Owens.SQLite權(quán)威指南[M].2版.北京:電子工業(yè)出版社,2012:21-137.
[2]http://www.sqlite.org,SQLite[OL].
[3]蔡勇,王勇.嵌入式數(shù)據(jù)庫(kù)SQLite在測(cè)控系統(tǒng)設(shè)計(jì)中的應(yīng)用[J].電子測(cè)試,2011(10):89-93.
[4]萬(wàn)瑪寧,關(guān)永,韓相軍.嵌入式數(shù)據(jù)庫(kù)典型技術(shù)SQLite和Berkeley DB 的研究[J].微計(jì)算機(jī)信息,2006,22(1/2):91-93.