段小芳,劉 丹
(中國電子科技集團公司第三十研究所,四川 成都 610041)
在無線網絡技術研究中,存儲各種重要活動中的無線網絡信號數據,并在后期對存儲的數據進行深入分析,對彌補網絡功能不足和對網絡性能提升具有重要意義。后期的各種分析必須以數據的實時存儲為前提,數據存儲的完整性、時效性等直接影響到后期分析所能獲取情報知識的程度。因此針對無線網絡的大數據實時高效存儲是必須解決的一項關鍵技術。
在當今世界對自主知識產權越發重視的背景下,各種設備及技術的國產化需求日益迫切,國產化操作系統的應用日漸普及。在這種背景下,Qt 作為一種可以跨操作系統的軟件開發平臺具有其明顯的優勢,通過一次開發,多處編譯,輕易地實現跨平臺移植,因其順應國產化的需求越加廣泛地被應用到各種軟件開發中。
本文基于Qt 平臺,采用內存映射技術,設計并實現了一種大數據文件的實時存儲方案,可實現對無線信號大數據量的實時存儲,并通過設計有效的索引機制,實現對存儲文件的高效讀取。最后通過測試程序對內存映射大數據文件實時存儲技術進行了實驗驗證。
在無線網絡信號的存儲應用中,可以將需要進行數據存儲的情況分為兩類:一是接收特定頻率范圍內的所有目標信號;二類是接收已知信號特征的特定目標信號。
接收特定頻率范圍內的所有目標信號時,為了后期分析處理過程中能將信號完全還原,需依據Nyquist 采樣原理,存儲以頻率帶寬2 倍的采樣率采樣后的中頻信號,頻率范圍的大小決定了需要存儲的數據量的大小。以網絡工作頻率帶寬為150 MHz為例,需要以300 M sample/s,16 bits 采樣,1 秒鐘的數據量為480 MB,這樣高的寫入速率通常的文件I/O 操作根本無法滿足需求。
接收已知信號特征的特定目標信號時,通過解調解碼可獲取信號的某些特征,可僅存儲解調解碼后的數據,此時需存儲的數據量遠遠小于全頻段采樣數據,數據量由網絡通信協議和流量決定。如果僅考慮文件寫入速率,采用普通的文件I/O 似乎可以滿足需求。但是在實際應用中,對無線信號的偵察站通常無人值守,對目標信號的存儲至少應滿足連續24 小時存儲的需求,長時間數據存儲的大數據量不可忽視。基于文件I/O 操作的普通文件操作,針對如此大的數據文件,不僅其存儲速度慢,更容易在存儲過程中出現壓力過大、運行不可靠等問題。
本文將在Qt 平臺下采用內存映射技術,設計實現滿足上述存儲需求的大數據實時存儲方案。并針對在后期離線分析時,需要在大數據文件中搜索某些關鍵數據進行深入分析的需求,設計了有效的文件索引機制,極大地方便對大數據文件進行數據搜索的操作。
內存映射文件,是由一個文件到一塊內存的映射。通過內存映射文件可以保留一個地址空間的區域,同時將物理存儲器提交給此區域,內存文件映射的物理存儲器來自一個已經存在于磁盤上的文件,而且在對該文件進行操作之前必須首先對文件進行映射。使用內存映射文件處理存儲于磁盤上的文件時,將不必再對文件執行I/O 操作,數據存儲速度大大提高,使得內存映射文件在處理大數據量的文件時能起到相當重要的作用[1-3]。
內存映射技術最大的優點在于,不對文件執行I/O 操作就能處理存儲于磁盤上的文件,這樣做在數據處理的過程中將不需要為所有的文件重新申請并分配緩存,這類緩存操作將由系統直接進行管理,從而大大提高了系統的運行效率[4]。
Qt 中采用內存映射進行文件存儲的標準流程如下圖1 所示。

圖1 內存映射數據存儲的標準的流程圖
但是在大數據文件讀寫應用中,由于數據文件遠超Windows 進程能分配的最大地址空間(2 GB),只能將數據文件分段映射,每次只映射文件的一部分(不能超過2 GB)[3]。在做方案設計時,我們以滿足數據量的極限情況為目標,但是在實際情況下的數據量往往遠小于極限情況,因此本方案設計了一種依據實際數據量動態調整數據文件長度的機制,可更加合理有效的使用內存和磁盤空間。本方案的內存映射文件存儲流程如圖2 所示。

圖2 大數據文件內存映射數據存儲的流程圖
3.2.1 關鍵函數說明
在圖2 大數據文件內存映射存儲數據的流程中涉及的關鍵函數描述如下。
(1)QFile::QFile(const QString &name)
QFile 構造函數,用于創建文件對象。參數name 表示在磁盤上需要操作的文件名稱。
(2)bool QFile::open(OpenMode mode)
用于打開文件,如果指定的文件不存在,將自動創建。參數mode 表示打開文件的方式,可以選擇僅寫入,僅讀取,或者可讀可寫等。
(3)bool QFile::resize(qint64 sz)
用于設置文件的長度,參數sz 表示文件的長度。
(4)uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions)
用于對文件進行映射,返回值為映射后的內存指針。參數offset 表示需要進行內存映射的數據段在相對文件起始位置的偏移值;參數size 表示需要映射的數據塊的大小。QFileDevice 類是QFile 類的父類。
(5)bool QFileDevice::unmap(uchar *address)
用于取消內存映射,參數address 上述映射成功的內存指針。
(6)void QFileDevice::close()用于關閉文件
3.2.2 關鍵步驟說明
圖2 流程圖中,有幾個關鍵步驟說明如下:
(1)設置文件長度為BLOCK_LEN*m_count
BLOCK_LEN 為自定義的文件初始長度,由于Windows 進程能分配的最大虛擬地址空間為4 GB,但是在實際應用中4 GB 的空間不能全部被占用進行內存映射實現數據存儲。m_count 為進行文件長度擴展的次數,初始值為1。
該步驟的含義描述:新建文件時,將文件長度設置為BLOCK_LEN,假設BLOCK_LEN 等于1 GB。當存儲的數據將該1 GB 的文件長度寫滿以后,動態擴展文件的長度到2 GB,依次類推,當前的數據文件不斷被寫滿后,不斷的將文件長度增加1 GB。這樣可有效合理的利用內存和磁盤空間。
(2)對文件進行映射獲取映射后的內存指針
該步驟的含義描述:假設新建文件時,文件長度為1 GB,這時進行文件映射可以將整個文件的1 GB 空間進行映射,獲取這1 GB 內存空間的指針。當文件長度擴展到2 GB 時,由于文件的前1 GB 空間已經寫滿了數據,此時只需要映射文件的后1 GB長度。依次類推,當文件長度不斷被擴展后,不管擴展后的文件長度有多長,始終只需要映射文件的最后1 GB 空間。
(3)文件寫入結束后調整文件長度為實際數據的長度
如上所述將文件擴展長度的步進設置為1 GB,如果剛擴展文件后,就需要停止數據寫入,如果就這樣取消映射關閉文件,那么磁盤上的數據文件中將會存在1 GB 的無效數據,浪費磁盤存儲空間。
為了避免這種情況,在Visual Studio 等平臺下的通常做法是以寫入的實際數據長度創建新的文件進行內存映射,將數據從原文件復制到新的文件。當進行大數據文件的拷貝時,同樣受進程可分配最大地址空間的限制,必須多次拷貝,極大的影響數據存儲處理的效率。在本方案中完成數據寫入后,利用Qt 系統提供的QFile::resize 函數直接將原數據文件的長度設置為實際數據的長度,此過程可直接保留原數據文件中的有效數據刪除無效數據,省去了新數據文件的創建和數據拷貝過程,有效地避免磁盤空間浪費的同時也提高了數據存儲處理的效率。
(4)流程中多次反復打開關閉文件對象
在圖2 的流程中,在每次進行內存映射或者取消內存映射前都會打開文件,在映射或者取消映射完成后及時關閉文件,這樣做的原因是為了避免長期對磁盤文件的占用,而導致其它應用對該文件的訪問無效。例如,在實時存儲數據的過程中,可能需要通過其它應用程序實時對存儲的數據文件進行讀取分析處理,在內存映射存儲數據過程中及時關閉文件可以有效地避免對文件的訪問沖突。
對數據文件的索引設計通常采用的方式為,在數據文件的起始段中專門預留一部分空間用來記錄索引信息。但是在大數據存儲應用中,無法估計需要記錄的索引信息的長度,如果預留記錄索引的空間不足則必須新建數據文件,當數據存儲時間較長時會產生很多數據文件,不便于對數據文件的管理。如果預留記錄索引的空間較大,在應用中由于文件的長度的動態擴展,使得預留較大空間記錄索引信息既不便于實現也可能造成存儲空間浪費。
在本方案中,采用了將源數據和索引信息獨立記錄在兩個文件中的方式。時間信息通常是所有無線信號數據所具有的關鍵信息,將時間每進行1 秒鐘后存儲數據相對數據文件起始的偏移作為索引值,記錄在索引文件中。索引文件的結構,以及在數據文件的寫入過程中如何在索引文件中記錄索引值的描述如下圖3 所示。索引文件的讀寫同樣可采用內存映射的方式實現。

圖3 索引文件的結構和索引值記錄描述
按照以上方式,如果在索引文件中以10 字節表示年月日時分秒在內的時間信息,以8 字節表示偏移地址,那么只需要占用675 KB 的磁盤空間就可以為連續24 小時的數據存儲建立索引,以極小的磁盤空間換取了數據搜索效率的極大提高。
測試環境描述:Windows 7 旗艦版64 位操作系統,Intel Core i7-377os 處理器,3.10 GHz CPU,8 GB RAM。
在以上測試環境下編寫測試程序,首先模擬產生了512 B 的數據,然后以內存映射和傳統I/O 兩種方式創建文件[5],并循環將模擬的512 B 數據寫入文件,直到文件寫滿,分別記錄兩種文件寫入方式創建并寫滿2 GB、5 GB、10 GB 文件的耗時和速率對比,如下表1 所示。計時起點為QFile::open,計時終點為文件寫滿后取消文件映射,關閉文件對象。

表1 兩種文件寫入方式對比
從上述測試結果可以看出內存映射寫入文件的速率遠高于傳統I/O 文件寫入的速率。以表1 中內存映射文件的速率1500 MB/s 計算,理論可滿足375 MHz 帶寬,750 M sample/s,16 bits 采樣的無線信號中頻采樣數據存儲需求。
上述測試結果是在測試程序功能相對單一的情況下獲取,在實際應用軟件功能復雜的情況下,可能會對文件存儲處理速率稍有影響,但至少可保證滿足帶寬小于300 MHz 的無線信號中頻采樣數據存儲需求。
本文以無線網絡信號的存儲需求和技術設備的國產化需求為背景,在Qt 平臺下設計了一種基于內存映射技術的大數據實時存儲方案。并通過編寫測試程序,驗證了該方案既可滿足對無線信號解調數據連續24 小時的實時存儲需求,也可滿足帶寬小于300 MHz 的無線信號中頻采樣數據的實時存儲需求。同時由于該方案基于Qt 平臺設計,也解決了國產化背景下軟件的跨平臺移植問題。