屠龍記

我是一個正經的大齡c#程序員,突然接到了一個大數據報表需求,開發語言python,框架pyspark,腳本運行環境juypter.

需求是這樣的:

工廠有很多生產線,每個生產線都有一套工序,每個工序都要掃碼,我的任務就是得到工序之間的時間差,計算一個叫leadtime的指標,分析每條產線的哪個環節耗時比較多。

工廠每天大概掃碼1000w左右,所有掃碼信息都存在一個pg數據庫的一個表裏面,格式大概爲一個編碼列,一個json列。編碼列主要存儲玻璃碼信息,json列裏面含有各種信息需要提取。數據庫尺寸非常龐大,會定期做歸檔。

一個產線的掃碼大致是這樣的,白片階掃白片碼,鐳碼工序有白片碼和成品碼,成品階之後只掃成品碼。意思就是說一個產品線的工序之間沒有一個碼貫穿,必須通過鐳碼工序銜接。當然這是典型的情況,也有其它情況。

拿到這個需求,頭很大,有沒有。公司要求2個月搞定,慌不慌?

既來之則安之。

python不會怎麼辦,惡補,spark不會怎麼辦,現找資料。以上工作大概2周弄了個大概,開幹。

大致理了一下思路:

1把數據同步到ods層(hive)

2清洗json,提取白片碼,成品碼,工序,產品線,掃碼時間等關鍵信息(dwd層)

3dws層,這層很頭疼,到底該如何計算?如何存儲?

4dm層,好像沒啥太大難度

5報表綁定,也很容易

問題主要就卡在第三步,如此大的數據量算兩兩之差到底蓋如何設計表?

找了幾個程序員頭腦風暴了一番,感覺都沒啥好的思路,能說服我就那樣或者這樣幹。都把它當成在sql數據庫的常識來看待問題了,如何設置主鍵,設置索引,如何分區,同事們想到的大多是一行一個碼,工序,時間,產線。轉碼如何從頭到尾關聯,數據量如此龐大如何處理?關於計算方面,也沒啥好的建議,反正比較亂,感覺不靠譜。既然都沒有這方面經驗借鑑,看來還得自己努力!

思索幾天,突然靈光一閃,列式存儲。數據行數將大大減小。雖然每個產品線的工序數量不一樣,但是完全可以做點冗餘,工序默認30列,那麼差值就是29列。這樣既方便計算又方便檢驗。

工序如何和列名對應呢?首先列名肯定不能是工序名,工序名是配置的,不固定,肯定不行。然後是如何體現工序的順序呢?思來想去一個想法湧現出來:工序列就叫p1,p2,p3,差值列叫diff1,diff2...,後面再根據工序,產線配置表確定p1,p2是什麼意思。

接着是下一個問題,碼到底應該如何處理?特別是轉碼,如何像糖葫蘆一樣形成一個串?

只存白片碼?只存成品碼?白片成品都存?hive還是kudu?一時之間不好定奪。既然不好定奪,那就擼起代碼再說。三套方案:

1hive表存,假設hive sql非常強大,直接sql join搞定

2hive表存,假設spark join運算能力優秀,搞定

3kudu表,做upsert操作(根據主鍵做insert或者update)

代碼1 方案1思路,上sql,實驗直接報廢,join太多,第一個工序和最後一個工序的時間差值可能很大,數據量太大,直接能跑死

代碼2 方案1思路,sql結合spark編程,雖然對過程做了一些分解,依然算死

代碼3 全spark寫法,依然被斬落馬下

.

.

.

代碼m 依舊沒能成功

雖然沒成功,卻積累了很多經驗。所謂大數據平臺,所謂map計算,也不是吊炸天的存在!必須對任務進行友好劃分,任務大小需要均勻分佈纔有可能打開成功的門。

有了前面的積累開始捲土重來,開始實驗方案3,寫了4個版本之後,第5個版本終於迎來了曙光,能跑出數據來了!雖然能跑出數據,耗時卻很高,另外一個問題就是cpu被我的程序搶太多了,其它程序運行不好。這時候ai發揮了強大這時ai起到了很大作用,對着ai一大堆靈魂拷問,終於調對了spark參數,問題基本得到解決。(ai還不是特別精確,經常會給出錯誤的東西,所以還是需要不斷嘗試)

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