劉儀軒
(東華大學計算機科學與技術(shù)學院,上海 8170003)
隨著城市智慧排水建設(shè)浪潮的不斷推進,各種降雨傳感器、積水位傳感器的數(shù)量不斷增多,大量的實時數(shù)據(jù)與歷史數(shù)據(jù)在管理和存儲上帶來了很大的挑戰(zhàn),傳統(tǒng)的關(guān)系型數(shù)據(jù)庫的短板逐漸顯現(xiàn),如數(shù)據(jù)格式要求統(tǒng)一,無法存儲復雜格式的數(shù)據(jù),對于大數(shù)據(jù)的存儲和管理效率低下,已無法滿足智慧城市建設(shè)發(fā)展的需求。而非關(guān)系型數(shù)據(jù)庫MongoDB的出現(xiàn),其在存儲復雜數(shù)據(jù)和大數(shù)據(jù)處理上都有很大的優(yōu)勢,通過搭建MongoDB 分布式數(shù)據(jù)庫為排水設(shè)施的可動態(tài)擴展、高效率數(shù)據(jù)存儲提供了新的解決方案。
MongoDB 數(shù)據(jù)庫由多個集合組成,而每個集合由多個文檔組成,MongoDB 中的集合概念相當于傳統(tǒng)關(guān)系型數(shù)據(jù)庫中數(shù)據(jù)庫的概念,而文檔相當于表的概念。區(qū)別在于文檔是自由模式的,沒有固定的行列結(jié)構(gòu),因此是不需要對表結(jié)構(gòu)進行特定的設(shè)置。雖然說集合和文檔的模式存儲較為靈活,但是帶來的缺點是缺乏規(guī)范性,在數(shù)據(jù)管理上需要進行設(shè)計。在本文中將數(shù)據(jù)結(jié)構(gòu)相近的數(shù)據(jù)存儲在相同的集合中,然后將相同的幾個集合分為幾個大類集合,這樣既能夠讓數(shù)據(jù)進行靈活存取,也能夠?qū)?shù)據(jù)進行統(tǒng)一管理,同時還有利于提高讀寫效率。創(chuàng)建集合需要遵循以下幾個原則:
(1)建立索引原則。在數(shù)據(jù)庫中建立索引能夠大大加速數(shù)據(jù)的查詢速度,添加索引之后查找數(shù)據(jù)就不需要整張表進行查找,在建立索引的時候是以集合為基礎(chǔ)建立的。MongoDB的索引可以根據(jù)關(guān)系型數(shù)據(jù)庫中索引的建立規(guī)則來建立,具體要求如下:根據(jù)需要查詢的字段來建立索引,索引不是越多越好,過多的索引會降低查詢效率。索引建立后并不是一成不變的,需要根據(jù)應用場景的變化做及時的更新。
(2)方便管理和存儲原則。將相似結(jié)構(gòu)和類型的數(shù)據(jù)歸類到相同的集合中,做好分類有利于開發(fā)人員、數(shù)據(jù)庫管理人員和用戶進行使用。
(3)利于擴展原則。考慮到隨著城市智慧水務(wù)系統(tǒng)的不斷擴大,傳感器部署越來越多,所記錄的雨量數(shù)據(jù)也越來越龐大,需要設(shè)計的集合應便于數(shù)據(jù)庫的橫向及縱向擴展。
根據(jù)系統(tǒng)數(shù)據(jù)庫的要求,將數(shù)據(jù)庫設(shè)計分為四大類:用戶信息數(shù)據(jù)庫、業(yè)務(wù)數(shù)據(jù)庫、傳感器積水量數(shù)據(jù)庫和多媒體數(shù)據(jù)庫。其中用戶信息數(shù)據(jù)庫根據(jù)權(quán)限分為巡檢人員、管理人員、超級管理員三大類。業(yè)務(wù)數(shù)據(jù)庫主要是用于巡檢養(yǎng)護數(shù)據(jù)存儲,包括養(yǎng)護里程統(tǒng)計、本月養(yǎng)護管道長度統(tǒng)計、當年街鎮(zhèn)養(yǎng)護計劃執(zhí)行情況、巡檢完成情況、巡檢上報事件統(tǒng)計、當年應急處置事件總數(shù)等。傳感器數(shù)據(jù)庫中的數(shù)據(jù)分為防汛監(jiān)控數(shù)據(jù)、污水監(jiān)控數(shù)據(jù),其中防汛監(jiān)控數(shù)據(jù)包括積水情況統(tǒng)計、今日降雨量統(tǒng)計、泵站工況實時信息和雨量實時信息。數(shù)據(jù)結(jié)構(gòu)示意圖如圖1所示。
隨著城市排水設(shè)施智能化的建設(shè),排水設(shè)施狀態(tài)監(jiān)控越來越完善,排水點感知器越來越多,同時也帶來了高并發(fā)和大數(shù)據(jù)存儲的考驗。單臺服務(wù)器已經(jīng)無法滿足如此大的數(shù)據(jù)量和查詢量,同時為了做好服務(wù)器災備,提高系統(tǒng)存儲查詢效率,將數(shù)據(jù)庫設(shè)計成集群模式,搭載多臺服務(wù)器一同工作,應對大數(shù)據(jù)帶來的挑戰(zhàn)。MongoDB 在搭建集群時會自動分片,不需要考慮硬件之間的聯(lián)系,同時可以在不影響當前數(shù)據(jù)庫的情況下進行動態(tài)擴容,從而實現(xiàn)數(shù)據(jù)庫的海量存儲[1]。MongoDB集群中有幾個重要概念:
Mongos,數(shù)據(jù)庫集群請求入口。所有的請求訪問MongoDB集群時都需要由Mongos來協(xié)調(diào)分發(fā),因此,Mongos也可以看作是MongoDB集群的消息分發(fā)中心,當Mongos收到請求時,會分發(fā)到多個Shard(分片)中,在實際應用中往往有多個Mongos,防止一臺Mongos出現(xiàn)問題導致整個系統(tǒng)崩潰。
Config server,存儲數(shù)據(jù)庫的元數(shù)據(jù),即存儲分片、路由等有關(guān)數(shù)據(jù)庫的信息。每次Mongos啟動時都會訪問Config server 來確定配置,在實際應用中也有多個Config server,防止數(shù)據(jù)丟失。
Shard(分片)是指將數(shù)據(jù)庫拆分成若干個小的數(shù)據(jù)庫,分布到若干臺服務(wù)器中,再由均衡器進行統(tǒng)一,這樣提高了數(shù)據(jù)庫的存儲能力和計算能力。
Replica set(副本集)是通過數(shù)據(jù)冗余來實現(xiàn)分片數(shù)據(jù)的備份,若其中一個分片服務(wù)器宕機,可由另一臺服務(wù)器提供備份數(shù)據(jù),保證了數(shù)據(jù)的安全性。
Arbiter(仲裁者)是副本集中MongoDB 的實例,仲裁者并沒有實際保存數(shù)據(jù),需要的資源也很小。添加仲裁節(jié)點能夠確保選擇主節(jié)點時投票數(shù)是奇數(shù)。
當一個應用需要訪問MongoDB 數(shù)據(jù)庫時,首先讀取配置服務(wù)器所存儲的數(shù)據(jù)庫相關(guān)的元數(shù)據(jù),并備份Mongos;需要保存的數(shù)據(jù)最終是存儲到Shard 分片上的;為了防止數(shù)據(jù)丟失,MongoDB 同時會給Replica set 備份數(shù)據(jù),而仲裁者的作用是決定將數(shù)據(jù)存儲到哪個節(jié)點上。
最簡單的MongoDB集群模式是由1個路由服務(wù)器、1個配置服務(wù)器和3個分片數(shù)據(jù)服務(wù)器組成。由于路由服務(wù)器、配置服務(wù)器、數(shù)據(jù)服務(wù)器都是單體結(jié)構(gòu),一旦出現(xiàn)斷電或者服務(wù)器故障,容易導致數(shù)據(jù)丟失,而沒有備份數(shù)據(jù)。為了使系統(tǒng)更加健壯,應當為服務(wù)器建立副本集,副本集具有主從復制的功能,當一臺主服務(wù)器出現(xiàn)故障時,副節(jié)點能夠通過仲裁升級成為主節(jié)點,代替主節(jié)點繼續(xù)工作。因此,為了提高系統(tǒng)的存儲和計算效率,同時又滿足穩(wěn)定性要求,可以通過分片+副本集的形式來構(gòu)建系統(tǒng),系統(tǒng)架構(gòu)如圖2。
從圖2 的副本集+分片的架構(gòu)可以看出,需要15 臺服務(wù)器來部署這套系統(tǒng),這樣的成本很高,而且會造成資源浪費。由于路由服務(wù)器和配置服務(wù)器不需要存儲大量數(shù)據(jù),因此不需要單獨的一臺服務(wù)器來作為路由服務(wù)器和配置服務(wù)器,只需要將他們與數(shù)據(jù)節(jié)點服務(wù)器放在一起即可,而主節(jié)點、副節(jié)點以及仲裁節(jié)點不能放在同一硬件服務(wù)器中,否則會導致數(shù)據(jù)丟失。該數(shù)據(jù)庫集群部署的參數(shù)如下:
(1)3臺硬件服務(wù)器配置數(shù)據(jù):
操作系統(tǒng):Windows 7,64位操作系統(tǒng);處理器i7;
安裝內(nèi)存:16.00GB 硬盤1000G。
(2)數(shù)據(jù)庫以及GUI可視化工具
MongoDB數(shù)據(jù)庫:3.6.0;GUI可視化工具:robomongo
以下演示在服務(wù)器上操作過程,由于3臺服務(wù)器操作類似,現(xiàn)僅演示1臺服務(wù)器操作命令:
(1)創(chuàng)建文件夾
md E:mongodatashard1masterdb
md E:mongodatashard1masterlog
md E:mongodatashard2slavedb
md E:mongodatashard2slavelog
md E:mongodatashard3arbiterdb
md E:mongodatashard3arbiterlog
(2)啟動數(shù)據(jù)庫
mongod --shardsvr --replSet shard1--port 28000
--dbpath E:mongodatashard1masterdb
--logpath E:mongodatashard1masterlogshard1.log
參數(shù)解釋:--dbpath 數(shù)據(jù)庫路徑,--shardsvr 使用分片模式啟動,--replSet 復制集模式啟動,復制集名稱為shard1。
GridFS屬于MongoDB的一個子模塊,彌補了MongoDB存儲大文件附件的短板。因為MongoDB對于文件的大小限制為16M,而實際使用中有許多業(yè)務(wù)需求會用到視頻圖片等附件,通常會大于16M,而GridFS就不受到文件大小的限制,下面說明其原理[2]:
GridFS分別使用兩個集合來存儲文件,一個集合用于存儲文件的元數(shù)據(jù),如文件名、文件類型、文件大小等信息,另一個集合存儲文件的chunks,存儲原理如圖3所示。
傳統(tǒng)的文件系統(tǒng)是將文件存儲于磁盤中,在數(shù)據(jù)庫中保存文件地址,而本存儲系統(tǒng)是將文件存儲在MongoDBGridFS模塊中。這種做法有以下幾點優(yōu)勢:
(1)實現(xiàn)restAPI使用方便;
(2)便于管理,便于備份;
(3)克服磁盤對文件存放數(shù)量的限制,存儲量大;
(4)可搭建分布式存儲,實現(xiàn)自動備份、故障遷移、負載均衡。
鑒于這些優(yōu)勢,GridFS在以下幾個場景中進行應用:
(1)由于GridFS對于文件的大小和數(shù)量沒有限制,并且可以通過增加服務(wù)器的方式來擴容服務(wù)器,因此不用當心隨著城市排水設(shè)備的增多和積水點位感應器的增多所帶來的照片和視頻數(shù)量的限制問題。同時在拍攝視頻的時候也可以不用受限于拍攝時長。
(2)對某個點位進行長時間的監(jiān)控記錄下的視頻,使用GridFS 后,可以只訪問其中的部分內(nèi)容,而不需要將全部內(nèi)容加載到內(nèi)存中,有利于提高訪問速度和內(nèi)存利用率。
(3)因為GridFS是分布式的文件存儲系統(tǒng),所以可以使用GridFS在多個排水和應急搶險部門同時更新視頻和照片,大大提高急救搶險效率。
GridFS 可通過MongoDB 自身的特點搭建副本集,這是一種高可用的方案。搭建方式有以下兩種:
(1)奇數(shù)個數(shù)據(jù)節(jié)點。以3個為例,即一主兩從。當一個主節(jié)點宕機了,另外兩個從節(jié)點會自己選出一個作為主節(jié)點。
(2)偶數(shù)個數(shù)據(jù)節(jié)點+一個仲裁節(jié)點。以3 個為例,即1主1從1仲裁。仲裁只負責推選主節(jié)點而不存放數(shù)據(jù)。如果主節(jié)點宕機了,仲裁節(jié)點會選出主節(jié)點。
GridFS可通過MongoDB自身的特點搭建分片+副本集,這是一種負載均衡+高可用的方案,可以用于大數(shù)據(jù)的存儲和抗擊高并發(fā)訪問。分片通過Mongos進行路由。值得注意的是查詢時應盡量避免跨分片查詢,使用分片的情況有以下幾種:
(1)當機器磁盤不夠用,可以使用分片來很好地解決磁盤空間不足的問題。
(2)當單個MongoDB 不能滿足寫數(shù)據(jù)的性能要求,可以使用多個分片分布在不同的服務(wù)器上,從而提高整體的讀寫速度。
(3)使用分片還可以提高內(nèi)存的存儲性能,可以將大量數(shù)據(jù)存在多個分片的內(nèi)存中。通過分片使用分片服務(wù)器自身的資源。
隨著城市建設(shè)越來越智能化,數(shù)據(jù)量與日俱增,應不斷加強對于大數(shù)據(jù)和數(shù)據(jù)庫方面的研究。本文分析了排水設(shè)備的各類數(shù)據(jù),分析了MongoDB的建庫原則,結(jié)合采集到的數(shù)據(jù)結(jié)構(gòu)特點構(gòu)建了排水設(shè)備數(shù)據(jù)庫,并分析研究了MongoDB 的GridFS 文件存儲模塊,用于存儲和管理積水點現(xiàn)場拍攝的多媒體數(shù)據(jù),最后根據(jù)系統(tǒng)需要實現(xiàn)了MongoDB 和GridFS的集群分布式部署。