本書是一本指導Storm用戶實踐應用的指南,從Storm組件的應用細節、Storm的代碼邏輯,到如何優化拓撲性能,以及如何在生產環境中部署Storm集群,作者將TheLadders的項目實踐經驗都整理歸納并在本書中完整呈現,配上大量圖例說明,還附帶了應用代碼演示,使讀者可以在短時間內學到作者花費多年才總結出來的Storm知識精華。
前 言
Preface在TheLadders,我們從Storm剛發布時就開始使用(那時的版本號還是0.5.x)。剛開始,我們只在一些非關鍵的業務流程上部署Storm,在很長的一段時間里,我們的Storm集群都一直處于持續運行的狀態,且十分穩定。正因為沒出過什么問題,所以我們也沒花太多的心思在上面。直到需要應對更多業務時,我們意識到Storm剛好是最合適的解決方案,可結果在實施的過程中暴露出了各種各樣的問題。例如,我們需要在生產環境中去應對資源爭奪,缺乏對底層運行原理的充分認知,不斷尋找優化性能的次優方案,面臨缺少可視化的系統運行狀態監控,等等。
這促使我們花費大量的時間和精力去研究本書中即將呈現的內容。在學習理解Storm的過程中,我們多次翻閱了所有可找得到的文檔,深入研究相關源代碼,整理最適合的Storm解決方案,不斷總結“最佳實踐”,并且我們還增加了自定義的監控系統,便于更有效地排查故障和優化方案。
你可以在網上輕松查到有關Storm的原理文檔,但我們發現,市面上依然缺少可以基于生產環境,指導使用Storm的實踐應用文檔。我們為此在博客上撰寫了大量有關Storm的使用經驗,所以當Manning找到我們希望合作一本Storm書籍時,大家一拍即合。我們有太多的知識想和大家一起分享,希望可以幫助大家少走我們曾走過的彎路,避開一些我們曾踩過的坑。
雖然我們分享出來的內容主要是基于在生產環境中,如何對Storm集群做優化、調試和故障排查,但我們更希望強調這里對Storm原理所需要的深入理解,同時展示出Storm的靈活性和廣泛適用性,即使我們僅能代表眾多使用Storm公司中的一員。
在本書中,我們將盡可能演示基于Storm下不同類型的應用案例,講解Storm的核心概念,以便更容易理解如何在生產環境中執行優化、調試和故障排查。希望這種形式能適用于不同層次的讀者,無論是剛接觸Storm的新人,還是擁有豐富經驗而且遇到過和我們有相似經歷的開發者。
本書絕對是一個團隊協作的結晶,無論是來自Manning的伙伴,還是來自TheLadders的同事,大家都從最開始就盡可能地支持我們,耐心地協助我們完成測試和驗證所有想法。
無論你的Storm使用經驗處于什么樣的層次,都希望本書能對你有所幫助,我們也很享受撰寫本書的過程,因為每一天我們都學到了更多關于Storm的知識。
致 謝?Acknowledgements感謝TheLadders所有為我們提供反饋和支持的同事,無論如何,這都是一本屬于集體的書,指導著我們在集群上實現更多更酷的功能。
也感謝來自Manning并為本書撰寫提供大量幫助的伙伴,這是一個很棒的團隊,在合作期間我們從他們身上學到了很多關于寫作的知識。特別感謝編輯Dan Maharry,從第1章開始一直到最后一章完成,他為第一次寫書的我們提供了大量的幫助,指導我們在錯誤和挫折中成長。
感謝所有參與本書的技術審校人員,感謝他們貢獻了自己私人的時間來核實書中的各技術要點:Antonios Tsaltas,Eugene Dvorkin,Gavin Whyte,Gianluca Righetto,Ioamis Polyzos,John Guthrie,Jon Miller,Kasper Madsen,Lars Francke,Lokesh Kumar,Lorcon Coyle,Mahmoud Alnahlawi,Massimo Ilario,Michael Noll,Muthusamy Manigandan,Rodrigo Abreau,Romit Singhai,Satish Devarapalli,Shay Elkin,Sorbo Bagchi以及Tanguy Leroux。其中我要著重感謝Michael Rose,感謝他為本書提供了大量高質量的反饋,可以說是本書最重要的技術審校人員。
感謝那些創造了Storm的人,沒有他們,我們就不會有日夜奮斗的理由!我們還會堅持使用Storm,也期待未來Storm可以帶來更新的改進。
感謝Andrew Montalenti在我們早期手稿中提供的反饋,這給了我們很大的啟發,并支撐我們完成了本書,他寫的推薦序也很棒,我們沒辦法要求更多了。
最后還要感謝Eleanor Roosevelt,她那句被大量錯誤引用的勵志名言“美國在哪里都講速度,燥熱、骯臟、惹是生非的速度”,鼓舞著我們在困難中前進,持續地學習Storm。
我們在看頒獎儀式時學到的一件事情,就是一定要感謝一路走來幫助我們的每一個人。
Sean Allen感謝Chas Emerick,如果不是因為和他激烈的爭論,我可能根本不會下決心來寫一本書,如果沒有他的付出,可能就不會有人有機會讀到這本書了。Stephanie,感謝他在我每次都想放棄的時候鼓勵我堅持下去。Kathy Sierra,感謝他在Twitter上和我溝通,讓我能梳理清晰寫作的思路。感謝Matt Chesler和Doug Grove,他們幫助糾正了第7章的寫作方向。感謝在TheLadders向我咨詢問題的伙伴,是他們幫助我完成了第8章。感謝Tom Santero,幫我審閱了我在分布式系統上的一些細節。感謝Matt,幫我做了大量寫書期間必須要做但我又不想做的事情。
Matthew Jankowski首先感謝我的妻子Megan,她是我永恒的動力來源,無論寫書會占用多少時間,她都表現出無限的耐心,給予我堅定的支持。可以說沒有她,我是無法完成本書的。還有我的女兒Rylan,感謝她出生在寫作的這段時間里,她給了我很大的啟迪,也許她到現在還根本沒意識到吧。感謝我的家人、朋友和同事,感謝他們的無限支持和建議。感謝Sean和Peter在剛開始聽到這個想法后,就愿意一起參與到本書的創作,這的確是一段漫長的經歷,感謝有他們一起一路走來。
關 于 本 書?About this book大數據的概念日趨流行,能用于處理實時流數據的工具顯得尤其重要,Apache Storm就是這樣一個能處理無限流數據的工具。
本書不僅供新手入門,也不只針對高階學習。盡管理解大數據技術以及分布式系統可以幫助閱讀,但我們并不希望這是作為閱讀本書的前提條件。我們盡可能嘗試迎合新人或是熟悉該領域的讀者,本書最初的目的就在于呈現如何在生產環境中應用Storm的“最佳實踐”,但為了更深刻地了解Storm的應用,一些基礎知識還是有必要預習的,所以我們希望本書的內容可以面向不同經驗層次的工程師。
如果你是剛開始學習Storm的新人,那么我們建議先閱讀第1~4章,并且確保要全面理解,因為這幾章包含了后面所需要的全部基礎概念知識。如果你是有Storm應用經驗的讀者,那希望后面的章節會對你們更有幫助。總之,設計開發基于Storm的解決方案僅僅是個開始,在生產環境中實踐這些方案才是我們需要在Storm上思考的重點。
本書的另外一個目的就是希望盡可能描述Storm的應用領域,基于此我們選擇了一些典型的用戶場景,希望對于理解未覆蓋到的用戶場景可以起到舉一反三的作用。我們在選擇用戶場景的時候也做了不同難度的區分,希望至少能有一種可以適用于你當前正在使用的Storm場景。
本書旨在關注Storm的運行方式,而我們意識到Storm需要和許多不同的技術一起使用,包括不同的消息隊列實現以及數據庫操作實現等,所以在講解每種用戶場景的時候,我們會很謹慎地選擇使用到的技術。我們不希望花太多精力在技術選型上,從而忽視了Storm使用上的重點講解,所以你看到的每一個演示都默認使用的是Java語言。如果將案例中的應用切換到使用另外一門語言,這么做其實很容易,但我們還是希望明確一點,那就是本書的核心講解并不在這些上面(事實上,我們在自己寫的拓撲上大量使用了Scala)。
路線圖第1章介紹大數據和Storm在大數據中所處的地位,該章的目的是展示一個選擇Storm的理由和時機,一些關于大數據應用的關鍵特性,各類用于處理大數據的工具,以及明確Storm的工具類型。
第2章借助一個對某GitHub庫提交數的統計案例,解釋Storm的核心概念。該章將建立學習Storm的相關術語基礎,嘗試一小段代碼來學習建立Storm工程,而這個案例中的概念也將貫穿本書。
第3章講解在Storm下設計拓撲結構的最佳實踐,同時以一個社交熱力圖的應用為例,展示了如何將問題基于Storm的結構來做分解,以便適用于程序的上下文實現部署。該章還討論了如何處理不穩定的數據源,或者是不可靠的外部服務。同時在該章中介紹的首字節并行性,也將成為后續章節中的重點,最后在該章中還深入討論了高級拓撲設計范式。
第4章以一個信用卡的授權系統為例,探討Storm如何確保消息以上下文的形式傳輸,闡述Storm的實現機制,并且如何基于一套方案的部署,提供不同層面的可靠性支持。同時該章在最后做一個總結,說明如何在Storm的拓撲結構上,實現這種不同層次的可靠性支持。
第5章涵蓋Storm集群的相關細節,還將討論Storm集群的各類組件,Storm集群如何提供容錯機制,以及如何配置一個Storm集群,并在Storm集群生產環境中部署并啟動拓撲。該章的提示內容將重點解釋Storm的UI部分,因為后面的章節會越來越多地涉及Storm UI中的相關操作。
第6章闡述在Storm的拓撲結構中,基于一個限時搶購系統的應用案例,如何實現反復調優的過程。同時還討論如何與外部系統協作,以及會對現有拓撲結構產生的影響。最后,我們將借助Storm現有的指標收集API,講解如何建立你的自定義指標。
第7章涵蓋在同時使用多拓撲的時候,Storm集群可能發生的各種沖突。我們將從一個拓撲中出現資源沖突的情況開始,逐步展開至拓撲間的系統資源沖突,以及Storm進程和其他進程甚至是操作系統之間的系統資源沖突分析,該章將帶你領略Storm集群的完整應用效果。
第8章深入講解Storm,在完整理解后,你基本上就能應對各種情況下的調試了。還深入講解Storm的并行化和執行器的中心單元,Storm的內部緩存調用方式,溢出的前提條件,如何優化這些緩沖配置等,最后討論Storm的調試日志輸出。
第9章講解Trident架構,它是一個基于Storm的上層抽象應用架構,同時演示基于它開發一個互聯網廣播應用。還解釋Trident結構的優勢,以及什么情況下你會使用到它。我們會比較一個常規的Storm拓撲和一個基于Trident結構的拓撲,分析兩者之間的區別。該章還將涉及Storm的分布式遠程過程調用(DRPC)組件,以及如何借助它來實現拓撲的狀態查詢。最后,演示一個完整的Trident拓撲部署,以及如何實現該結構的擴展。
代碼的下載和使用規范本書中的所有代碼可以在https://github.com/Storm-Applied中下載,包含以下章節中涉及的源代碼。
第2章,GitHub的提交次數計數。
第3章,社交熱力圖。
第4章,信用卡授權。
第6章,限時搶購系統。
......
目 錄?Contents
譯者序
序
前言
致謝
關于本書
關于原書封面插圖
第1章 Storm簡介 1
1.1 什么是大數據 1
1.1.1 大數據的四大特性 2
1.1.2 大數據工具 3
1.2 Storm如何應用于大數據應用場景 5
1.3 為什么你希望使用Storm 9
1.4 小結 10
第2章 Storm核心概念 11
2.1 問題定義:GitHub提交數監控看板 11
2.1.1 數據:起點和終點 12
2.1.2 分解問題 12
2.2 Storm基礎概念 13
2.2.1 拓撲 13
2.2.2 元組 15
2.2.3 流 16
2.2.4 spout 17
2.2.5 bolt 18
2.2.6 流分組 20
2.3 在Storm中實現GitHub提交數監控看板 22
2.3.1 建立一個Storm工程 22
2.3.2 實現spout 23
2.3.3 實現bolt 26
2.3.4 集成各個部分組成拓撲 29
2.4 小結 30
第3章 拓撲設計 31
3.1 拓撲設計方法 32
3.2 問題定義:一個社交熱力圖 32
3.3 將解決方案映射至Storm的邏輯 33
3.3.1 考慮數據流本身施加的要求 33
3.3.2 將數據點表示為元組 34
3.3.3 確定拓撲組成的步驟 35
3.4 設計的初步實現 38
3.4.1 spout:從數據源讀取數據 38
3.4.2 bolt:連接至外部服務 39
3.4.3 bolt:將數據寄放在內存里 41
3.4.4 bolt:持久化存儲到數據庫 45
3.4.5 定義組件間的流分組策略 47
3.4.6 在本地集群模式中構建一個拓撲 48
3.5 擴展拓撲 49
3.5.1 理解Storm中的并行機制 50
3.5.2 調整拓撲配置來解決設計中遺留的瓶頸 54
3.5.3 調整拓撲以解決數據流中固有的瓶頸 60
3.6 拓撲的設計范式 63
3.6.1 分解為功能組件的設計方法 65
3.6.2 基于重分配來分解組件的設計方法 65
3.6.3 最簡單的功能組件與最少的重分配次數 69
3.7 小結 70
第4章 設計健壯的拓撲 71
4.1 對可靠性的要求 71
4.2 問題定義:一個信用卡授權系統 72
4.2.1 有重試特性的概念性解決方案 72
4.2.2 定義數據點 74
4.2.3 在Storm上實現帶有重試特性的方案 74
4.3 bolt基礎實現 76
4.3.1 AuthorizeCreditCard的實現 76
4.3.2 ProcessedOrderNotification的實現 77
4.4 消息處理保障 78
4.4.1 元組狀態:處理完成或失敗 78
4.4.2 bolt中的錨定、應答和容錯 80
4.4.3 spout在消息處理保障中的角色 84
4.5 回放語義 87
4.5.1 Storm中可靠性的級別 87
4.5.2 在Storm拓撲中檢查僅一次處理 88
4.5.3 檢查拓撲中的可靠性保障 89
4.6 小結 94
第5章 拓撲由本地到遠程的實施 95
5.1 Storm集群 96
5.1.1 解析工作結點 98
5.1.2 基于信用卡授權拓撲的上下文來理解工作結點 99
5.2 Storm集群容錯中的快速失敗機制 100
5.3 安裝Storm集群 101
5.3.1 配置Zookeeper集群 101
5.3.2 在 Storm 的主結點和工作結點上安裝依賴組件 102
5.3.3 安裝Storm到主結點和工作結點 102
5.3.4 通過storm.yaml配置主結點和工作結點 102
5.3.5 在監督機制下啟動Nimbus和Supervisor 103
5.4 在Storm集群上運行拓撲 104
5.4.1 重新考慮如何將拓撲組件組合在一起 104
5.4.2 在本地模式下運行拓撲 105
5.4.3 在一個遠程 Storm 集群上運行拓撲 105
5.4.4 在一個遠程Storm集群上部署拓撲 106
5.5 Storm UI及其在集群中的角色 107
5.5.1 Storm UI:Storm集群概要 107
5.5.2 Storm UI:獨立拓撲概要 111
5.5.3 Storm UI:獨立spout/bolt概要 115
5.6 小結 118
第6章 對Storm進行調優 120
6.1 問題定義:Daily Deals!重生版 121
6.1.1 創建概念性解決方案 121
6.1.2 將方案轉換為Storm設計 122
6.2 初始化實施 122
6.2.1 spout:讀取自一個數據源 124
6.2.2 bolt:查找推薦商品 125
6.2.3 bolt:為每個商品查詢詳細信息 126
6.2.4 bolt:保存推薦的商品詳情 127
6.3 調優:我想為它提速 128
6.3.1 Storm UI:調優的定位工具 128
6.3.2 為性能值建立一個基線集 130
6.3.3 判斷瓶頸 131
6.3.4 spout:控制數據流入拓撲的速率 135
6.4 延遲率:當外部系統依然能正常工作時 137
6.4.1 在拓撲中模擬延遲 137
6.4.2 延遲的外因和內因 139
6.5 Storm的指標統計API 143
6.5.1 使用Storm的內建
CountMetric 143
6.5.2 設置一個指標接收器 144
6.5.3 創建一個自定義的SuccessRateMetric 145
6.5.4 創建一個自定義的MultiSuccessRateMetric 147
6.6 小結 149
第7章 資源沖突 150
7.1 調整一個工作結點上運行的工作進程數量 152
7.1.1 問題 152
7.1.2 解決方案 152
7.1.3 討論 153
7.2 修改工作進程(JVM)上的內存分配 153
7.2.1 問題 153
7.2.2 解決方案 154
7.2.3 討論 154
7.3 定位拓撲上運行的工作結點/進程 154
7.3.1 問題 154
7.3.2 解決方案 155
7.3.3 討論 155
7.4 在一個Storm集群中的工作進程沖突 156
7.4.1 問題 157
7.4.2 解決方案 157
7.4.3 討論 158
7.5 在一個工作進程(JVM)中的內存沖突 159
7.5.1 問題 162