如何高可用的將大量數據通過kafka的讀出來並進行處理

先說一點,因爲項目原因需要對大量數據進行處理,有一個要求就是在5秒中之內將120w條數據推送到第三方app,怎麼理解呢,就是說每5秒中我可能要產生120w條數據,這些產生的數據需要發送到第三方app指定的接口上,保證數據能夠到達app端進行處理,這個app端不是指前端,可能是別人第三方的後臺服務接口,這些接口拿到這些數據怎麼處理是第三方app的事情,我們要做的事情就是要保證這麼多的數據能夠傳輸成功。

先來說思路:

面對每秒鐘20萬的數據量,要存儲這麼大的數據量,就很困難,所以,這些數據的存儲我們選擇用kafka進行臨時存儲,然後通過消費者將這些數據發給第三方app。至於kafka如何配置運用,建議直接去看學習資料瞭解。因爲kafka的讀寫都是非常快的,所以這樣的數據量完全不用擔心。

關於kafka中消費者從讀取數據的效率,根據實際測試,如果只是將數據讀取出來,不做任何處理的話,大概每5秒種能夠讀取數據在30多萬,所以爲了達到要求,方法就是增加消費者集羣,也就是消費服務多佈置在幾臺服務器上,這樣增加了橫向擴展之後呢,也就能滿足這樣要求了,同時我們是三個kafka集羣,服務消費者最多給到8臺服務器,所以最多給你8臺服務器,看似現在滿足要求輕而易舉了,實際不然,因爲這時候的效率是沒有包含處理和向第三方app發送的要求的。所以這時候的效率其實偏高,再加上雖然8臺,但其實最多隻能有7臺,還有一臺還要幹其他事。因爲我不負責kafka生產端,所以這塊我也不能細說,反正kafka中能夠生產出這麼多的數據,我這邊要乾的只是要滿足要求消費掉這些數據。

先說這個30多萬怎麼測出來的,因爲大家都知道kafka的消費者在java中的寫法是針對每個topic都創建一個線程去處理,每個線程都是一個死循環,然後再這個死循環中,循環通過poll方法讀取kafka數據,kafka默認單次poll出來是500條數據。讀出來的數據量用一個靜態變量進行記錄,然後通過定時任務每秒統計然後清零,因爲生產那邊的生產效率是這麼多,所以消費者這邊會受到生產者那邊生產速度的限制,但是這樣的讀取效率已經能滿足要求了。這是單臺服務器測出的數據。

但是將數據處理之後加上向第三方app發送數據後性能降到了每5秒18萬,這樣的效率勉強滿足,但是不夠,萬一服務器一個掛了怎麼辦。然後通過查看代碼,發現這個從kafka消費和向第三方app發送的操作在同一個線程之中,這樣的話,每次讀取數據必須等整個流程執行完才能進行下一次讀取處理。於是我們想到了讀發分離,將讀取和發送這兩個操作分開來進行處理,這樣不就提高效率了麼,這麼處理過後呢,你根本不用擔心讀的問題,因爲已經說了,讀都在30多萬,我們要關心的是發操作。如何將這些數據發送出去呢。說一下,這些數據被讀取出來後,存放在一個阻塞隊列之中。

我們要做的就是從這個隊列中去把數據讀出來然後發送就可以了。所以發送方同樣的,利用線程池創建多個線程,每個線程裏面都是死循環,通過循環的去讀取隊列裏面是否有數據,有數據,就poll讀出來進行發送到第三方app。發送到第三方app用的httpclient發送的,這個不用擔心,只要網絡正常,我這裏模擬測試了一下數據,80到90萬每5秒時沒問題的。最終測試在多線程下實現了每5秒27萬的發送,遠遠滿足要求。

 然後通過查看cpu佔用率,發現在250%左右,也滿足要求,因爲上面給的是300%一下,3個核心。

所以總結一下:多集羣、多線程、阻塞隊列。

通過一個阻塞隊列保存讀取出來的數據,通過多線程方式從隊列中讀取數據並處理髮送。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章