一個(gè)數(shù)據(jù)爬取和分析系統(tǒng)的演變過程
假設(shè)有這樣一個(gè)需求,需要你寫一個(gè)爬蟲,爬取微博中關(guān)于某個(gè)話題的討論,然后分析情感,最后用一個(gè)網(wǎng)頁來展示分析結(jié)果。那么你一開始的數(shù)據(jù)流程可能是這樣的:
后來,老板發(fā)現(xiàn)只有微博一個(gè)源不夠,于是又給你加了100000個(gè)源?,F(xiàn)在你的系統(tǒng)是這樣的:
為了防止太多的線做交叉,我做了一些處理。
一開始你調(diào)用 NLP 分析接口的時(shí)候,傳入的參數(shù)只有爬取內(nèi)容的正文,但有一天,NLP 研究員希望做一個(gè)情感衰減分析。于是你要修改每一個(gè)爬蟲,讓每一個(gè)爬蟲在調(diào)用 NLP 分析接口的時(shí)候,都帶上時(shí)間參數(shù)。這花了你幾天的時(shí)間。
你一想,這不行啊,豈不是每次增加修改字段,都要改每一個(gè)爬蟲?為了避免動(dòng)到爬蟲,于是你對(duì)系統(tǒng)架構(gòu)做了一些修改:
現(xiàn)在,爬蟲這邊總是會(huì)把它能爬到的全部數(shù)據(jù)都寫進(jìn) Kafka 里面。你的 ETL 程序只挑選需要的字段傳給 NLP 接口進(jìn)行分析,分析完成以后,寫入數(shù)據(jù)庫中。程序的處理線條變得清晰了。
你以為這樣就完了?還早呢。
有一天,你發(fā)現(xiàn)網(wǎng)頁上的數(shù)據(jù)很久沒有更新了。說明數(shù)據(jù)在某個(gè)地方停了。現(xiàn)在,你首先去 Kafka 檢查爬蟲的數(shù)據(jù),發(fā)現(xiàn)爬蟲數(shù)據(jù)是正常入庫的。那么,說明問題出現(xiàn)在下圖這一塊:
那么,請(qǐng)問是 ETL 在處理數(shù)據(jù)的時(shí)候出現(xiàn)問題導(dǎo)致數(shù)據(jù)丟失了,還是 NLP 接口出了問題,導(dǎo)致你傳給他的數(shù)據(jù)沒有返回?還是數(shù)據(jù)庫不堪重負(fù),寫入數(shù)據(jù)庫的時(shí)候出錯(cuò)了?
你現(xiàn)在根本不知道哪里出了問題。于是互相甩鍋。
為了避免這個(gè)問題,你再一次修改了系統(tǒng)架構(gòu):
現(xiàn)在通過檢查 Kafka 的數(shù)據(jù),我可以知道 ETL 程序是否正常輸出內(nèi)容。也可以知道 NLP 分析程序是否正常返回?cái)?shù)據(jù)。我還可以對(duì)比兩邊的數(shù)據(jù)變化率進(jìn)行監(jiān)控。甚至還可以通過監(jiān)控 Kafka,發(fā)現(xiàn)負(fù)面內(nèi)容太多時(shí),及時(shí)報(bào)警。
當(dāng)然,這還沒有完,如果還需要發(fā)現(xiàn)新的鏈接,并自動(dòng)抓取,那么又需要增加新的節(jié)點(diǎn)。又或者有一些內(nèi)容需要用瀏覽器渲染,又要增加新的節(jié)點(diǎn)……
大家可以看到,數(shù)據(jù)會(huì)反復(fù)進(jìn)出 Kafka,那么它的效率顯然會(huì)比直接用爬蟲串聯(lián)萬物的寫法慢。但我認(rèn)為這樣的效率損失是值得的。因?yàn)橥ㄟ^把系統(tǒng)拆解成不同的小塊,我們可以對(duì)系統(tǒng)運(yùn)行的每一個(gè)階段進(jìn)行監(jiān)控,從而能夠更好地了解系統(tǒng)的運(yùn)行狀態(tài)。并且,每一個(gè)小塊也能夠更方便地進(jìn)行維護(hù),無論是修 bug 還是增加新功能,都能減小對(duì)其他部分的影響,并且可以提高修復(fù)的速度。