一、 系統(tǒng)架構(gòu)
這是基于云計(jì)算和大數(shù)據(jù)的模擬車輛行車監(jiān)控系統(tǒng),可模擬實(shí)現(xiàn)在線遠(yuǎn)程對(duì)車輛行車的信息記錄以及數(shù)據(jù)處理。其中,記錄信息其中包括車輛的id、經(jīng)過的地點(diǎn)(經(jīng)緯度)、時(shí)間,數(shù)據(jù)處理包括對(duì)數(shù)據(jù)的排序、錯(cuò)誤數(shù)據(jù)的排查、通過時(shí)間以及地點(diǎn)在地圖上獲得車輛行駛的軌跡、車輛相遇次數(shù)。
系統(tǒng)包括數(shù)據(jù)產(chǎn)生模塊、數(shù)據(jù)接受與處理模塊、數(shù)據(jù)庫模塊、客戶端模塊。其中kafka進(jìn)行數(shù)據(jù)的接收,并進(jìn)行數(shù)據(jù)過濾,將過濾后的數(shù)據(jù)傳遞給Redis,Redis再將數(shù)據(jù)存入Hbase數(shù)據(jù)庫,Spark從Hbase中獲得數(shù)據(jù),將處理后的數(shù)據(jù)再傳遞回Hbase,客戶端從Hbase中獲得數(shù)據(jù)并將其展示在前端。
邏輯架構(gòu)如下:
物理架構(gòu)圖如下:

二、數(shù)據(jù)流程分析
1. 數(shù)據(jù)采集過程分析
數(shù)據(jù)采集過程包括Kafka數(shù)據(jù)采集、Redis數(shù)據(jù)過濾、Hbase數(shù)據(jù)入庫三部分,其中包括三個(gè)實(shí)體:Kafka生產(chǎn)者、Kafka消費(fèi)者兼Redis發(fā)布者、Redis訂閱者。
各自的作用如下:
Kafka生產(chǎn)者:負(fù)責(zé)從json文件中以行為單位讀取數(shù)據(jù)源,通過Kafka生產(chǎn)者代碼編寫生產(chǎn)消息,將json讀取的消息發(fā)布在topic上。
Kafka消費(fèi)者兼Redis發(fā)布者:負(fù)責(zé)從topic上消費(fèi)Kafka生產(chǎn)者生產(chǎn)的消息,將消息通過Redis發(fā)布訂閱功能發(fā)布到一個(gè)信道,等待訂閱者接受消息。
Redis訂閱者:負(fù)責(zé)訂閱發(fā)布者相應(yīng)的信道,接受發(fā)布者的消息,將消息存入Hbase數(shù)據(jù)庫。
數(shù)據(jù)過濾過程使用了Kafka streams對(duì)原始數(shù)據(jù)進(jìn)行過濾,本小組采用HIGH-LEVEL STREAMS DSL進(jìn)行處理。Kafka創(chuàng)建一個(gè)Filter流,流的源綁定filter-before topic,同時(shí)Kafka生成者將消息生產(chǎn)在這個(gè)topic上;流的出口綁定filter-after topic,Kafka消費(fèi)者綁定這個(gè)topic消費(fèi)消息。過濾器消息選擇條件過濾掉不正確的經(jīng)緯度數(shù)據(jù),并將這部分?jǐn)?shù)據(jù)存放在Redis filter 鍵里,合格的數(shù)據(jù)傳送到filter-after topic上。
Redis的緩沖作用
在Redis訂閱者上,由于生產(chǎn)者生產(chǎn)消息過快,如果選擇一條一條的存入數(shù)據(jù)庫,會(huì)出現(xiàn)存取數(shù)據(jù)過慢,導(dǎo)致生產(chǎn)者的消息經(jīng)過規(guī)定的時(shí)間(本小組設(shè)置的時(shí)間是90秒)沒有被消費(fèi),報(bào)出Timeout錯(cuò)誤。為避免這樣的問題,選擇每1000條數(shù)據(jù)存入數(shù)據(jù)庫一次,這樣的方式優(yōu)點(diǎn)在于每1000條數(shù)據(jù)才請(qǐng)求連接數(shù)據(jù)庫一次。請(qǐng)求連接數(shù)據(jù)庫是較耗時(shí)的一個(gè)步驟,頻繁的請(qǐng)求連接數(shù)據(jù)庫會(huì)拖慢程序的運(yùn)行時(shí)長。在基礎(chǔ)項(xiàng)時(shí),選擇將所有數(shù)據(jù)存入list,然后一次請(qǐng)求數(shù)據(jù)庫連接,將所有數(shù)據(jù)存入數(shù)據(jù)庫,請(qǐng)求數(shù)據(jù)庫連接的時(shí)間占比很小。
出現(xiàn)的問題以及解決方案
1000條數(shù)據(jù)一次存入無法達(dá)到實(shí)時(shí)的記錄,這是本小組項(xiàng)目的一個(gè)缺點(diǎn),但同時(shí),這個(gè)問題可以通過選擇storm 流式框架數(shù)據(jù)處理來解決,直接在Kafka消費(fèi)階段對(duì)數(shù)據(jù)進(jìn)行流式處理能達(dá)到實(shí)時(shí)效果。
2.數(shù)據(jù)查詢和離線處理分析
數(shù)據(jù)查詢:數(shù)據(jù)采集完成,所有數(shù)據(jù)存入Hbase數(shù)據(jù)庫的‘Record’表中,行鍵設(shè)計(jì)為eid、placeid、time組合鍵,在數(shù)據(jù)查詢時(shí),需要將行鍵截取,獲取對(duì)應(yīng)的數(shù)據(jù),與查詢條件比較,返回滿足條件的數(shù)據(jù)。
spark處理:spark分析過程包含三個(gè)階段——程序源碼發(fā)布到master節(jié)點(diǎn)、master將map程序分配給map節(jié)點(diǎn)進(jìn)行map操作、master將reduce程序分配給reduce節(jié)點(diǎn)進(jìn)行reduce操作。數(shù)據(jù)流向是map節(jié)點(diǎn)從master節(jié)點(diǎn)獲取Hbase數(shù)據(jù)索引,進(jìn)而獲取數(shù)據(jù),接著運(yùn)行map程序?qū)?shù)據(jù)分散處理。Map程序處理完的數(shù)據(jù)流入reduce進(jìn)行聚合處理,最后將reduce結(jié)果存入Hbase數(shù)據(jù)庫中。
問題:在進(jìn)行spark分析時(shí),限于物理機(jī),整個(gè)集群僅有一個(gè)master節(jié)點(diǎn)、一個(gè)map worker節(jié)點(diǎn)、一個(gè)reduce worker節(jié)點(diǎn),在數(shù)據(jù)分析時(shí)出現(xiàn)的情況是map worker節(jié)點(diǎn)的工作任務(wù)量遠(yuǎn)遠(yuǎn)大于reduce worker的工作任務(wù)量。在任務(wù)啟動(dòng)時(shí),集群中各個(gè)節(jié)點(diǎn)使用top命令查看當(dāng)前節(jié)點(diǎn)的CPU占比,發(fā)現(xiàn)在整個(gè)任務(wù)中map worker 節(jié)點(diǎn)長時(shí)間高CPU占比工作,而reduce worker節(jié)點(diǎn)在map worker節(jié)點(diǎn)處理完成后有10秒左右的高CPU占比工作期,然后整個(gè)數(shù)據(jù)分析完成。鑒于上述的問題,考慮在主機(jī)充足的情況下,選擇為map任務(wù)分配多臺(tái)主機(jī)。使得任務(wù)執(zhí)行量較均勻分布。
三、軟件功能分析
1、完成基本搭建系統(tǒng),完成過車統(tǒng)計(jì)功能
系統(tǒng)可根據(jù)輸入的地點(diǎn)ID進(jìn)行檢索,顯示通過該地點(diǎn)的車輛ID、時(shí)間、地點(diǎn)以及經(jīng)緯度;或者根據(jù)輸入的車輛ID,顯示出該車輛經(jīng)過的地點(diǎn)、經(jīng)過時(shí)間以及對(duì)應(yīng)地點(diǎn)的經(jīng)緯度。
結(jié)果展示:

2.系統(tǒng)附加功能分析
(1)原始信息過濾
原始數(shù)據(jù)包含若干條錯(cuò)誤記錄,如經(jīng)緯度不合法等,需要實(shí)時(shí)對(duì)kafka中接收到的數(shù)據(jù)進(jìn)行過濾處理,將處理后的數(shù)據(jù)傳遞給Redis。

(2)車輛行駛軌跡重現(xiàn)
實(shí)現(xiàn)方式:我們想出了兩種方法實(shí)現(xiàn)其軌跡重新。
A、hbase方式
建立一張新表,重新編排行鍵。
在hbaseTest類中完成具體操作。首先使用HBaseConf類中的getConnection()方法與HBase數(shù)據(jù)庫進(jìn)行連接。然后利用HBaseConf類中g(shù)etTableByName()方法得到對(duì)表“Record”表的操作句柄。同時(shí)使用相同的方法得到對(duì)Trace表的操作句柄。之后,使用Table類中的getScanner()方法得到Record表中的所有數(shù)據(jù),并記錄中“result”中。因?yàn)橹噩F(xiàn)軌跡的時(shí)候只需要車輛的標(biāo)識(shí)信息(Eid)和車輛經(jīng)過的時(shí)間(time)和經(jīng)過地方的經(jīng)緯度(latitude,longitude)所以我們只需要在“Trace”表中存入這些數(shù)據(jù)即可。
現(xiàn)在我們已經(jīng)將得到的所有的“Record”表中的數(shù)據(jù)都存在了“result”中。然后將result中的所有數(shù)據(jù)掃描一遍,同時(shí)將每條記錄中的“Eid,time,latitude,longitude”信息記錄下來,同時(shí)將每一條記錄的這些信息作為新的一條記錄,以“Eid”為rowKey且以“time”為列族的第一列放在Put類的對(duì)象中,最后通過Table類的put()方法將新的記錄存在“Trace”表中。這樣得到的“Trace”表中的數(shù)據(jù)即會(huì)以“time”自動(dòng)排序。
當(dāng)所有數(shù)據(jù)被讀取并被重新放入“Trace”表中后,關(guān)閉與數(shù)據(jù)庫的連接,所有的信息即被重新規(guī)劃好。
B、spark的MapReduce方式
展示結(jié)果:
輸入要查詢的車輛的ID,顯示其行駛軌跡。鼠標(biāo)點(diǎn)擊地點(diǎn),可顯示其經(jīng)緯度。
軌跡展示結(jié)果:

(3)車輛相遇次數(shù)統(tǒng)計(jì)
我們定義相遇為“兩車之間出現(xiàn)在同一地點(diǎn)的時(shí)間間隔小于一分鐘”。
首先,通過Spark從Hbase表中讀取數(shù)據(jù),自身以地點(diǎn)為鍵進(jìn)行join操作,計(jì)算除自身外的車輛是否相遇;再以地點(diǎn)為鍵進(jìn)行分組,同一組內(nèi)的數(shù)據(jù)按照時(shí)間進(jìn)行排序,遍歷整個(gè)列表,找出滿足小于一分鐘的數(shù)據(jù)。
結(jié)果展示:
輸入要查詢的車輛Id,查詢結(jié)果顯示與之相遇過的車輛的ID以及次數(shù)。

四、實(shí)驗(yàn)感受及收獲
在選修這門課之前,就已經(jīng)對(duì)云計(jì)算與大數(shù)據(jù)產(chǎn)生了濃厚的興趣,通過這學(xué)期對(duì)這個(gè)項(xiàng)目的完成,更加深了我對(duì)云計(jì)算與大數(shù)據(jù)的理解以及實(shí)際的應(yīng)用。此次我負(fù)責(zé)的部分是hbase對(duì)數(shù)據(jù)的存儲(chǔ),通過這個(gè)項(xiàng)目我了解了nosql的特點(diǎn)以及運(yùn)用。雖然在這個(gè)項(xiàng)目過程中,遇到了很多困難,但與隊(duì)友們一起不厭其煩地解決了,我在這個(gè)過程中學(xué)到了很多。希望在今后的云計(jì)算與大數(shù)據(jù)的學(xué)習(xí)道路上,可以克服重重困難,加深對(duì)其的學(xué)習(xí)。
|