為什麼一個星期工作量的工作,我做了一個多月,還沒結束
為什麼一個星期工作量的工作,我做了一個多月,還沒結束
為什麼一個星期工作量的程式碼,我寫了一個多月,還在寫
這是一個HIK平台WIFI數據接入的工作,先看下我的程式碼提交記錄:
首先有這兩方面的原因:1、初學Java時間不長,不夠熟練,這個原因浪費的時間並不多。2、與數據提供方溝通浪費的時間,因數據有問題,即DeviceId和資料庫中的DeviceId對不上,導致程式篩選不到數據,需要對方修改相關配置,由於我感覺事情並不急,所以是隔幾天催一下,浪費了不少天的時間,最後DeviceId依然對不上,我是怎麼解決的呢?由於基本上是一個設備布在一個地點,所以我是根據數據中的經緯度來篩選數據的,這種辦法其實還是有一點點問題的。
再說寫程式碼花費的時間,服務部署到現網後,就開始發現BUG了,程式處理數據的速度不夠,導致FTP上的ZIP包處理不完大量積壓,因為我用的是單執行緒處理數據,遂改成多執行緒處理數據。
經過優化和測試,發現數據處理速度還是不夠,FTP上數據產生的速度大約是380條每秒,可能會更多,而單機每秒最多只能處理200多條數據,繼續嘗試優化,但還是不行。所以我面臨第一個重要問題:把程式部署到多台機器,提高數據處理速度,程式該怎麼寫?
對於這個問題,經過探索,我最終的解決辦法是:把程式部署在5台機器上,程式跑起來後,能拿到機器名稱,FTP上的ZIP文件名帶有時間戳,根據機器名和時間戳的最後一位,把ZIP文件分配到5台機器處理,這樣就解決了數據處理速度不夠的問題。
我想解決的第二個重要問題是:由於我目前做的是大數據維護,學了點Spark和Flink知識,所以我想用Spark改寫,已經寫好的程式是SpringBoot的,所以我要做的是SpringBoot整合Spark。周末我在家搭了一個Hadoop+Spark的分散式集群環境,寫了個純Spark的Demo跑,正常。然後寫了個SpringBoot整合Spark的Demo,本地模式跑,即.setMaster(“local[3]”),正常。但是提交到集群跑,web api和swagger在線文檔正常,任務跑起來後在Spark Web頁面可以看到,但日誌報錯。我試了3種方式,一種是打war包部署在tomcat里,一種是用命令java -jar運行jar包,一種是用spark-submit命令運行jar包,任務跑起來後都報錯了,三種方式錯誤也不相同,搞到凌晨4點多,沒有解決,放棄。不過,就算我成功了,接下來的問題,可能依然無法解決,就是數據處理完後,要推送到Kafka,網上的教學都是教Spark怎麼處理Kafka流數據,Kafka數據是作為數據源的,不是作為目的地的,所以我的想法可能本身就是個問題。
解釋一下為什麼要SpringBoot整合Spark,只用Spark不用SpringBoot不行嗎?實際上之前同事就是這麼乾的,要麼用SpringBoot,要麼用Spark或Flink,沒有把SpringBoot和二者在一起用過,為什麼我要這麼做?因為我要讀mysql資料庫,我要用JDBC或者Mybatis等,如果不用SpringBoot,有些東西可能要自己搞,不太方便。
既然SpringBoot整合Spark沒有成功,那數據分配不均勻的問題怎麼解決(FTP上ZIP文件5分種產生5個文件,2個數據量大,3個不是我需要的數據可以直接刪了,但不管是按時間戳這個特徵分配,還是按序號這個特徵分配,都無法均勻分配,可能會導致一個節點數據積壓,另外3個節點沒有要處理的數據,即一個節點有難,3個節點圍觀,雖然時間尺度拉大後,數據分配是均勻的,但是數據處理延遲大了,5分鐘產生一個ZIP文件,意味著,有的數據已經延遲處理了5分鐘,而我這邊還要延遲幾分鐘到幾十分鐘不等)?這是我準備解決的第三個重要問題。
我用Socket解決了這個問題,我把程式部署在5個節點上,一個作為master節點,4個作為worker節點,程式啟動後根據機器名判斷,確定master節點,master節點從FTP上下載ZIP文件,FTP上ZIP文件可能很多,先只下載一個文件進行處理,一個文件中可能有多達10萬條數據,也可能就幾萬條數據,還可能不是我需要的數據,直接刪掉該ZIP文件即可,然後解析數據,再然後把數據集合平均分成4份,通過Socket發送給4個worker節點,worker節點收到數據集合,進行篩選和處理,然後推送到Kafka,數據處理完後,給master節點發送一條消息,可以重複發送幾次,再加上是區域網,以確保master節點能收到消息(這個很重要,但這裡也有問題),master節點收到4個節點數據處理完成的消息後,刪除FTP上的該ZIP文件。然後進行下一次處理,直到FTP上的ZIP文件全部處理完成並刪除。我今天寫完後,把寫ES日誌和發Kafka以及刪除ZIP文件的程式碼注釋掉,耗時的地方用Thread.sleep代替,部署到真實環境,看能不能穩定跑上一天。我感覺用Socket實現分散式數據處理,雖然能解決數據分配不均勻的問題,但是程式穩定性變差了,如果master節點收不到worker節點發來的數據處理完成的消息怎麼辦?假設其中一個worker節點的程式掛掉了呢?
雖然只是一個簡單的小任務,我真的是非常努力,如果我最初的設想成功,以後的類似服務都可以這麼寫,意義重大,可惜沒搞成功,退而求其次,用Socket寫分散式處理程式,我好像迷迷糊糊明白為什麼Spark要依賴Hadoop了,我自己用Socket寫漏洞很多啊,沒有把數據持久化,萬一漰了,數據就丟了。
有沒有大佬給指點一下,我努力的思路是不是有問題,有沒有程式碼又容易寫,又不容易寫錯,程式又穩定可靠的方案?