劉云漢 郭繼光
(中國電子科技集團(tuán)公司電子科學(xué)研究院 北京市 100041)
衛(wèi)星影像數(shù)據(jù)文件大小不一,具有多時態(tài)、大數(shù)據(jù)量,且隨時間延長,數(shù)據(jù)量不斷增加的特點(diǎn),單臺服務(wù)器內(nèi)存、CPU 資源難以支撐海量數(shù)據(jù)的存儲和高效訪問。MongoDB分片復(fù)制集群,將數(shù)據(jù)分散到不同的MongoDB 節(jié)點(diǎn),具有負(fù)載均衡、故障切換和故障恢復(fù)等特點(diǎn),適合存儲衛(wèi)星影像等海量小文件數(shù)據(jù),能夠提供更大的讀寫吞吐量。
MongoDB 高可用集群有主從復(fù)制(Master-Slaver)、副本集(Replica Set)和分片(Sharding)模式三種部署模式。如表1 所示。
表1:分片、副本集集群對比
主從復(fù)制(Master-Slaver)模式不推薦使用,主節(jié)點(diǎn)宕機(jī)不能自動恢復(fù)。
Replica Set 模式取代了 Master-Slaver 模式,是一種互為主從的關(guān)系。Replica Set 將數(shù)據(jù)復(fù)制多份保存,不同服務(wù)器保存同一份數(shù)據(jù),在出現(xiàn)故障時自動切換,實現(xiàn)故障轉(zhuǎn)移,在實際生產(chǎn)中非常實用。Replica Set 是mongod 的實例集合,它們有著同樣的數(shù)據(jù)內(nèi)容。包含主節(jié)點(diǎn)(Primary)、副本節(jié)點(diǎn)(Secondary)和仲裁者(Arbiter)三類角色。一個復(fù)制集群只有一個主節(jié)點(diǎn),主節(jié)點(diǎn)接收所有寫請求,讀請求可以通過配置均衡分配到主節(jié)點(diǎn)和副本節(jié)點(diǎn)。通過數(shù)據(jù)復(fù)制實現(xiàn)副本節(jié)點(diǎn)和主節(jié)點(diǎn)的數(shù)據(jù)同步,當(dāng)主節(jié)點(diǎn)掛掉時,會從副本節(jié)點(diǎn)中選取一個作為主節(jié)點(diǎn),復(fù)制集群中節(jié)點(diǎn)的數(shù)量應(yīng)為奇數(shù)。
Sharding 模式適合處理大量數(shù)據(jù),它將數(shù)據(jù)分開存儲,不同服務(wù)器保存不同的數(shù)據(jù),所有服務(wù)器數(shù)據(jù)的總和即為整個數(shù)據(jù)集。
Sharding 模式追求的是高性能,而且是三種集群中最復(fù)雜的。在實際生產(chǎn)環(huán)境中,通常將 Replica Set 和 Sharding兩種技術(shù)結(jié)合使用。
MongoDB Sharding 分片復(fù)制集群適用于存儲海量數(shù)據(jù)、瞬間并發(fā)讀寫高的場景。其主要有以下特性:
(1)故障切換:Sharding 集群中每個分片節(jié)點(diǎn)采用ReplicaSet 集群來實現(xiàn)高可用性,當(dāng)某個分片節(jié)點(diǎn)的復(fù)制節(jié)點(diǎn)出現(xiàn)故障時,可自動切換至副本節(jié)點(diǎn),從而避免單點(diǎn)故障造成數(shù)據(jù)丟失或影響數(shù)據(jù)庫服務(wù)。
(2)負(fù)載均衡:分片復(fù)制集群會將不同分片部署到不同服務(wù)器上,Sharding 集群通過數(shù)據(jù)分片機(jī)制將數(shù)據(jù)均勻分布到多個數(shù)據(jù)節(jié)點(diǎn)上,減少了單機(jī)數(shù)據(jù)存儲量,提高數(shù)據(jù)存儲總量。通過設(shè)置多個mongos 節(jié)點(diǎn),通過mongos 節(jié)點(diǎn)上配置的負(fù)載均衡機(jī)制,促使每個 shard 節(jié)點(diǎn)上的數(shù)據(jù)塊大小趨于平衡,減小單一節(jié)點(diǎn)的讀寫壓力。
(3)故障恢復(fù):Sharding集群中,每一個數(shù)據(jù)分片(shard)被部署成 ReplicaSet 模式,分片復(fù)制集群具有備份、自動容錯轉(zhuǎn)移、自動恢復(fù)能力,能夠?qū)崿F(xiàn)數(shù)據(jù)存儲服務(wù)的高可用。
如圖 1 所示,mongodb 的集群架構(gòu)主要由3 部分組成:配置服務(wù)服務(wù)器集群,路由節(jié)點(diǎn)服務(wù)器集群,分片+復(fù)制服務(wù)器集群。
圖1:Mongodb 集群的分布式架構(gòu)
(1)路由進(jìn)程 (Route Process):路由進(jìn)程是一個mongos 實例,是數(shù)據(jù)庫集群請求的入口,負(fù)責(zé)將數(shù)據(jù)請求轉(zhuǎn)發(fā)到對應(yīng)的Shard 服務(wù)器上。實際部署時,通常配置多個Mongos 節(jié)點(diǎn),防止其中一個掛掉導(dǎo)致整個集群無法響應(yīng)的情況。
(2)配置服務(wù)器(Config Server):存儲所有數(shù)據(jù)庫元信息(路由、分片)的配置。Mongos 節(jié)點(diǎn)本身不存儲分片服務(wù)器和數(shù)據(jù)路由信息,只是緩存在內(nèi)存里。Mongos 第一次啟動或重啟后會從配置服務(wù)器加載配置信息,如果配置信息變化,配置服務(wù)器會將變化信息通知路由服務(wù)器。實際部署時,為防止配置信息的數(shù)據(jù)丟失,通常配置多個配置服務(wù)器。
(3)分片服務(wù)器(Shard Server):分片服務(wù)器是存儲實際數(shù)據(jù)的地方,也稱為分片節(jié)點(diǎn)。每個分片節(jié)點(diǎn)可以是一個 mongod 實例,也可以是一組 mongod 實例構(gòu)成的復(fù)制集。
MongoDB 基于MongoDB 文檔數(shù)據(jù)庫和其內(nèi)置的GridFS 實現(xiàn)文件數(shù)據(jù)的統(tǒng)一管理。
(1)對于<16M 的數(shù)據(jù)文件,轉(zhuǎn)換為二進(jìn)制,直接插入數(shù)據(jù)庫,使用Binary數(shù)據(jù)類型存儲。MongoDB的操作如下:
(2)對于≥16M 的大文件,使用GridFS 文件系統(tǒng)存儲。GridFS 將大文件對象分割成多個小的chunk(256K 文件片段),以兩個集合配合的方式存儲。其中fs.files 集合存儲文件名稱、文件大小、文件片段數(shù)量、文件存儲時間等文件元數(shù)據(jù)信息;fs.chunks 集合存儲文件實際內(nèi)容。GridFS 文件操作如下:
通過MongoDB 存儲文件將數(shù)據(jù)庫與文件綁定,可通過檢索數(shù)據(jù)庫獲取文件,避免文件位置變化導(dǎo)致文件丟失。
海量數(shù)據(jù)存儲需要通過數(shù)據(jù)分片來應(yīng)對高吞吐量和大數(shù)據(jù)量,當(dāng)集群主機(jī)性能到達(dá)瓶頸時可以通過水平擴(kuò)展提高存儲容量和吞吐量。
MongoDB 的自動分片是將數(shù)據(jù)庫中的集合數(shù)據(jù)按照一定的規(guī)則切分成若干小塊,這些分片的數(shù)據(jù)寫入和讀取統(tǒng)一由mongos 管理,路由會依據(jù)shard key 的分片規(guī)則找到對應(yīng)的分片。
3.2.1 片鍵選擇方式
最常用的數(shù)據(jù)分片方式有三種:升序片鍵、隨機(jī)分發(fā)的片鍵和基于位置的片鍵。
(1)升序片鍵:升序片鍵通常有點(diǎn)類似于"date"字段或者是ObjectId,是一種隨著時間穩(wěn)定增長的字段。缺點(diǎn):例如ObjectId 可能會導(dǎo)致接下來的所有的寫入操作都在同一塊分片上。
(2)隨機(jī)分發(fā)的片鍵:隨機(jī)分發(fā)的片鍵可以是用戶名,郵件地址,UDID,MD5 散列值或者數(shù)據(jù)集中其他一些沒有規(guī)律的鍵。缺點(diǎn):MongoDB 在隨機(jī)訪問超出RAM 大小的數(shù)據(jù)時效率不高。
(3)基于位置的片鍵:基于位置的片鍵可以是用戶的IP、經(jīng)緯度、或者地址。這里的"位置"比較抽象,不必與實際的物理位置字段相關(guān)。
3.2.2 片鍵選取規(guī)則
(1)片鍵限制:片鍵不可以是數(shù)組。文檔一旦插入,其片鍵就無法修改了。要修改文檔的片鍵值,就必須先刪除文檔。
(2)片鍵的勢:選擇一個值會變化的鍵非常重要,即值很多,隨著數(shù)據(jù)量的增大可以分出更多的片鍵。分片在勢比較高的字段上性能更佳。
綜上所述,衛(wèi)星影像數(shù)據(jù)存儲采用衛(wèi)星編號作為分片鍵。分片的語句定義如下:
對數(shù)據(jù)庫啟用分片:sh.enableSharding (“satsjdb”);
為驗證MongoDB 分片集群的性能,通過3 臺機(jī)器搭建MongoDB 分片集群,機(jī)器的配置如表2 所示。
表2:配置表
4.2.1 MongoDB 高可用測試
基于上述搭建的高可用集群,測試分片復(fù)制集群的負(fù)載均衡和故障切換性能。
(1)執(zhí)行插入程序插入千萬級數(shù)據(jù),執(zhí)行db.test.getShardDistribution()指令查看集合數(shù)據(jù)的分布情況。如圖2所示。
圖2
(2)執(zhí)行指令停掉21 服務(wù)器上分片1 的服務(wù),查看分片狀態(tài)如下:21 上分片1 的節(jié)點(diǎn)狀態(tài)變成not reachable;22上分片1 的節(jié)點(diǎn)狀態(tài)變成PRIMARY;執(zhí)行分片1 上數(shù)據(jù)的讀寫操作,能夠正常響應(yīng)。如圖3 所示。
圖3
結(jié)論:數(shù)據(jù)能夠根據(jù)分片鍵均勻分布到分片節(jié)點(diǎn)上;當(dāng)某個分片的主節(jié)點(diǎn)宕機(jī)時,副本節(jié)點(diǎn)能夠自動切換為主節(jié)點(diǎn);某個路由服務(wù)或配置服務(wù)器停止時,客戶端能夠正常訪問數(shù)據(jù)庫,整個集群在測試過程中均穩(wěn)定無差錯運(yùn)行。
4.2.2 MongoDB 集群擴(kuò)容測試
新增三臺服務(wù)器,組成分片4,執(zhí)行指令為admin 數(shù)據(jù)庫綁定shard4,執(zhí)行操作如下:
db.runCommand({addshard:"shard4/10.17.2.24:22004,10.17.2.25: 22004,10.17.2.26:22004"});
通過指令查看集合數(shù)據(jù)的分布情況如圖4 所示。
圖4
結(jié)論:新加分片后,數(shù)據(jù)會根據(jù)分片鍵將數(shù)據(jù)遷移至分片4,并實現(xiàn)數(shù)據(jù)在4 個分片的均勻分布;可通過擴(kuò)充服務(wù)器實現(xiàn)集群存儲容量的水平擴(kuò)展。
MongoDB 分片復(fù)制集群基于自動分片機(jī)制,不同的分片之間可以負(fù)載均衡,具有高并發(fā)、高可靠性和高效擴(kuò)展存儲等特點(diǎn)。能夠?qū)崿F(xiàn)海量小文件和大文件的統(tǒng)一存儲管理,數(shù)據(jù)的訪問效率優(yōu)于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,能夠滿足遙感影像數(shù)據(jù)的存儲訪問需求。