有點懷念起北京來。
史鐵生小說裡的地壇,滿山楓葉的香山,如詩如畫的頤和園,美侖美奐的天壇 , 很多景點都讓我流連忘返。
在我心裡,有一處很神聖的地方,它是知識和希望的象徵,那就是國家圖書館 。
一段在國家圖書館學習流式計算的經歷 ,就如同刀刻斧鑿一般,刻在我的腦中 。
寫這篇文章,想和大家聊聊這段學習流式計算的經歷,希望對大家有所啟發。
中國國家圖書館位於北京市中關村南大街33號,與海淀區白石橋高粱河、紫竹院公園相鄰。它是國家總書庫,國家書目中心,國家古籍保護中心,同時也是世界最大、最先進的國家圖書館之一 。
中國國家圖書館前身是籌建於1909年9月9日的京師圖書館,1931年,文津街館舍落成(現為國家圖書館古籍館)。新中國成立後,更名為北京圖書館。1987年新館落成,1998年12月12日經國務院批准,北京圖書館更名為國家圖書館,對外稱中國國家圖書館。
中國國家圖書館總建築面積28萬平方米,圖書館分為總館南區、總館北區和古籍館,館藏文獻3768.62萬冊,其中古籍文獻近200萬冊,數位資源總量超過1000 TB,是亞洲規模最大的圖書館,居世界國家圖書館第三位。
每到週末,當我想安靜下來,專注思考時,我就會揹著筆記型電腦來到國家圖書館。
選擇自己喜歡的書,然後將筆記型電腦開啟,一邊看書,一邊在電腦上寫點筆記。
偶爾擡起頭,望著那些正在閱讀的讀者,心裡面感覺很陽關,覺得生命充滿了希望。
2014年,我在藝龍旅行網促銷團隊負責紅包系統。彼時,促銷大戰如火如荼,優惠券計算服務也成為藝龍業務系統中最重要的系統之一。
而優惠券計算服務正是採用當時大名鼎鼎的流式計算框架 Storm。
何為流式計算 ?
流式計算是利用分散式的思想和方法,對海量「流」式資料進行實時處理的系統,它源自對海量資料「時效」價值上的挖掘訴求。
優惠券計算服務的邏輯是:每個城市每個酒店的使用優惠券的規則並不相同,當運營人員修改規則之後,觸發優惠券計算服務,計算完成之後,使用者下單時在使用優惠券時會呈現最新的規則。
優惠券計算服務是我們團隊的明星專案,很多研發的同學都對 Storm 特別感興趣 , 因為 Storm 的核心開發語言是 clojure , 比較小眾。
於是,在團隊內部,發現一個很有趣的現象:很多同學的辦公桌上放著《clojure in Action 》這本書。
彼時,藝龍開始發力行動網際網路,業務量的激增,優惠券計算服務遇到了瓶頸。
比如運營人員修改全量規則時,整個計算流程要耗時一上午,也就談不上實時計算了。
CTO 幾次找團隊負責人,並嚴厲批責成他儘快優化。
沒想到,經過一個半月幾次優化,系統的瓶頸依然明顯,時不時運營同事會走到我們的工位附近,催促我們:「系統生效了麼? 」
每到這個時候,我都感到很疑惑:「難道優惠券計算服務真的那麼複雜嗎? Storm 框架真的那麼難以維護麼? 」
想要揭開 Storm 神祕面紗的探索欲,同時解決公司技術問題的渴望,讓我好幾天晚上沒睡好。
於是週六上午9點半, 我揹著筆記型電腦來到國家圖書館。
學習一門技術,首先需要了解 Storm 的整體概念。
當我在官網上看到 Storm 的邏輯流程圖時, 做為程式設計師,我第一次感覺到抽象之美。
從源頭流下來的水通過水龍頭( Spout ),再經過層層轉接頭( Bolt )過濾,不就是我們想要的純淨水嗎?
當我瞭解了 Storm 整體概念 , 下一步也就是大家熟知的寫 Hello World 階段了 。
我參考教學寫了一個簡單的 Storm 應用(簡稱:拓撲),在部署後,程式正常跑了起來。
我腦海裡一直有一個概念:「是不是優惠券計算服務的 storm 叢集的設定沒有調優,導致計算的效能太差 ? 」 所以我必須去理解 storm 的並行度是如何計算的。
整個下午,我一直在查閱相關的資料,並結合上圖思考:Nimbus, Supervisor ,Worker ,Task 這些名詞到底是什麼概念。拓撲到底會啟動幾個程序,每個程序內部執行緒模型是怎樣的,頗有些庖丁解牛的味道。
等天色已黑,我走出國圖的大門,內心裡面,有莫名的自信,我相信自己可以解決優惠券計算服務的問題了。
感覺自己就像仙劍奇俠傳裡的酒劍仙,伴隨著激昂的 BGM ,拔劍四顧,斬妖除魔。
御劍乘風來,除魔天地間,有酒樂逍遙,無酒我亦癲。
一飲盡江河,再飲吞日月,千杯醉不倒,唯我酒劍仙。
雖然我大體瞭解了 Storm 的機制,但是我還不太瞭解優惠券計算服務整體邏輯,所以我必須梳理流式計算的整體流程。
流式計算整體流程分為三個步驟 :
我找到負責優惠券計算服務的同事,匯出相關紀錄檔。
分析紀錄檔後,令人驚奇的是:一次全量計算需要耗時4個小時,但步驟1竟然需要2個多小時,因為我們需要找到效能最薄弱的點,攻堅解決。那麼應該優先優化酒店拉取服務。
之所以拉取慢,是因為它的執行緒模型不夠好,部署多個節點,每個節點只能有兩個執行緒執行拉取任務。而且老程式碼年久失修,維護成本頗高,於是和團隊負責人溝通後,我決定重構該服務。
在重構工程裡,我必須做到如下兩點:
因為 RocketMQ 剛開源不久 , 我將 RocketMQ 如何建立執行緒的知識點正好也用了上去。
這次重構也非常成功,我們將原來的老服務替換後,部署了3個節點, 每個節點8個 worker 並行拉取酒店資訊 。
驚喜的發現,原來需要4個小時的全量處理時間縮短成了1個半小時,看來我這次重構非常成功,而且沒有出現一例 BUG 。
優化結束了嗎? 沒有,當步驟1優化後,我們還有步驟2,步驟3可以優化。
在閱讀優惠券計算服務的程式碼中,我發現兩個問題:
我提了兩點建議:
步驟三也並行進行,一位研發同學將原來的單條資料入庫修改成批次入庫。
當所有的優化完成後,原來4個小時的全量計算已經縮短成四十多分鐘了。 以後,運營小姐姐就很少來我們工位了。(^-^)V
我至今都記得 :
當我第一次看到 Storm 的邏輯圖時,感嘆中介軟體設計的抽象之美 ;
當我走出國圖門口,那麼的意氣風發,那麼的捨我其誰 ,我就是酒劍仙,御劍乘風來,除魔天地間 ,那些技術問題算什麼,我一一給你們剷除;
當我和技術負責人保證我可以解決這個問題時,他不情願和難以置信的表情;
當我和同事做酒店拉取服務 Code Review 時,當講到如何建立執行緒時,同事們目瞪口呆的表情,我暗自竊喜:那是我學習 RocketMQ 的效果;
當酒店拉取服務上線後,全量資料計算的時間從4個小時變成1個半小時,我興奮著拍著桌子,旁邊的同事都神奇的看著我;
當我指出Storm 拓撲的問題時,我是那麼篤定 ,最後優化結果也和我預期的一樣 。
當優惠券計算服務優化完畢,一切塵埃落定,卻又好像什麼都沒發生。
時光荏苒,生命中遇到越來越多的挫折,有的時候也會讓人低落,但一想到那個時候的一往無前,頓覺生命又充滿了希望,對於人生也有了新的感悟。
如果我的文章對你有所幫助,還請幫忙點贊、在看、轉發一下,你的支援會激勵我輸出更高質量的文章,非常感謝!