本發(fā)明涉及數(shù)據(jù)采集技術(shù)領(lǐng)域,特別涉及一種基于MongoDB和Redis的網(wǎng)頁數(shù)據(jù)采集處理方法及系統(tǒng)。
背景技術(shù):
當(dāng)前處于一個(gè)信息爆發(fā)增長的數(shù)據(jù)時(shí)代,專業(yè)化的數(shù)據(jù)分析和深度挖掘,不斷孕育出巨大商機(jī)。越來越多企業(yè)由傳統(tǒng)模式的依靠直覺和經(jīng)驗(yàn)判斷,轉(zhuǎn)向依靠大數(shù)據(jù)分析和預(yù)測來制定企業(yè)戰(zhàn)略決策,各企業(yè)對數(shù)據(jù)的獲取需求愈加強(qiáng)烈。特別地,對于那些并不直接生產(chǎn)大數(shù)據(jù)的互聯(lián)網(wǎng)中小企業(yè)而言,通過網(wǎng)絡(luò)爬蟲技術(shù)實(shí)施有針對性、行業(yè)性、精準(zhǔn)性的數(shù)據(jù)采集,間接建立企業(yè)的“大數(shù)據(jù)戰(zhàn)略”體系,就顯得尤為重要。不僅能大大降低企業(yè)大數(shù)據(jù)信息建設(shè)的成本,更能滿足企業(yè)業(yè)務(wù)發(fā)展要求,充分利用網(wǎng)絡(luò)數(shù)據(jù)價(jià)值,達(dá)到利益更大化。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明的目的在于針對現(xiàn)有技術(shù)的不足,提供一種基于MongoDB和Redis的網(wǎng)頁數(shù)據(jù)采集處理方法及系統(tǒng),便于企業(yè)低成本、高效率建立滿足自身業(yè)務(wù)發(fā)展需求的數(shù)據(jù)倉庫。
本發(fā)明的目的是通過以下技術(shù)方案來實(shí)現(xiàn)的:一種基于MongoDB和Redis的網(wǎng)頁數(shù)據(jù)采集處理方法,該方法包括以下步驟:
(1)設(shè)定網(wǎng)頁下載請求的格式:請求唯一標(biāo)識符id、業(yè)務(wù)類型biz、時(shí)間戳ts、請求實(shí)體內(nèi)容data、消息處理狀態(tài)flag;
(2)為下載請求分配全局唯一ID,對應(yīng)下載請求的id字段;
(3)基于分布式協(xié)同服務(wù),在配置中心預(yù)置各業(yè)務(wù)的網(wǎng)頁請求解析規(guī)則映射表、持久化節(jié)點(diǎn)列表、MongoDB數(shù)據(jù)庫名、集合名、集合水平拆分?jǐn)?shù)、Redis消息隊(duì)列名。
(4)依照配置中心預(yù)置的對應(yīng)業(yè)務(wù)負(fù)載均衡策略,完成對請求的轉(zhuǎn)發(fā):首先根據(jù)下載請求的業(yè)務(wù)類型biz,從配置中心獲取該biz預(yù)先定義的持久化節(jié)點(diǎn)列表、MongoDB數(shù)據(jù)庫名、集合名、集合水平拆分?jǐn)?shù)、Redis消息隊(duì)列名,再結(jié)合對唯一標(biāo)識符id求模取余策略,將請求持久化到MongoDB相應(yīng)的數(shù)據(jù)庫和集合,同時(shí)在Redis消息隊(duì)列記錄此條請求;
(5)采用MongoDB的副本集架構(gòu)將請求按業(yè)務(wù)類型分庫分表。將請求寫入MongoDB數(shù)據(jù)庫,并用id字段覆蓋MongoDB默認(rèn)的_id索引,對ts字段建立TTL索引,同時(shí)將id、biz、ts三個(gè)字段轉(zhuǎn)json格式后,利用lpush操作壓入Redis消息隊(duì)列;
(6)各下載服務(wù)器一直保持監(jiān)聽Redis消息隊(duì)列,輪詢提取請求并下載解析網(wǎng)頁,獲取目標(biāo)數(shù)據(jù)記錄入庫。
進(jìn)一步地,所述步驟6具體為:首先利用rpop或其阻塞版操作brpop從隊(duì)列彈出請求,再結(jié)合id、biz和ts這三個(gè)字段組合成查詢過濾條件,然后調(diào)用MongoDB的原子操作findAndModify查詢對應(yīng)的MongoDB持久化節(jié)點(diǎn)的數(shù)據(jù)庫和集合,即可得到完整的請求內(nèi)容,根據(jù)該請求附帶的解析規(guī)則映射表,解析頁面獲取目標(biāo)數(shù)據(jù)記錄入庫。
進(jìn)一步地,在步驟1-步驟6中,實(shí)時(shí)監(jiān)控網(wǎng)頁下載請求的生成速率;監(jiān)控服務(wù)節(jié)點(diǎn)的健康狀況:包括數(shù)據(jù)庫存儲容量、內(nèi)存使用率、慢查詢操作,以及內(nèi)存消息隊(duì)列的內(nèi)存占用、消息積壓程度等,當(dāng)遭遇節(jié)點(diǎn)故障或服務(wù)性能下滑超過設(shè)定閾值時(shí),及時(shí)以短信或郵件方式發(fā)送報(bào)警信息;監(jiān)控下載請求的處理速率,發(fā)現(xiàn)請求積壓嚴(yán)重或無法在計(jì)劃時(shí)間內(nèi)完成處理時(shí),及時(shí)增加處理節(jié)點(diǎn)動態(tài)擴(kuò)容。
進(jìn)一步地,所述步驟2中,使用SnowFlake為下載請求分配全局唯一ID。
一種基于MongoDB和Redis的網(wǎng)頁數(shù)據(jù)采集處理系統(tǒng),該系統(tǒng)包括以下模塊:全局ID生成器模塊、請求路由轉(zhuǎn)發(fā)模塊、配置中心、持久化模塊和消息隊(duì)列模塊;
所述全局ID生成器模塊為下載請求分配全局唯一ID,對應(yīng)下載請求的id字段;
所述配置中心基于分布式協(xié)同服務(wù),預(yù)置各業(yè)務(wù)的網(wǎng)頁請求解析規(guī)則映射表、持久化節(jié)點(diǎn)列表、MongoDB數(shù)據(jù)庫名、集合名、集合水平拆分?jǐn)?shù)、Redis消息隊(duì)列名;
所述請求路由轉(zhuǎn)發(fā)模塊依照配置中心預(yù)置的對應(yīng)業(yè)務(wù)負(fù)載均衡策略,完成對請求的轉(zhuǎn)發(fā):首先根據(jù)下載請求的業(yè)務(wù)類型biz,從配置中心獲取該biz預(yù)先定義的持久化節(jié)點(diǎn)列表、MongoDB數(shù)據(jù)庫名、集合名、集合水平拆分?jǐn)?shù)、Redis消息隊(duì)列名,再結(jié)合對唯一標(biāo)識符id求模取余策略,將請求持久化到MongoDB相應(yīng)的數(shù)據(jù)庫和集合,同時(shí)在Redis消息隊(duì)列記錄此條請求;
所述持久化模塊采用MongoDB的副本集架構(gòu)將請求按業(yè)務(wù)類型分庫分表;將請求寫入MongoDB數(shù)據(jù)庫,并用id字段覆蓋MongoDB默認(rèn)的_id索引,對ts字段建立TTL索引;
所述消息隊(duì)列模塊:在請求生成者端,將請求持久化到MongoDB同時(shí),將id、biz、ts三個(gè)字段轉(zhuǎn)json格式后,利用lpush操作壓入Redis消息隊(duì)列。在請求消費(fèi)者端,各下載服務(wù)器一直保持監(jiān)聽Redis消息隊(duì)列,利用rpop或其阻塞版操作brpop從隊(duì)列彈出請求,再結(jié)合id、biz和ts這三個(gè)字段組合成查詢過濾條件,然后調(diào)用MongoDB的原子操作findAndModify查詢對應(yīng)的MongoDB持久化節(jié)點(diǎn)的數(shù)據(jù)庫和集合,即可得到完整的請求內(nèi)容,根據(jù)該請求附帶的解析規(guī)則映射表,解析頁面獲取目標(biāo)數(shù)據(jù)記錄入庫。
進(jìn)一步地,該系統(tǒng)還包括服務(wù)監(jiān)控模塊,該模塊實(shí)時(shí)監(jiān)控網(wǎng)頁下載請求的生成速率;監(jiān)控服務(wù)節(jié)點(diǎn)的健康狀況:包括數(shù)據(jù)庫存儲容量、內(nèi)存使用率、慢查詢操作,以及內(nèi)存消息隊(duì)列的內(nèi)存占用、消息積壓程度等,當(dāng)遭遇節(jié)點(diǎn)故障或服務(wù)性能下滑超過設(shè)定閾值時(shí),及時(shí)以短信或郵件方式發(fā)送報(bào)警信息;監(jiān)控下載請求的處理速率,發(fā)現(xiàn)請求積壓嚴(yán)重或無法在計(jì)劃時(shí)間內(nèi)完成處理時(shí),及時(shí)增加處理節(jié)點(diǎn)動態(tài)擴(kuò)容。
本發(fā)明的有益效果是:本發(fā)明結(jié)合Redis內(nèi)存消息隊(duì)列和Mongodb副本集架構(gòu)實(shí)施的分布式網(wǎng)頁下載請求存儲方案,構(gòu)建成本低、簡單實(shí)用,具體表現(xiàn)在:1.可支撐每日千萬量級請求的高效可靠存儲;2.服務(wù)端自動執(zhí)行過期請求清理,避免了消息積壓,提升請求處理效率。3.具備快速透明的消息查詢跟蹤功能,這是按業(yè)界較常用的內(nèi)存消息隊(duì)列或消息中間件存儲方案,是難以做到的。
附圖說明
圖1是本發(fā)明實(shí)施例的網(wǎng)頁下載請求的主要流程示意圖;
圖2是請求路由轉(zhuǎn)發(fā)模塊執(zhí)行流程示意圖;
圖3是持久化模塊結(jié)構(gòu)示意圖;
圖4是下載服務(wù)器處理下載請求流程示意圖。
具體實(shí)施方式
下面結(jié)合附圖及具體實(shí)施方式對本發(fā)明作進(jìn)一步詳細(xì)說明。
為方便開展后續(xù)介紹,先闡述自定義的網(wǎng)頁下載請求各字段格式設(shè)計(jì):
1.字段名:id,數(shù)據(jù)類型為長整型,表示請求唯一標(biāo)識符。通常由全局ID生成服務(wù)分配;一方面,可以根據(jù)該字段按指定負(fù)載均衡策略將該請求轉(zhuǎn)發(fā)到指定存儲節(jié)點(diǎn)和消息隊(duì)列,另一方面,利用該字段覆蓋MongoDB默認(rèn)的_id索引,當(dāng)按該字段查詢和定位消息處理記錄狀態(tài)時(shí),效率極高。
2.字段名:biz,數(shù)據(jù)類型為字符串,記錄該消息由何種業(yè)務(wù)產(chǎn)生。對于請求的生產(chǎn)者,查詢注冊中心獲取該類業(yè)務(wù)的消息隊(duì)列各服務(wù)節(jié)點(diǎn),路由到指定的消息隊(duì)列;對于消費(fèi)者,根據(jù)該字段可以篩選和處理其感興趣的業(yè)務(wù)消息。
3.字段名:ts,數(shù)據(jù)類型為時(shí)間戳,記錄消息寫入隊(duì)列時(shí)刻。特別地,通過在該字段上建立TTL索引,可以將那些超過預(yù)設(shè)時(shí)間但未被處理的消息交給MongoDB服務(wù)器自動清理掉,避免消息大量堆積;另一方面,請求消費(fèi)者也可以根據(jù)該索引字段篩選或過濾消息。
4.字段名:data,數(shù)據(jù)類型為字節(jié)數(shù)組,真正的請求實(shí)體內(nèi)容(如:頁面Url,解析規(guī)則在配置中心對應(yīng)提取編號、http請求頭請求參數(shù)等),通常為了提高網(wǎng)絡(luò)傳輸速率和減少消息耗用的存儲空間,存儲請求時(shí),會采用某種序列化機(jī)制,將請求實(shí)體內(nèi)容轉(zhuǎn)化為字節(jié)數(shù)組。而在提取到請求后,將該字段的內(nèi)容反序列化為可視對象。
5.字段名:flag,數(shù)據(jù)類型為整型,記錄當(dāng)前消息處理狀態(tài)。通常持久化請求時(shí)狀態(tài)默認(rèn)賦值為0,當(dāng)請求被處理后,狀態(tài)同步更新為1。一般使用0和1兩種狀態(tài)即可。特定業(yè)亦可定義多種取值,協(xié)定消息處理的不同狀態(tài)。
基于MongoDB和Redis這兩種在互聯(lián)網(wǎng)公司廣泛應(yīng)用的開源NoSQL數(shù)據(jù)庫,構(gòu)建一套簡單靈活的網(wǎng)頁數(shù)據(jù)采集方法體系。這一方法體系主要包含六個(gè)模塊:全局ID生成器模塊、請求路由轉(zhuǎn)發(fā)模塊、配置中心、持久化模塊、消息隊(duì)列模塊、服務(wù)監(jiān)控模塊。完整的網(wǎng)頁數(shù)據(jù)采集流程示意圖如圖1所示:首先,指定需要抓取的網(wǎng)頁鏈接及相對應(yīng)的解析規(guī)則說明。為了便于后期追蹤和查詢指定請求處理記錄,通常會由全局ID生成服務(wù),分配該請求一個(gè)唯一ID,然后將其包裝為網(wǎng)頁下載請求。之后,請求路由轉(zhuǎn)發(fā)模塊會根據(jù)該請求的業(yè)務(wù)類型,依照指定負(fù)載均衡策略,將請求持久化到數(shù)據(jù)庫。同時(shí),存儲請求的部分關(guān)鍵字段到消息隊(duì)列。值得說明的是,為了避免請求的生成者與請求執(zhí)行者相耦合,并考慮到后期動態(tài)擴(kuò)展要求,這一步并未直接將網(wǎng)頁下載請求分配給指定的下載服務(wù)器。與此同時(shí),各下載服務(wù)器一直保持監(jiān)聽消息隊(duì)列和數(shù)據(jù)庫的變更,定時(shí)輪詢提取請求并下載網(wǎng)頁,最后根據(jù)該請求附帶的解析規(guī)則映射表,解析頁面獲取目標(biāo)數(shù)據(jù)記錄入庫。
各模塊具體介紹如下:
1.全局ID生成器模塊:此模塊用于給每個(gè)下載請求分配一個(gè)全局唯一ID,對應(yīng)著下載請求的id字段。常用的全局ID生成方案包括32位長度的UUID、MongoDB采用的ObjectId、Twitter發(fā)明的SnowFlake算法、Flickr基于MySQL主鍵自增ID。在高并發(fā)大數(shù)據(jù)量的情況下,建議使用SnowFlake方案,性能非常突出。
2.請求路由轉(zhuǎn)發(fā)模塊:這一模塊的主要功能類似關(guān)系型數(shù)據(jù)庫中間件代理,基于客戶端分庫分表,以便降低單節(jié)點(diǎn)、單庫、單表壓力,提升存儲和查詢性能。具體應(yīng)用時(shí),依照配置中心預(yù)置的對應(yīng)業(yè)務(wù)負(fù)載均衡策略(一致性哈希、簡單求模取余等),完成對請求轉(zhuǎn)發(fā)。一次簡單的請求路由轉(zhuǎn)發(fā)流程如圖2所示:首先根據(jù)下載請求biz字段定義的類型,從配置中心獲取該biz預(yù)先定義的持久化節(jié)點(diǎn)列表、MongoDB數(shù)據(jù)庫名、集合名、集合水平拆分?jǐn)?shù)、Redis消息隊(duì)列名,再結(jié)合對id字段求模取余策略,將請求持久化到MongoDB相應(yīng)的數(shù)據(jù)庫和集合,同時(shí)在Redis消息隊(duì)列記錄此條請求。
3.配置中心:基于Redis、etcd或Zookeeper等分布式服務(wù),存儲各業(yè)務(wù)類型的網(wǎng)頁請求解析規(guī)則映射表,統(tǒng)一注冊和配置相關(guān)業(yè)務(wù)的服務(wù)節(jié)點(diǎn)、持久化節(jié)點(diǎn)列表、消息隊(duì)列列表。支持動態(tài)修改配置而不用重啟已部署線上應(yīng)用程序。
4.持久化模塊:基于MongoDB,采用其副本集(Replica Sets)架構(gòu),并按業(yè)務(wù)類型分庫、拆分集合,提供數(shù)據(jù)存儲的整體高可用性,如圖3所示。使用該技術(shù)能夠?qū)?shù)據(jù)副本保存到多臺服務(wù)器,當(dāng)一臺或多臺服務(wù)器故障時(shí),系統(tǒng)會自動切換到副本集中的其他服務(wù)器,保證了數(shù)據(jù)安全性和服務(wù)的容錯性。實(shí)際持久化請求時(shí),會用請求id字段覆蓋MongoDB默認(rèn)的_id索引,并對ts字段建立TTL(time-to-live)索引。TTL索引支持對每個(gè)文檔預(yù)先設(shè)置超時(shí)時(shí)間,這樣做的好處是:當(dāng)文檔達(dá)到設(shè)置的老化程度后,MongoDB服務(wù)器會自動將其刪除。默認(rèn)情況下,MongoDB服務(wù)器每隔一分鐘開展一次TTL索清理,應(yīng)用程序無需提供額外編碼就能避免了消息堆積,極大地方便了開發(fā)人員。
5.消息隊(duì)列模塊:利用Redis原生提供的list數(shù)據(jù)結(jié)構(gòu)及l(fā)push和rpop、brpop等原子操作構(gòu)建而成。由于是基于內(nèi)存存儲,為降低內(nèi)存占用率,并未將請求全部字段寫入。實(shí)際使用中:請求生成者端,將完整的請求持久化到MongoDB同時(shí),僅將id、biz、ts三個(gè)字段轉(zhuǎn)json格式后,利用lpush操作壓入隊(duì)列;在請求消費(fèi)者端,先利用rpop或其阻塞版操作brpop從隊(duì)列彈出請求,再結(jié)合id、biz和ts這三個(gè)字段組合成查詢過濾條件,然后調(diào)用MongoDB的原子操作findAndModify查詢對應(yīng)的MongoDB存儲節(jié)點(diǎn)的數(shù)據(jù)庫和集合,即可得到完整的請求內(nèi)容,流程示意圖如圖4所示。由于Redis獲取的數(shù)據(jù)直接源于內(nèi)存,而查詢MongoDB又能利用上其主鍵id索引,故這兩步操作即便以事務(wù)方式執(zhí)行,亦可獲得極高的執(zhí)行效率。
6.服務(wù)監(jiān)控模塊:主要監(jiān)控三個(gè)方面,1.以不同的時(shí)間精度(1秒、5秒、1分鐘等)監(jiān)控網(wǎng)頁下載請求的生成速率,當(dāng)請求生成過快時(shí)以便能及時(shí)調(diào)控;2.各服務(wù)節(jié)點(diǎn)監(jiān)控狀態(tài)匯報(bào),包括數(shù)據(jù)庫存儲容量、內(nèi)存使用率、慢查詢操作,以及內(nèi)存消息隊(duì)列的內(nèi)存占用、消息積壓程度等,當(dāng)遭遇節(jié)點(diǎn)故障或服務(wù)性能下滑超過設(shè)定閾值時(shí),能及時(shí)以短信或郵件方式發(fā)送報(bào)警信息;3.以不同的時(shí)間精度(1秒、5秒、1分鐘等)監(jiān)控下載請求的處理速率,一旦發(fā)現(xiàn)請求積壓嚴(yán)重或無法在計(jì)劃時(shí)間內(nèi)完成處理,則及時(shí)增加處理節(jié)點(diǎn)動態(tài)擴(kuò)容。