bollm源碼
❶ jstorm 核心
生成Topology
IRichSpout
IRichSpout 為最簡單的Spout介面
其中注意:
=>spout對象必須是繼承Serializable, 因此要求spout內所有數據結構必須是可序列化的
=>spout可以有構造函數,但構造函數只執行一次,是在提交任務時,創建spout對象,因此在task分配到具體worker之前的初始化工作可以在此處完成,一旦完成,初始化的內容將攜帶到每一個=>task內(因為提交任務時將spout序列化到文件中去,在worker起來時再將spout從文件中反序列化出來)。
=>open是當task起來後執行的初始化動作
=>close是當task被shutdown後執行的動作
=>activate 是當task被激活時,觸發的動作
=>deactivate 是task被deactive時,觸發的動作
=>nextTuple 是spout實現核心, nextuple完成自己的邏輯,即每一次取消息後,用collector 將消息emit出去。
=>ack, 當spout收到一條ack消息時,觸發的動作,詳情可以參考 ack機制
=>fail, 當spout收到一條fail消息時,觸發的動作,詳情可以參考 ack機制
=>declareOutputFields, 定義spout發送數據,每個欄位的含義
=>getComponentConfiguration 獲取本spout的component 配置
Bolt
其中注意:
=>bolt對象必須是繼承Serializable, 因此要求spout內所有數據結構必須是可序列化的
=>bolt可以有構造函數,但構造函數只執行一次,是在提交任務時,創建bolt對象,因此在task分配到具體worker之前的初始化工作可以在此處完成,一旦完成,初始化的內容將攜帶到每一個task內(因為提交任務時將bolt序列化到文件中去,在worker起來時再將bolt從文件中反序列化出來)。
=>prepare是當task起來後執行的初始化動作
=>cleanup是當task被shutdown後執行的動作
=>execute是bolt實現核心, 完成自己的邏輯,即接受每一次取消息後,處理完,有可能用collector 將產生的新消息emit出去。 ** 在executor中,當程序處理一條消息時,需要執行collector.ack, 詳情可以參考 ack機制 ** 在executor中,當程序無法處理一條消息時或出錯時,需要執行collector.fail ,詳情可以參考 ack機制
=>declareOutputFields, 定義bolt發送數據,每個欄位的含義
=>getComponentConfiguration 獲取本bolt的component 配置
打包
提交jar
xxxx.jar 為打包後的jar
com.alibaba.xxxx.xx 為入口類,即提交任務的類
parameter即為提交參數
Storm中有個特殊的task名叫acker,他們負責跟蹤spout發出的每一個Tuple的Tuple樹(因為一個tuple通過spout發出了,經過每一個bolt處理後,會生成一個新的tuple發送出去)。當acker(框架自啟動的task)發現一個Tuple樹已經處理完成了,它會發送一個消息給產生這個Tuple的那個task。Acker的跟蹤演算法是Storm的主要突破之一,對任意大的一個Tuple樹,它只需要恆定的20位元組就可以進行跟蹤。
Acker跟蹤演算法的原理:acker對於每個spout-tuple保存一個ack-val的校驗值,它的初始值是0,然後每發射一個Tuple或Ack一個Tuple時,這個Tuple的id就要跟這個校驗值異或一下,並且把得到的值更新為ack-val的新值。那麼假設每個發射出去的Tuple都被ack了,那麼最後ack-val的值就一定是0。Acker就根據ack-val是否為0來判斷是否完全處理,如果為0則認為已完全處理。
要實現ack機制:
阿里自己的Jstorm會提供
public interface IFailValueSpout { void fail(Object msgId, List<object>values); }
這樣更合理一些, 可以直接取得系統cache的msg values
ack機制即,spout發送的每一條消息,在規定的時間內,spout收到Acker的ack響應,即認為該tuple 被後續bolt成功處理
在規定的時間內(默認是30秒),沒有收到Acker的ack響應tuple,就觸發fail動作,即認為該tuple處理失敗,timeout時間可以通過Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS來設定。
l或者收到Acker發送的fail響應tuple,也認為失敗,觸發fail動作
注意,我開始以為如果繼承BaseBasicBolt那麼程序拋出異常,也會讓spout進行重發,但是我錯了,程序直接異常停止了
這里我以分布式程序入門案例worldcount為例子吧。
有人問到Storm 是怎麼處理重復的tuple?
因為Storm 要保證tuple 的可靠處理,當tuple 處理失敗或者超時的時候,spout 會fail並重新發送該tuple,那麼就會有tuple 重復計算的問題。這個問題是很難解決的,storm也沒有提供機制幫助你解決。不過也有一些可行的策略:
(1)不處理,這也算是種策略。因為實時計算通常並不要求很高的精確度,後
續的批處理計算會更正實時計算的誤差。
(2)使用第三方集中存儲來過濾,比如利用 Mysql 、MemCached 或者 Redis 根據邏輯主鍵來去重。
(3)使用bloom filter 做過濾,簡單高效。
在學習storm的過程中,有不少人對storm的Spout組件中的ack及fail相關的問題存在困惑,這里做一個簡要的概述。
Storm保證每一個數據都得到有效處理,這是如何保證的呢?正是ack及fail機制確保數據都得到處理的保證,但是storm只是提供給我們一個介面,而具體的方法得由我們自己來實現。例如在spout下一個拓撲節點的bolt上,我們定義某種情況下為數據處理失敗,則調用fail,則我們可以在fail方法中進行數據重發,這樣就保證了數據都得到了處理。其實,通過讀storm的源碼,裡面有講到,有些類(BaseBasicBolt?)是會自動調用ack和fail的,不需要我們程序員去ack和fail,但是其他Bolt就沒有這種功能了。
❷ hbase源代碼 純java開發的嗎
是的,純java開發的nosql
❸ 如何用JAVA寫一個知乎爬蟲
下面說明知乎爬蟲的源碼和涉及主要技術點:
(1)程序package組織
(2)模擬登錄(爬蟲主要技術點1)
要爬去需要登錄的網站數據,模擬登錄是必要可少的一步,而且往往是難點。知乎爬蟲的模擬登錄可以做一個很好的案例。要實現一個網站的模擬登錄,需要兩大步驟是:(1)對登錄的請求過程進行分析,找到登錄的關鍵請求和步驟,分析工具可以有IE自帶(快捷鍵F12)、Fiddler、HttpWatcher;(2)編寫代碼模擬登錄的過程。
(3)網頁下載(爬蟲主要技術點2)
模擬登錄後,便可下載目標網頁html了。知乎爬蟲基於HttpClient寫了一個網路連接線程池,並且封裝了常用的get和post兩種網頁下載的方法。
(4)自動獲取網頁編碼(爬蟲主要技術點3)
自動獲取網頁編碼是確保下載網頁html不出現亂碼的前提。知乎爬蟲中提供方法可以解決絕大部分亂碼下載網頁亂碼問題。
(5)網頁解析和提取(爬蟲主要技術點4)
使用Java寫爬蟲,常見的網頁解析和提取方法有兩種:利用開源Jar包Jsoup和正則。一般來說,Jsoup就可以解決問題,極少出現Jsoup不能解析和提取的情況。Jsoup強大功能,使得解析和提取異常簡單。知乎爬蟲採用的就是Jsoup。
(6)正則匹配與提取(爬蟲主要技術點5)
雖然知乎爬蟲採用Jsoup來進行網頁解析,但是仍然封裝了正則匹配與提取數據的方法,因為正則還可以做其他的事情,如在知乎爬蟲中使用正則來進行url地址的過濾和判斷。
(7)數據去重(爬蟲主要技術點6)
對於爬蟲,根據場景不同,可以有不同的去重方案。(1)少量數據,比如幾萬或者十幾萬條的情況,使用Map或Set便可;(2)中量數據,比如幾百萬或者上千萬,使用BloomFilter(著名的布隆過濾器)可以解決;(3)大量數據,上億或者幾十億,Redis可以解決。知乎爬蟲給出了BloomFilter的實現,但是採用的Redis進行去重。
(8)設計模式等Java高級編程實踐
除了以上爬蟲主要的技術點之外,知乎爬蟲的實現還涉及多種設計模式,主要有鏈模式、單例模式、組合模式等,同時還使用了Java反射。除了學習爬蟲技術,這對學習設計模式和Java反射機制也是一個不錯的案例。
4. 一些抓取結果展示