段小芳,劉 丹
(中國電子科技集團公司第三十研究所,四川 成都 610041)
在無線網(wǎng)絡技術研究中,存儲各種重要活動中的無線網(wǎng)絡信號數(shù)據(jù),并在后期對存儲的數(shù)據(jù)進行深入分析,對彌補網(wǎng)絡功能不足和對網(wǎng)絡性能提升具有重要意義。后期的各種分析必須以數(shù)據(jù)的實時存儲為前提,數(shù)據(jù)存儲的完整性、時效性等直接影響到后期分析所能獲取情報知識的程度。因此針對無線網(wǎng)絡的大數(shù)據(jù)實時高效存儲是必須解決的一項關鍵技術。
在當今世界對自主知識產(chǎn)權越發(fā)重視的背景下,各種設備及技術的國產(chǎn)化需求日益迫切,國產(chǎn)化操作系統(tǒng)的應用日漸普及。在這種背景下,Qt 作為一種可以跨操作系統(tǒng)的軟件開發(fā)平臺具有其明顯的優(yōu)勢,通過一次開發(fā),多處編譯,輕易地實現(xiàn)跨平臺移植,因其順應國產(chǎn)化的需求越加廣泛地被應用到各種軟件開發(fā)中。
本文基于Qt 平臺,采用內存映射技術,設計并實現(xiàn)了一種大數(shù)據(jù)文件的實時存儲方案,可實現(xiàn)對無線信號大數(shù)據(jù)量的實時存儲,并通過設計有效的索引機制,實現(xiàn)對存儲文件的高效讀取。最后通過測試程序對內存映射大數(shù)據(jù)文件實時存儲技術進行了實驗驗證。
在無線網(wǎng)絡信號的存儲應用中,可以將需要進行數(shù)據(jù)存儲的情況分為兩類:一是接收特定頻率范圍內的所有目標信號;二類是接收已知信號特征的特定目標信號。
接收特定頻率范圍內的所有目標信號時,為了后期分析處理過程中能將信號完全還原,需依據(jù)Nyquist 采樣原理,存儲以頻率帶寬2 倍的采樣率采樣后的中頻信號,頻率范圍的大小決定了需要存儲的數(shù)據(jù)量的大小。以網(wǎng)絡工作頻率帶寬為150 MHz為例,需要以300 M sample/s,16 bits 采樣,1 秒鐘的數(shù)據(jù)量為480 MB,這樣高的寫入速率通常的文件I/O 操作根本無法滿足需求。
接收已知信號特征的特定目標信號時,通過解調解碼可獲取信號的某些特征,可僅存儲解調解碼后的數(shù)據(jù),此時需存儲的數(shù)據(jù)量遠遠小于全頻段采樣數(shù)據(jù),數(shù)據(jù)量由網(wǎng)絡通信協(xié)議和流量決定。如果僅考慮文件寫入速率,采用普通的文件I/O 似乎可以滿足需求。但是在實際應用中,對無線信號的偵察站通常無人值守,對目標信號的存儲至少應滿足連續(xù)24 小時存儲的需求,長時間數(shù)據(jù)存儲的大數(shù)據(jù)量不可忽視?;谖募蘒/O 操作的普通文件操作,針對如此大的數(shù)據(jù)文件,不僅其存儲速度慢,更容易在存儲過程中出現(xiàn)壓力過大、運行不可靠等問題。
本文將在Qt 平臺下采用內存映射技術,設計實現(xiàn)滿足上述存儲需求的大數(shù)據(jù)實時存儲方案。并針對在后期離線分析時,需要在大數(shù)據(jù)文件中搜索某些關鍵數(shù)據(jù)進行深入分析的需求,設計了有效的文件索引機制,極大地方便對大數(shù)據(jù)文件進行數(shù)據(jù)搜索的操作。
內存映射文件,是由一個文件到一塊內存的映射。通過內存映射文件可以保留一個地址空間的區(qū)域,同時將物理存儲器提交給此區(qū)域,內存文件映射的物理存儲器來自一個已經(jīng)存在于磁盤上的文件,而且在對該文件進行操作之前必須首先對文件進行映射。使用內存映射文件處理存儲于磁盤上的文件時,將不必再對文件執(zhí)行I/O 操作,數(shù)據(jù)存儲速度大大提高,使得內存映射文件在處理大數(shù)據(jù)量的文件時能起到相當重要的作用[1-3]。
內存映射技術最大的優(yōu)點在于,不對文件執(zhí)行I/O 操作就能處理存儲于磁盤上的文件,這樣做在數(shù)據(jù)處理的過程中將不需要為所有的文件重新申請并分配緩存,這類緩存操作將由系統(tǒng)直接進行管理,從而大大提高了系統(tǒng)的運行效率[4]。
Qt 中采用內存映射進行文件存儲的標準流程如下圖1 所示。
圖1 內存映射數(shù)據(jù)存儲的標準的流程圖
但是在大數(shù)據(jù)文件讀寫應用中,由于數(shù)據(jù)文件遠超Windows 進程能分配的最大地址空間(2 GB),只能將數(shù)據(jù)文件分段映射,每次只映射文件的一部分(不能超過2 GB)[3]。在做方案設計時,我們以滿足數(shù)據(jù)量的極限情況為目標,但是在實際情況下的數(shù)據(jù)量往往遠小于極限情況,因此本方案設計了一種依據(jù)實際數(shù)據(jù)量動態(tài)調整數(shù)據(jù)文件長度的機制,可更加合理有效的使用內存和磁盤空間。本方案的內存映射文件存儲流程如圖2 所示。
圖2 大數(shù)據(jù)文件內存映射數(shù)據(jù)存儲的流程圖
3.2.1 關鍵函數(shù)說明
在圖2 大數(shù)據(jù)文件內存映射存儲數(shù)據(jù)的流程中涉及的關鍵函數(shù)描述如下。
(1)QFile::QFile(const QString &name)
QFile 構造函數(shù),用于創(chuàng)建文件對象。參數(shù)name 表示在磁盤上需要操作的文件名稱。
(2)bool QFile::open(OpenMode mode)
用于打開文件,如果指定的文件不存在,將自動創(chuàng)建。參數(shù)mode 表示打開文件的方式,可以選擇僅寫入,僅讀取,或者可讀可寫等。
(3)bool QFile::resize(qint64 sz)
用于設置文件的長度,參數(shù)sz 表示文件的長度。
(4)uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions)
用于對文件進行映射,返回值為映射后的內存指針。參數(shù)offset 表示需要進行內存映射的數(shù)據(jù)段在相對文件起始位置的偏移值;參數(shù)size 表示需要映射的數(shù)據(jù)塊的大小。QFileDevice 類是QFile 類的父類。
(5)bool QFileDevice::unmap(uchar *address)
用于取消內存映射,參數(shù)address 上述映射成功的內存指針。
(6)void QFileDevice::close()用于關閉文件
3.2.2 關鍵步驟說明
圖2 流程圖中,有幾個關鍵步驟說明如下:
(1)設置文件長度為BLOCK_LEN*m_count
BLOCK_LEN 為自定義的文件初始長度,由于Windows 進程能分配的最大虛擬地址空間為4 GB,但是在實際應用中4 GB 的空間不能全部被占用進行內存映射實現(xiàn)數(shù)據(jù)存儲。m_count 為進行文件長度擴展的次數(shù),初始值為1。
該步驟的含義描述:新建文件時,將文件長度設置為BLOCK_LEN,假設BLOCK_LEN 等于1 GB。當存儲的數(shù)據(jù)將該1 GB 的文件長度寫滿以后,動態(tài)擴展文件的長度到2 GB,依次類推,當前的數(shù)據(jù)文件不斷被寫滿后,不斷的將文件長度增加1 GB。這樣可有效合理的利用內存和磁盤空間。
(2)對文件進行映射獲取映射后的內存指針
該步驟的含義描述:假設新建文件時,文件長度為1 GB,這時進行文件映射可以將整個文件的1 GB 空間進行映射,獲取這1 GB 內存空間的指針。當文件長度擴展到2 GB 時,由于文件的前1 GB 空間已經(jīng)寫滿了數(shù)據(jù),此時只需要映射文件的后1 GB長度。依次類推,當文件長度不斷被擴展后,不管擴展后的文件長度有多長,始終只需要映射文件的最后1 GB 空間。
(3)文件寫入結束后調整文件長度為實際數(shù)據(jù)的長度
如上所述將文件擴展長度的步進設置為1 GB,如果剛擴展文件后,就需要停止數(shù)據(jù)寫入,如果就這樣取消映射關閉文件,那么磁盤上的數(shù)據(jù)文件中將會存在1 GB 的無效數(shù)據(jù),浪費磁盤存儲空間。
為了避免這種情況,在Visual Studio 等平臺下的通常做法是以寫入的實際數(shù)據(jù)長度創(chuàng)建新的文件進行內存映射,將數(shù)據(jù)從原文件復制到新的文件。當進行大數(shù)據(jù)文件的拷貝時,同樣受進程可分配最大地址空間的限制,必須多次拷貝,極大的影響數(shù)據(jù)存儲處理的效率。在本方案中完成數(shù)據(jù)寫入后,利用Qt 系統(tǒng)提供的QFile::resize 函數(shù)直接將原數(shù)據(jù)文件的長度設置為實際數(shù)據(jù)的長度,此過程可直接保留原數(shù)據(jù)文件中的有效數(shù)據(jù)刪除無效數(shù)據(jù),省去了新數(shù)據(jù)文件的創(chuàng)建和數(shù)據(jù)拷貝過程,有效地避免磁盤空間浪費的同時也提高了數(shù)據(jù)存儲處理的效率。
(4)流程中多次反復打開關閉文件對象
在圖2 的流程中,在每次進行內存映射或者取消內存映射前都會打開文件,在映射或者取消映射完成后及時關閉文件,這樣做的原因是為了避免長期對磁盤文件的占用,而導致其它應用對該文件的訪問無效。例如,在實時存儲數(shù)據(jù)的過程中,可能需要通過其它應用程序實時對存儲的數(shù)據(jù)文件進行讀取分析處理,在內存映射存儲數(shù)據(jù)過程中及時關閉文件可以有效地避免對文件的訪問沖突。
對數(shù)據(jù)文件的索引設計通常采用的方式為,在數(shù)據(jù)文件的起始段中專門預留一部分空間用來記錄索引信息。但是在大數(shù)據(jù)存儲應用中,無法估計需要記錄的索引信息的長度,如果預留記錄索引的空間不足則必須新建數(shù)據(jù)文件,當數(shù)據(jù)存儲時間較長時會產(chǎn)生很多數(shù)據(jù)文件,不便于對數(shù)據(jù)文件的管理。如果預留記錄索引的空間較大,在應用中由于文件的長度的動態(tài)擴展,使得預留較大空間記錄索引信息既不便于實現(xiàn)也可能造成存儲空間浪費。
在本方案中,采用了將源數(shù)據(jù)和索引信息獨立記錄在兩個文件中的方式。時間信息通常是所有無線信號數(shù)據(jù)所具有的關鍵信息,將時間每進行1 秒鐘后存儲數(shù)據(jù)相對數(shù)據(jù)文件起始的偏移作為索引值,記錄在索引文件中。索引文件的結構,以及在數(shù)據(jù)文件的寫入過程中如何在索引文件中記錄索引值的描述如下圖3 所示。索引文件的讀寫同樣可采用內存映射的方式實現(xiàn)。
圖3 索引文件的結構和索引值記錄描述
按照以上方式,如果在索引文件中以10 字節(jié)表示年月日時分秒在內的時間信息,以8 字節(jié)表示偏移地址,那么只需要占用675 KB 的磁盤空間就可以為連續(xù)24 小時的數(shù)據(jù)存儲建立索引,以極小的磁盤空間換取了數(shù)據(jù)搜索效率的極大提高。
測試環(huán)境描述:Windows 7 旗艦版64 位操作系統(tǒng),Intel Core i7-377os 處理器,3.10 GHz CPU,8 GB RAM。
在以上測試環(huán)境下編寫測試程序,首先模擬產(chǎn)生了512 B 的數(shù)據(jù),然后以內存映射和傳統(tǒng)I/O 兩種方式創(chuàng)建文件[5],并循環(huán)將模擬的512 B 數(shù)據(jù)寫入文件,直到文件寫滿,分別記錄兩種文件寫入方式創(chuàng)建并寫滿2 GB、5 GB、10 GB 文件的耗時和速率對比,如下表1 所示。計時起點為QFile::open,計時終點為文件寫滿后取消文件映射,關閉文件對象。
表1 兩種文件寫入方式對比
從上述測試結果可以看出內存映射寫入文件的速率遠高于傳統(tǒng)I/O 文件寫入的速率。以表1 中內存映射文件的速率1500 MB/s 計算,理論可滿足375 MHz 帶寬,750 M sample/s,16 bits 采樣的無線信號中頻采樣數(shù)據(jù)存儲需求。
上述測試結果是在測試程序功能相對單一的情況下獲取,在實際應用軟件功能復雜的情況下,可能會對文件存儲處理速率稍有影響,但至少可保證滿足帶寬小于300 MHz 的無線信號中頻采樣數(shù)據(jù)存儲需求。
本文以無線網(wǎng)絡信號的存儲需求和技術設備的國產(chǎn)化需求為背景,在Qt 平臺下設計了一種基于內存映射技術的大數(shù)據(jù)實時存儲方案。并通過編寫測試程序,驗證了該方案既可滿足對無線信號解調數(shù)據(jù)連續(xù)24 小時的實時存儲需求,也可滿足帶寬小于300 MHz 的無線信號中頻采樣數(shù)據(jù)的實時存儲需求。同時由于該方案基于Qt 平臺設計,也解決了國產(chǎn)化背景下軟件的跨平臺移植問題。