葉思斯,林志達,郭獻彬,曹小明
(1.中國南方電網數字電網研究院有限公司,廣東廣州 510663;2.中國南方電網有限責任公司,廣東廣州 510670)
隨著互聯網行業的進一步發展,數據呈爆炸式增長趨勢。大數據已經逐漸成為社會發展的重要組成部分,而社會也逐步邁入了大數據發展的時代[1]。但是隨著數據量的逐漸增多,傳統的儲存方式已經無法適應當今的發展需求[2]。在此背景下,研究者開始尋求新興的數據處理以及存儲技術,其中,云存儲技術作為一種通用型強、可靠性高等優勢已經逐漸成為了大規模數據存儲的重要技術之一[3]。所謂云存儲技術是指一種基于云計算技術的新興存儲技術,當云計算技術可以和云存儲技術相互轉化,當云計算系統需要進行大量的數據存儲以及管理工作時,云計算系統就可以轉換為云存儲技術。云儲存技術也可以被看作為一種數據服務技術[4]。在實際應用中,云存儲技術研究由于起步較晚,發展不夠成熟,在使用方面往往存在著安全性較差、帶寬限制以及數據管理等方面的問題[5]。這些問題嚴重制約了云儲存技術的發展。而現階段,針對云儲存相關技術的設計與優化已經成為了互聯網領域研究的熱點問題,引發了研究者廣泛關注。
NoSQL是近年來發展較快的一種云存儲數據庫類型,與傳統數據庫不同,NoSQL數據庫不需要遵循基本要求,其數據存儲方式也更加靈活[6]。其中MongoDB是NoSQL中功能最為豐富也是應用最長的數據庫之一。MongoDB主要是面向文檔的一種數據庫類型,可以支持BSON格式的數據,數據存儲模式自由、結構松散[7]。MongoDB應用優勢顯著,具有部署性強、性能高以及使用簡便等優點。其語言查詢功能強大,可實現關系數據庫中絕大部分的查詢功能,同時MongoDB也可以支持建立數據索引功能。
本研究基于MongoDB的基本理論與概念,提出了基于片鍵類型優化、數據查詢優化以及數據存儲優化3個方面的MongoDB分片集群系統優化方案。為檢測優化效果,研究分別檢測了在不同分片環境下的MongoDB數據插入性能以及數據查詢性能,明確了優化效果。
本研究中的MongoDB分片集群部署構成示意圖如圖1所示。

圖1 MongoDB分片集群部署示意圖Fig.1 Schematic diagram of MongoDB sharding cluster deployment
由圖1可知,在本研究中MongoDB分片集群主要由Mongos、config server、mongod以及monitor等主要模塊組成[8]。其中,Mongos是整個MongoDB分片集群中的路由服務器。通過Mongos可以使MongoDB分片集群中的客戶端以及服務端進行連接。用戶發送的請求將通過Mongos發送至不同的服務器中。為進一步提高MongoDB的穩定性以及可靠性,在本研究中使用集群的方式對Mongos進行搭建。config server是存儲數據分片以及數據塊中具體信息的主要結構,當MongoDB運行時,config server負責將相關信息提供給Mongos,保證了Mongos的可靠性。同時,config server也可以擴展為集群。Mongod主要負責MongoDB的實際操作,包括數據塊的存儲、數據的查詢、數據的插入以及數據的實例化等操作。而monitor在MongoDB分片集群中主要起到數據監控的作用。通過monitor可以監控系統的負載均衡狀態、數據操作頻率以及讀寫基本耗時等內容。
本研究主要從片鍵類型、數據查詢以及數據存儲3個方面對MongoDB進行系統優化分析。具體優化內容如下。
1.2.1 片鍵類型優化
片鍵是分片集群中最常用的索引,當設定MongoDB中的某個索引為片鍵時,分片集群會根據片鍵的設定來對數據進行劃分[9]。同時在進行分片后,片鍵直接決定了數據的存放情況。因此片鍵的選擇十分重要,不恰當的片鍵往往會使系統的性能降低,無法適應較高的訪問量;而恰當的片鍵則可以進一步提高系統的性能,確保系統良好運行[10]。
常用的片鍵類型主要分為小基數片鍵、升序片鍵以及Hash片鍵等。本研究中小基數片鍵的數量有限,在實際使用時往往會產生眾多體積較大且難以移動的數據塊。升序片鍵則主要是以ID字段作為片鍵,在沒使用升序片鍵時可以將最新產生的數據集中起來,可以大幅度提高數據的讀取性能[11]。Hash片鍵是一種基于范圍的分片形式,其主要優點為存儲和讀取的操作都均勻分布,并且消除了數據塊過大的問題[12]。
基于實際需求和考慮,本研究選取了資源標簽作為組合片鍵中的搜索鍵。同時,本文使用時段鍵來控制數據的局部化,時段鍵數目的取值需要保證在足夠大的同時又不超出系統所能承受的最佳處理范圍。本研究使用{Month:1,Label:1}的組合片鍵形式。其中Month字段作為主片鍵,表示資源上傳的時間,Labe字段作為第二片鍵,表示系統資源。在設定中,系統運行超過兩年時,即n>24,在這一范圍內既可以保證數據的局部化又可以使每個時間段對應多個數據塊。
1.2.2 數據查詢優化
數據查詢優化主要包括兩方面的內容,分別是查詢數據優化以及搜索鍵優化。在某些情況下,MongoDB會將查詢后的結果分配到可能的幾個分片內,隨后將執行后的結果信息匯總起來反饋給客戶端[13]。這種工作模式極容易造成資源的消耗,同時也增加了操作的使用時間。在本研究中主要采用sort()來排序查詢數據,以片鍵中的第一個字段為排序依據,隨后系統按照事先排序好的順序進行查詢,再將執行結果反饋給用戶,降低反應時間以及資源占用程度。
搜索鍵的優化主要以時段鍵以及搜索鍵作為片鍵,該組合方式可以使同類型的數據集中在較少的分片上,有利于數據的查詢以及下載操作。同時,本文將用戶的ID作為搜索鍵的一部分,自動添加進搜索鍵的標簽內容中,解決了用戶在查詢和讀取本人的數據時系統查詢負荷過大的問題。
1.2.3 數據存儲優化
在MongoDB空間不足時需要自動申請相應的硬盤空間,申請空間的大小為64 M、128 M以及256 M并逐漸上升,最高申請上限為2G。但是在該種自動分片的機制下容易導致內存以及硬盤的占用。其示意圖如圖2所示。

圖2 數據存儲次序Fig.2 Data storage sequence
已知共有Shard01、Shard02以及Shard03 3個片,其負載分別為400、300以及700。假設此時需要插入一組新的數據,由于其數據儲存是按照時間順序進行排列的,因此當寫入新數據時首先會寫入到Shard03片中,此時則會導致shard03負載過高,而Shard01和Shard02負載過低,造成資源的浪費。因此在實際應用中常常需要使用數據均衡算法進行優化。而在MongoDB的優化算法中常常根據數據量的大小來統計負載的方式。此種方法在實際運行過程中存在諸多問題,實際應用效果較差。
為解決此問題,基于數據被查詢的概率來進行系統的數據存儲優化。該方案利用FODO算法思想進行實驗數據存儲優化,首先利用數據被查詢的概率來計算查詢負載,隨后將所有存儲對象按照查詢負載由小到大派別,假設集群中的某一分片被刪除,該片中的數據塊就會以被查詢的概率來決定存儲的位置,進而提高查詢的速度。
本研究利用FODO算法進行優化的步驟如下。
首先,計算出第i個數據塊被訪問的概率,公式如下所示:

其中,P為第i個數據塊被查詢的次數和全體數據被查詢的次數的比值。由式(1)可以看出,對所有數據塊而言,其分母均相同。因此P可以通過單位時間內數據塊的查詢次數排序來代替。
因此,在數據文檔中添加查詢的頻率鍵F,其表達式為

其中,F表示第i個數據塊被查詢的頻率。
在實際應用中發現,部分數據在不同的時間段查詢的頻率也不盡相同,為確保數據查詢的時效性,需要統計最近一段時間的查詢頻率,而本研究通過調整資源可知,將時間段的長度設置為一個月是最佳的選擇,因此將式(2)中的時間段長度設置為1個月,則該公式可以被改寫為

又因為式(3)中的t為固定值,因此可以進一步簡化式(3),即可得出一個月內的查詢次數C,公式如下所示:

其中,Fit為第i個數據塊在t時間段內的查詢總數。
所有數據塊的值的總和如下所示:

當開啟新節點時,可以與鏈表中的其他對象所對應的C值進行對比,從而實現排序操作。在均衡器進行數據遷移時也可以根據數據塊中對應的C值進行統計,分析存儲對象的查詢負載,決定數據點存儲次序,從而實現數據的存儲優化。
本研究主要測試環境如表1所示。

表1 實驗測試環境Tab.1 Experimental test environment
2.1.1 3個不同分片環境下的插入分析
本研究主要討論了升序片鍵、Hash片鍵以及優化片鍵這3種分片環境下MongoDB數據庫的相關性能,具體討論了在150萬條數據插入時,數據的分布規律以及數據的寫入速度,具體內容如圖3-5所示。
由圖3可知,在升序分片的環境下,數據插入后的分片差距過大,分布極不均衡。其中,Shard01的插入數據占比為81.94%,而Shard03的插入數據占比僅為18.06%,在Shard02區域甚至出現了沒有數據輸入的情況。而在Hash分片以及優化分片的情況下均可使數據較為均勻地分布在各個區域內。其中,在Hash片鍵的環境下,Shard01-Shard03的插入數據分布占比分別為30.42%、37.94%以及31.64%;而在優化片鍵的環境下Shard01-Shard03的插入數據分布占比分別為32.45%、35.34%以及32.21%;優化分片的效果略好于Hash分片。產生這種現象的主要原因是在升序分片中,當數據插入時往往會在最新的片上進行,造成數據分布不均。而優化分片擁有升序分片與Hash分片的優點,在保證數據確定分布的情況下又可以避免數據過度集中。

圖3 升序片鍵數據插入性能分析Fig.3 Performance analysis of ascending slice key data insertion

圖4 Hash片鍵數據插入性能分析Fig.4 Hash key data insertion performance analysis

圖5 優化片鍵數據插入性能分析Fig.5 Optimized slice key data insertion performance analysis
在3種分片環境下,數據寫入速度也有著較大的區別,當數據量分別在100萬-700萬條時,在升序片鍵環境下,數據寫入速度為7000條/秒至9000條/秒。而在Hash片鍵以及優化片鍵的環境下,插入速度則在3000條/秒至4000條/秒之間。結果顯示在升序分片的環境下,數據插入的速度最快。
2.1.2 插入方式測試
同時,本研究還分析了在優化片鍵分片的條件下,不同數據插入方式對MongoDB性能的影響,以插入所需時間作為評判依據,主要分析了批量插入以及逐條插入這兩種數據插入方式的影響。具體結果如圖6所示。
由圖6可知,在數據量分別為100萬條至700萬條時,數據逐條插入以及數據批量插入時所需的時間基本相同,差距不大。結果表明,在該條件下插入方式的不同并不會影響MongoDB數據庫的相關性能。

圖6 逐條插入與批量插入的性能分析Fig.6 Performance analysis of strip insert and batch insert
本研究同時分析了在3種不同分片環境下數據查詢的相關性能,本文以查詢速度作為查詢評價指標。具體結果如圖7所示,其中圖7(a)-7(c)分別為升序片鍵、Hash片鍵以及優化片鍵的數據查詢速度結果。
由圖7可知,當數據量分別為100萬-700萬條時,在升序片鍵的環境下,數據查詢速度在4000條/秒至6000條/秒之間;在Hash片鍵的環境下,數據查詢速度最小,基本維持在1000條/秒左右。而在優化片鍵的環境下,數據查詢速度最大,在1萬條/秒至1.2萬條/秒之間。結果表明,在優化片鍵的環境下,MongoDB的查詢性能最好。
本研究主要探討了MongoDB集群的系統優化以及相關的測試研究。主要分析了在升序片鍵、Hash片鍵以及優化片鍵3種不同分片條件下數據的插入性能以及數據的查詢性能。可得出如下結論:(1)在插入數據分布規律測試中,升序分片中數據分布差距較大,Shard01插入數據占比為81.94%,Shard03的插入數據占比僅為18.06%,而在Shard02區域無數據插入。(2)在Hash分片以及優化分片環境下數據分布較為均勻,其中,優化分片環境下速度分布最為均勻,3個區域的數據分布占比均在33%左右。(3)數據插入速度則是升序分片下速度最快,Hash分片以及優化分片的數據插入速度基本一致。同時,研究還表明,逐條插入以及批量插入這兩種插入方式對MongoDB的數據插入所需時間并無明顯影響。數據查詢結果表明,在數據量分別為100萬-700萬條時,在優化片鍵的環境下,數據查詢速度范圍為1萬條/秒至1.2萬條/秒之間。在優化片鍵環境下查詢速度最大,查詢性能最好。綜合上述結果可知,在優化后的分片環境下數據插入性能以及數據查詢性能較高,使用本研究的優化方案可以有效地提高MongoDB集群的相關性能,從而提高MongoDB集群的使用效果。