李 星 鄔少飛
(武漢工程大學計算機科學與工程學院,湖北 武漢 430000)
在當前的交通運輸領域中,車聯(lián)網(wǎng)(IoV) 屬于物聯(lián)網(wǎng)(IoT)內(nèi)最典型的應用,但因汽車的使用存在周期性,使得數(shù)據(jù)的產(chǎn)生也存在周期性,汽車數(shù)據(jù)的海量產(chǎn)生會固定出現(xiàn)在早高峰和晚高峰期間。每天汽車產(chǎn)生的海量大數(shù)據(jù)存儲達到了日增數(shù)據(jù)15TB,而如此巨量的數(shù)據(jù)在每日的產(chǎn)生并不是均勻分布而是周期性的產(chǎn)生,在短時時間里面會產(chǎn)生大量的數(shù)據(jù)。為了應對數(shù)據(jù)波動性產(chǎn)生對集群存儲性能的影響,部分研究者從算法上希望能夠解決Hbase 數(shù)據(jù)不平衡的問題,比如通過對預先對數(shù)據(jù)進行采集分析后再進行數(shù)據(jù)的分配[1,2],還有對Hbase的原有算法進行優(yōu)化,這些方法很好地解決了數(shù)據(jù)的不均衡問題,實現(xiàn)了Hbase的最大化利用,但是面對TB級別的數(shù)據(jù)其對cpu和集群性能的損耗是巨大的。部分研究者對數(shù)據(jù)進行了預處理[3-5],通過對數(shù)據(jù)的特征進行提取,預估不同分區(qū)的負載情況,然后提前對region 進行拆分或是保證熱點數(shù)據(jù)分布在不同的分區(qū),保證Hbase的負載平衡,同樣面對TB 級別的數(shù)據(jù),其cpu 的消耗成為了新的瓶頸。近些年來,面對大數(shù)據(jù)量的存儲,高并發(fā)的場景,普遍會采用Kafka 作為中間件,因為Kafka 作為消息中間件所采取的消息消費模式是發(fā)布-訂閱的消息模式,面對不同的消費者,Kafka的分布式消息讀取可以很好地支持到它們,相對于以往的消息隊列,Kafka 單點的生產(chǎn)者和消費者擁有顯著的優(yōu)越性,能夠做到百萬級的讀寫速率,其吞吐量更高,性能更加優(yōu)越,同時它能將數(shù)據(jù)寫入磁盤的同時將數(shù)據(jù)復制到集群里面,這些處理不僅保證了數(shù)據(jù)的持久化更使數(shù)據(jù)的容錯性得到了保障[6]。
基于以上背景,為解決海量數(shù)據(jù)存儲在Hbase中的存儲問題,本文研究出一種基于Hbase的海量數(shù)據(jù)存儲方案??紤]到車聯(lián)網(wǎng)數(shù)據(jù)的特殊性本文采用了相應的行鍵設計和預分區(qū)[7-11]。
研究采用的數(shù)據(jù)來自實際傳輸進來的報文,原始數(shù)據(jù)包包含每輛車采集的該車編號信息、采集時間、各個部分的埋點信息等480個信號。經(jīng)過對原始數(shù)據(jù)的分析,確認了不同數(shù)據(jù)擁有不同的價值,以及不同數(shù)據(jù)的歸類不同,而大量的信息讓處理的成本更高,為了提高這些信息的利用價值和保證核心數(shù)據(jù)的不缺失,需要對數(shù)據(jù)先進行簡單的處理后再存儲進入Hbase數(shù)據(jù)庫里面,處理的具體步驟如下:
(1)剔除缺失數(shù)據(jù),缺失數(shù)據(jù)指的是當上傳的時候有些車輛的信息沒有被錄入到系統(tǒng)里面,當查詢該車輛或是該種車架信息的時候,該車輛的信息不存在,這些信息將無法錄入數(shù)據(jù)庫中。
(2)區(qū)分不同狀態(tài)信息,汽車數(shù)據(jù)中有部分是屬于報警數(shù)據(jù),在這些數(shù)據(jù)在中間件處理的時候就需要被識別出來,然后及時通過報警系統(tǒng)將數(shù)據(jù)上傳,關于這部分數(shù)據(jù)的存儲需要先通告報警系統(tǒng)后再錄入系統(tǒng)。
(3)剔除失效數(shù)據(jù),當數(shù)據(jù)傳輸過程中存在數(shù)據(jù)的累計,如所處環(huán)境的網(wǎng)絡信號差,導致后期上傳的數(shù)據(jù)的接收時間相同,對于這種數(shù)據(jù)僅取發(fā)送時間距離當下最近的數(shù)據(jù),對于其他數(shù)據(jù)不進行存儲,以防數(shù)據(jù)之間的沖突。
對于數(shù)據(jù)庫的優(yōu)化,不可忽略的部分就是進行預分區(qū)以及對行鍵進行優(yōu)化,針對不同的數(shù)據(jù)結(jié)構需要采取的分區(qū)方式和行鍵的設計都是不同的。面對車聯(lián)網(wǎng)的海量數(shù)據(jù),行鍵的設計和預分區(qū)都是十分重要。在對行鍵進行設計時,會對核心字段進行簡化并在最開始就約定實現(xiàn)的規(guī)則,在后期就依循著規(guī)則來生成行鍵。選取的行鍵要求能對存儲和查詢存在一定的優(yōu)化效果,而在當前的大數(shù)據(jù)量存儲的系統(tǒng)中,核心是進行存儲的優(yōu)化。面對行量數(shù)據(jù)存儲的場景,本文選擇了將核心字段處理后拼接到行鍵里面,同時對行鍵進行散列化,使行鍵能夠盡可能地散落在不同的Region 里面,避免熱點現(xiàn)象的出現(xiàn)。
為了達到這樣的存儲效果,當前系統(tǒng)采用的行鍵設計方案是:
第一,對車輛的vin碼的前四位進行了md5處理,將數(shù)據(jù)散列開;
第二,在后面添加車輛的vin碼(20位);
第三,添加數(shù)據(jù)類型(15 位)再加上采集時間(18 位,前14 位為年月日時分秒,第15 位為N 表示設備上沒有上傳采集時間,由系統(tǒng)自動加上當前時間作為采集時間);
第四,加隨機數(shù)(4位,解決同一時間上傳一個數(shù)據(jù)包,里頭包含兩個告警數(shù)據(jù)導致數(shù)據(jù)覆蓋的問題)。
最終的行鍵設計方案如表1所示。
表1 行鍵最終方案
相對于其他的數(shù)據(jù)而言,車聯(lián)網(wǎng)的大批量數(shù)據(jù)更多是直接存儲進入Hbase中,其90%以上的操作都是寫入操作,而且數(shù)據(jù)量極其巨大,面對這樣的場景可以直接將所有的數(shù)據(jù)存儲于一個列簇里面,將核心的數(shù)據(jù)如車輛定位、定位時的詳細時間、汽車移動速度、汽車的油量、汽車的里程數(shù)等數(shù)據(jù)封裝入一條Json字符串里,當需要處理時再提取字符串進行處理,這樣就僅需要一個列,可以極大減輕存儲的壓力。
第三,好教育要有一支數(shù)量充足的高素質(zhì)的校長、教師隊伍?!秶医逃虚L期教育改革與發(fā)展規(guī)劃綱要(2010 —2020年)》指出,有好的教師才有好的教育。高素質(zhì)、專業(yè)化的校長隊伍與師德高尚、業(yè)務精湛、充滿活力的教師隊伍,是構成好教育的最重要因素,也是辦好教育的第一資源。校長要敢于擔當,有教育情懷,有辦學思路,懂管理,全心全意為學生著想、為教職工服務。好教師不僅要有較高的學歷,更要有專業(yè)精神和正確的教育觀、學生觀、質(zhì)量觀。
當創(chuàng)建一個Hbase表的時候,如果不指定預分區(qū)Region,默認是只會創(chuàng)建一個Region。當海量數(shù)據(jù)寫入Hbase 的時候,所有的數(shù)據(jù)都會寫入默認的Region里面,直至Region的空間消耗完,然后進行拆分操作,將一個Region 劃分為兩個小的Region。這樣處理將會造成兩個問題:一是數(shù)據(jù)存儲在單一的Region 中,更容易出現(xiàn)單節(jié)點故障,這會影響到入庫的性能;二是該行為會導致磁盤的拆分,而拆分操作將使大量的集群I/O 資源被消耗掉。為了解決這些問題,本文結(jié)合Rowkey的設計確定預分區(qū)的方案。選擇在全表創(chuàng)建10個分區(qū),分區(qū)的劃分使用HexStringSplit算法實現(xiàn)。
數(shù)據(jù)實時處理是車聯(lián)網(wǎng)海量數(shù)據(jù)存儲的核心層。車聯(lián)網(wǎng)數(shù)據(jù)的處理對于實時性的要求是極強的,在一定時間里面若數(shù)據(jù)沒有處理完全,那么這一幀數(shù)據(jù)就會失效,因為只有滿足實時性才能實現(xiàn)對車輛的實時監(jiān)控,并做出及時的反饋。面對傳統(tǒng)平臺處理海量數(shù)據(jù)存在的高延遲、高并發(fā)問題,本文選擇了開發(fā)新的PVO 中間件擔任Kafka 到Hbase 中間的數(shù)據(jù)實時處理工作。
車載終端采集的數(shù)據(jù)是實時、不間斷的,要求實時處理層穩(wěn)定可靠、不宕機。而PVO層的處理能力是有限的,如果不進行獲取消費數(shù)據(jù)的限制可能會導致數(shù)據(jù)出現(xiàn)延時,當前數(shù)據(jù)還未處理完全,后面的數(shù)據(jù)又進來了,當完全堆積在PVO 的內(nèi)存后會導致程序壓力過大,降低程序的運行速度,嚴重情況下甚至會導致宕機。為了處理這個問題,選擇在中間件添加計數(shù)器進行數(shù)據(jù)消費的控制。
詳細處理流程如圖1。這里首先對PVO 的性能進行壓力測試,待內(nèi)存消耗完,測試出其最大的承受數(shù)據(jù)量為DEFAULT_MAX_BLOCKING_SIZE。PVO 會在對Kafka 數(shù) 據(jù)進行消費的同時用Scheduled 算法對消費數(shù)據(jù)進行監(jiān)控,當大流量涌入并超過最大承受量的時候就會進入等待期同時進行警告,等待期滿發(fā)現(xiàn)內(nèi)存釋放出來后會立刻繼續(xù)進行消費。此外,當出現(xiàn)網(wǎng)絡波動等問題時也會導致數(shù)據(jù)處理延遲,導致數(shù)據(jù)的堆積,針對這樣的問題,在處理數(shù)據(jù)前還會調(diào)取Hbase的數(shù)據(jù)存入耗時,當前面的數(shù)據(jù)存儲時間過長時,會先讓進程等待,同時進行警報處理,方便后期對問題進行排查和維護,直到等待期滿后再重復進行判斷,判斷通過后再進行數(shù)據(jù)處理。
圖1 數(shù)據(jù)處理流程圖
為了驗證上述Hbase表設計和數(shù)據(jù)處理優(yōu)化的性能,通過實驗對其進行評測。實驗使用的操作系統(tǒng)均為centos 6.10,所搭建的Hbase 集群部署在Cloudera Manager 上面,版本為5.13.1。CDH 版本為5.13.1,hadoop 版本為2.6.0,HDFS版本為2.6.0,Hbase 版本為1.2.0。Hbase 集群的詳細配置如表2所示。
表2 集群配置
為確認當前設計的Hbase行鍵方案是有效的且能夠提升存儲的性能,這里采取了相同的數(shù)據(jù)集進行輸入測試,控制數(shù)據(jù)集是相同的,數(shù)量也相同,唯一變化的就是行鍵是否進行設計,詳細的測試流程如下:
(2)每組對比實驗采用隨機模擬的報文數(shù)據(jù);
(3)每組實驗重復三次,取最終存儲效率的平均值繪圖。
按照以上的策略測試有行鍵設計的方案和沒有行鍵的設計方案,以Cloudera Manager 中對Hbase 寫數(shù)據(jù)的監(jiān)控數(shù)據(jù)作為對比,通過對比兩者的差異來比較兩種設計方案的優(yōu)劣。實驗結(jié)果如圖2所示,橫軸為數(shù)據(jù)開始輸入的時間,縱軸為一分鐘內(nèi)平均的數(shù)據(jù)請求數(shù)量。
圖2 存儲效率對比
由圖2可知,在前兩分鐘里面數(shù)據(jù)的寫入會快速達到最大峰值,然后就在該峰值處波動,直到數(shù)據(jù)存儲完畢沒有數(shù)據(jù)錄入的最后兩分鐘數(shù)據(jù)寫入才會大幅降低。同樣是寫入100w數(shù)據(jù),兩者的時間消耗不同,但是兩種方案都呈現(xiàn)了性能達到峰值后的穩(wěn)定性,這顯示了Hbase對于海量數(shù)據(jù)存儲的適用性,符合長期高性能穩(wěn)定的運行要求。同時,圖2中也可以看見無行鍵設計的方案每秒請求數(shù)在3w左右就達到了峰值,而有行鍵設計的方案直到6w 才到達數(shù)據(jù)存儲的峰值。實驗說明,在Hbase的表設計中,是否針對存儲做合理的行鍵設計,對數(shù)據(jù)的存儲性能影響較大。
在所搭建的平臺上對上述的優(yōu)化進行測試,實驗數(shù)據(jù)來自于內(nèi)部的報文模擬器。為驗證優(yōu)化后的中間件擁有更好的性能,采用如下方法進行測試:
(1)啟動報文模擬器穩(wěn)定向Kafka發(fā)送報文;
(2)開啟PVO中間件拉取Kafka的報文并對報文進行處理;
(3)將數(shù)據(jù)存儲到Hbase里面;
(4)通過Cloudera Manager的讀請求監(jiān)控觀測數(shù)據(jù)處理的穩(wěn)定性;
(5)關閉報文模擬器后切換PVO 中間件為優(yōu)化后的PVO中間件;
(6)重復步驟一到步驟四。
PVO優(yōu)化前后的監(jiān)控結(jié)果如圖3,可以很清晰地看到相比起優(yōu)化前的數(shù)據(jù)存儲,優(yōu)化后的數(shù)據(jù)存儲的穩(wěn)定性更強。
圖3 請求數(shù)目對比
車聯(lián)網(wǎng)在未來的交通出行扮演的角色越來越重要,對車聯(lián)網(wǎng)數(shù)據(jù)的處理也有著更大的需求。本文針對采集自海量汽車的詳細數(shù)據(jù),提出了一種基于Hbase對數(shù)據(jù)存儲性能進行優(yōu)化的中間件控制方案。該方案對原生的PVO中間件添加計數(shù)器限流的功能,該方法在實驗中展現(xiàn)出了更為優(yōu)越的穩(wěn)定性。該方案通過對Rowkey和表結(jié)構的設計使得存儲性能得到極大的提升。在Hbase的集群上進行測試,相對于未進行設計的Rowkey方案,優(yōu)化后的Rowkey方案展現(xiàn)了在存儲效率上的優(yōu)越性。