青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

loop_in_codes

低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

磁力搜索第二版-dhtcrawler2

上篇

下載使用

目前為止dhtcrawler2相對dhtcrawler而言,數據庫部分調整很大,DHT部分基本沿用之前。但單純作為一個爬資源的程序而言,DHT部分可以進行大幅削減,這個以后再說。這個版本更快、更穩定。為了方便,我將編譯好的erlang二進制文件作為git的主分支,我還添加了一些Windows下的批處理腳本,總之基本上下載源碼以后即可運行。

項目地址:https://github.com/kevinlynx/dhtcrawler2

使用方法

  • 下載erlang,我測試的是R16B版本,確保erl等程序被加入Path環境變量
  • 下載mongodb,解壓即用:

      mongod --dbpath xxx --setParameter textSearchEnabled=true
    
  • 下載dhtcrawler2

      git clone https://github.com/kevinlynx/dhtcrawler2.git
    
  • 運行win_start_crawler.bat

  • 運行win_start_hash.bat
  • 運行win_start_http.bat
  • 打開localhost:8000查看stats

爬蟲每次運行都會保存DHT節點狀態,早期運行的時候收集速度會不夠。dhtcrawler2將程序分為3部分:

  • crawler,即DHT爬蟲部分,僅負責收集hash
  • hash,準確來講叫hash reader,處理爬蟲收集的hash,處理過程主要涉及到下載種子文件
  • http,使用hash處理出來的數據庫,以作為Web端接口

我沒有服務器,但程序有被部署在別人的服務器上:bt.cmhttp://222.175.114.126:8000/

其他工具

為了提高資源索引速度,我陸續寫了一些工具,包括:

  • import_tors,用于導入本地種子文件到數據庫
  • tor_cache,用于下載種子到本地,僅僅提供下載的功能,hash_reader在需要種子文件時,可以先從本地取
  • cache_indexer,目前hash_reader取種子都是從torrage.com之類的種子緩存站點取,這些站點提供了種子列表,cache_indexer將這些列表導入數據庫,hash_reader在請求種子文件前可以通過該數據庫檢查torrage.com上有無此種子,從而減少多余的http請求

這些工具的代碼都被放在dhtcrawler2中,可以查看對應的啟動腳本來查看具體如何啟動。

OS/Database

根據實際的測試效果來看,當收集的資源量過百萬時(目前bt.cm錄入近160萬資源),4G內存的Windows平臺,mongodb很容易就會掛掉。掛掉的原因全是1455,頁面文件太小。有人建議不要在Windows下使用mongodb,Linux下我自己沒做過測試。

mongodb可以部署為集群形式(replica-set),當初我想把http部分的查詢放在一個只讀的mongodb實例上,但因為建立集群時,要同步已有的10G數據庫,而每次同步都以mongodb掛掉結束,遂放棄。在目前bt.cm的配置中,數據庫torrent的鎖比例(db lock)很容易上50%,這也讓http在搜索時,經常出現搜索超時的情況。

技術信息

dhtcrawler最早的版本有很多問題,修復過的最大的一個問題是關于erlang定時器的,在DHT實現中,需要對每個節點每個peer做超時處理,在erlang中的做法直接是針對每個節點注冊了一個定時器。這不是問題,問題在于定時器資源就像沒有GC的內存資源一樣,是會由于程序員的代碼問題而出現資源泄漏。所以,dhtcrawler第一個版本在節點數配置在100以上的情況下,用不了多久就會內存耗盡,最終導致erlang虛擬機core dump。

除了這個問題以外,dhtcrawler的資源收錄速度也不是很快。這當然跟數據庫和獲取種子的速度有直接關系。尤其是獲取種子,使用的是一些提供info-hash到種子映射的網站,通過HTTP請求來下載種子文件。我以為通過BT協議直接下載種子會快些,并且實時性也要高很多,因為這個種子可能未被這些緩存網站收錄,但卻可以直接向對方請求得到。為此,我還特地翻閱了相關協議,并且用erlang實現了(以后的文章我會講到具體實現這個協議)。

后來我懷疑get_peers的數量會不會比announce_peer多,但是理論上一般的客戶端在get_peers之后都是announce_peer,但是如果get_peers查詢的peers恰好不在線呢?這意味著很多資源雖然已經存在,只不過你恰好暫時請求不到。實際測試時,發現get_peers基本是announce_peer數量的10倍。

將hash的獲取方式做了調整后,dhtcrawler在幾分鐘以內以幾乎每秒上百個新增種子的速度工作。然后,程序掛掉。

從dhtcrawler到今天為止的dhtcrawler2,中間間隔了剛好1個月。我的所有業余時間全部撲在這個項目上,面臨的問題一直都是程序的內存泄漏、資源收錄的速度不夠快,到后來又變為數據庫壓力過大。每一天我都以為我將會完成一個穩定版本,然后終于可以去干點別的事情,但總是干不完,目前完沒完都還在觀察。我始終明白在做優化前需要進行詳盡的數據收集和分析,從而真正地優化到正確的點上,但也總是憑直覺和少量數據分析就開始嘗試。

這里談談遇到的一些問題。

erlang call timeout

最開始遇到erlang中gen_server:call出現timeout錯誤時,我還一直以為是進程死鎖了。相關代碼讀來讀去,實在覺得不可能發生死鎖。后來發現,當erlang虛擬機壓力上去后,例如內存太大,但沒大到耗盡系統所有內存(耗進所有內存基本就core dump了),進程間的調用就會出現timeout。

當然,內存占用過大可能只是表象。其進程過多,進程消息隊列太長,也許才是導致出現timeout的根本原因。消息隊列過長,也可能是由于發生了消息泄漏的緣故。消息泄漏我指的是這樣一種情況,進程自己給自己發消息(當然是cast或info),這個消息被處理時又會發送相同的消息,正常情況下,gen_server處理了一個該消息,就會從消息隊列里移除它,然后再發送相同的消息,這不會出問題。但是當程序邏輯出問題,每次處理該消息時,都會發生多余一個的同類消息,那消息隊列自然就會一直增長。

保持進程邏輯簡單,以避免這種邏輯錯誤。

erlang gb_trees

我在不少的地方使用了gb_trees,dht_crawler里就可能出現gb_trees:get(xxx, nil)這種錯誤。乍一看,我以為我真的傳入了一個nil值進去。然后我苦看代碼,以為在某個地方我會把這個gb_trees對象改成了nil。但事情不是這樣的,gb_tress使用一個tuple作為tree的節點,當某個節點沒有子節點時,就會以nil表示。

gb_trees:get(xxx, nil)類似的錯誤,實際指的是xxx沒有在這個gb_trees中找到。

erlang httpc

dht_crawler通過http協議從torrage.com之類的緩存網站下載種子。最開始我為了盡量少依賴第三方庫,使用的是erlang自帶的httpc。后來發現程序有內存泄漏,google發現erlang自帶的httpc早為人詬病,當然也有大神說在某個版本之后這個httpc已經很不錯。為了省事,我直接換了ibrowse,替換之后正常很多。但是由于沒有具體分析測試過,加之時間有點遠了,我也記不太清細節。因為早期的http請求部分,沒有做數量限制,也可能是由于我的使用導致的問題。

某個版本后,我才將http部分嚴格地與hash處理部分區分開來。相較數據庫操作而言,http請求部分慢了若干數量級。在hash_reader中將這兩塊分開,嚴格限制了提交給httpc的請求數,以獲得穩定性。

對于一個復雜的網絡系統而言,分清哪些是耗時的哪些是不大耗時的,才可能獲得性能的提升。對于hash_reader而言,處理一個hash的速度,雖然很大程度取決于數據庫,但相較http請求,已經快很多。它在處理這些hash時,會將數據庫已收錄的資源和待下載的資源分離開,以盡快的速度處理已存在的,而將待下載的處理速度交給httpc的響應速度。

erlang httpc ssl

ibrowse處理https請求時,默認和erlang自帶的httpc使用相同的SSL實現。這經常導致出現tls_connection進程掛掉的錯誤,具體原因不明。

erlang調試

首先合理的日志是任何系統調試的必備。

我面臨的大部分問題都是內存泄漏相關,所以依賴的erlang工具也是和內存相關的:

  • 使用etop,可以檢查內存占用多的進程、消息隊列大的進程、CPU消耗多的進程等等:

      spawn(fun() -> etop:start([{output, text}, {interval, 10}, {lines, 20}, {sort, msg_q }]) end).
    
  • 使用erlang:system_info(allocated_areas).檢查內存使用情況,其中會輸出系統timer數量

  • 使用erlang:process_info查看某個具體的進程,這個甚至會輸出消息隊列里的消息

hash_writer/crawler

crawler本身僅收集hash,然后寫入數據庫,所以可以稱crawler為hash_writer。這些hash里存在大量的重復。hash_reader從數據庫里取出這些hash然后做處理。處理過程會首先判定該hash對應的資源是否被收錄,沒有收錄就先通過http獲取種子。

在某個版本之后,crawler會簡單地預先處理這些hash。它緩存一定數量的hash,接收到新hash時,就合并到hash緩存里,以保證緩存里沒有重復的hash。這個重復率經過實際數據分析,大概是50%左右,即收到的100個請求里,有50個是重復的。這樣的優化,不僅會降低hash數據庫的壓力,hash_reader處理的hash數量少了,也會對torrent數據庫有很大提升。

當然進一步的方案可以將crawler和hash_reader之間交互的這些hash直接放在內存中處理,省去中間數據庫。但是由于mongodb大量使用虛擬內存的緣故(內存映射文件),經常導致服務器內存不夠(4G),內存也就成了珍稀資源。當然這個方案還有個弊端是難以權衡hash緩存的管理。crawler收到hash是一個不穩定的過程,在某些時間點這些hash可能爆多,而hash_reader處理hash的速度也會不太穩定,受限于收到的hash類別(是新增資源還是已存在資源)、種子請求速度、是否有效等。

當然,也可以限制緩存大小,以及對hash_reader/crawler處理速度建立關系來解決這些問題。但另一方面,這里的優化是否對目前的系統有提升,是否是目前系統面臨的最大問題,卻是需要考究的事情。

cache indexer

dht_crawler是從torrage.com等網站獲取種子文件,這些網站看起來都是使用了相同的接口,其都有一個sync目錄,里面存放了每天每個月索引的種子hash,例如 http://torrage.com/sync/。這個網站上是否有某個hash對應的種子,就可以從這些索引中檢查。

hash_reader在處理新資源時,請求種子的過程中發現大部分在這些服務器上都沒有找到,也就是發起的很多http請求都是404回應,這不但降低了系統的處理能力、帶寬,也降低了索引速度。所以我寫了一個工具,先手工將sync目錄下的所有文件下載到本地,然后通過這個工具 (cache indexer) 將這些索引文件里的hash全部導入數據庫。在以后的運行過程中,該工具僅下載當天的索引文件,以更新數據庫。 hash_reader 根據配置,會首先檢查某個hash是否存在該數據庫中,存在的hash才可能在torrage.com上下載得到。

種子緩存

hash_reader可以通過配置,將下載得到的種子保存在本地文件系統或數據庫中。這可以建立自己的種子緩存,但保存在數據庫中會對數據庫造成壓力,尤其在當前測試服務器硬件環境下;而保存為本地文件,又特別占用硬盤空間。

基于BT協議的種子下載

通過http從種子緩存里取種子文件,可能會沒有直接從P2P網絡里取更實時。目前還沒來得及查看這些種子緩存網站的實現原理。但是通過BT協議獲取種子會有點麻煩,因為dht_crawler是根據get_peer請求索引資源的,所以如果要通過BT協議取種子,那么這里還得去DHT網絡里查詢該種子,這個查詢過程可能會較長,相比之下會沒有http下載快。而如果通過announce_peer來索引新資源的話,其索引速度會大大降低,因為announce_peer請求比get_peer請求少很多,幾乎10倍。

所以,這里的方案可能會結合兩者,新開一個服務,建立自己的種子緩存。

中文分詞

mongodb的全文索引是不支持中文的。我在之前提到,為了支持搜索中文,我將字符串拆成了若干子串。這樣的后果就是字符串索引會稍稍偏大,而且目前這一塊的代碼還特別簡單,會將很多非文字字符也算在內。后來我加了個中文分詞庫,使用的是rmmseg-cpp。我將其C++部分抽離出來編譯成erlang nif,這可以在我的github上找到。

但是這個庫拆分中文句子依賴于詞庫,而這個詞庫不太新,dhtcrawler爬到的大部分資源類型你們也懂,那些詞匯拆出來的比率不太高,這會導致搜索出來的結果沒你想的那么直白。當然更新詞庫應該是可以解決這個問題的,目前還沒有時間顧這一塊。

總結

一個老外對我說過,”i have 2 children to feed, so i will not do this only for fun”。

你的大部分編程知識來源于網絡,所以稍稍回饋一下不會讓你丟了飯碗。

我很窮,如果你能讓我收獲金錢和編程成就,還不會嫌我穿得太邋遢,that’s really kind of you。

posted on 2013-07-20 16:37 Kevin Lynx 閱讀(5748) 評論(1)  編輯 收藏 引用 所屬分類: networkerlang

評論

# re: 磁力搜索第二版-dhtcrawler2 2014-04-25 12:34 vvke

在WIN上面,一搜索就跪。。。500錯誤。。。  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲人成在线观看网站高清| 欧美国产一区二区在线观看 | 欧美一级理论片| 亚洲精品一区二区三区99| 亚洲精品一区二区三| 亚洲天天影视| 午夜欧美大尺度福利影院在线看| 午夜精品亚洲| 暖暖成人免费视频| 亚洲黄色天堂| 一区二区三区 在线观看视| 亚洲天堂av图片| 亚洲午夜一区| 久久久久久久激情视频| 久久久久久久精| 亚洲国产精品va| 一片黄亚洲嫩模| 久久精品成人| 欧美日韩国产美| 国产一区二区精品在线观看| 在线成人免费视频| 亚洲少妇最新在线视频| 久久国产日韩| 亚洲狠狠丁香婷婷综合久久久| 亚洲性感激情| 欧美电影免费| 国产一区二区三区高清| 亚洲免费高清| 久久久亚洲国产美女国产盗摄| 91久久在线观看| 欧美一区二区网站| 欧美日一区二区三区在线观看国产免 | 免费一级欧美片在线播放| 亚洲日韩欧美视频| 久久精品视频播放| 国产精品视频网| 亚洲视频一二| 亚洲日本欧美| 欧美成人精品在线观看| 国产综合激情| 欧美一区二区成人6969| 99re66热这里只有精品4| 老色鬼久久亚洲一区二区| 国产亚洲成精品久久| 亚洲一区免费| av成人激情| 欧美日韩国产区| 亚洲精品中文字幕女同| 久久综合亚州| 久久久久久久精| 国产自产精品| 久久久久久久一区二区三区| 亚洲欧美bt| 国产精品久久久久久五月尺| 一区二区精品| 一区二区三区|亚洲午夜| 欧美美女日韩| 日韩一级精品视频在线观看| 欧美成年人视频网站| 久久中文精品| 亚洲精品一区久久久久久| 欧美激情片在线观看| 欧美jizz19hd性欧美| 亚洲国产美国国产综合一区二区| 久热成人在线视频| 玖玖综合伊人| 亚洲日本在线观看| 亚洲精品欧美专区| 欧美日韩另类国产亚洲欧美一级| 亚洲剧情一区二区| 亚洲在线成人精品| 99精品国产高清一区二区| 欧美精品久久久久a| 一本久久综合| 亚洲欧美激情四射在线日 | 国产精自产拍久久久久久| 亚洲欧美春色| 午夜精品一区二区在线观看 | 亚洲欧洲av一区二区| 在线视频亚洲欧美| 国产视频亚洲精品| 久久一区中文字幕| 老司机成人在线视频| 亚洲人精品午夜在线观看| 99re亚洲国产精品| 国产亚洲一区精品| 亚洲电影第1页| 欧美三级黄美女| 久久国产精品色婷婷| 久久在线免费观看| 亚洲五月婷婷| 久久精品二区亚洲w码| 亚洲精品资源美女情侣酒店| 在线一区二区三区四区| 国产丝袜一区二区三区| 亚洲激情视频在线观看| 国产伦精品一区二区三区在线观看 | 欧美一区二区福利在线| 香蕉尹人综合在线观看| 亚洲欧洲精品成人久久奇米网 | 久久精品国产亚洲一区二区三区| 久久久国产一区二区三区| 99视频热这里只有精品免费| 午夜精品久久久久久久99樱桃| 一区视频在线| 亚洲一区二区三区在线视频| 亚洲国产日韩一区二区| 亚洲欧美日韩在线一区| 亚洲精品午夜精品| 午夜免费日韩视频| 亚洲免费婷婷| 欧美日韩国产成人在线| 欧美成人激情在线| 国产精品视频一二三| 亚洲欧洲偷拍精品| 亚洲第一视频| 久久精品一区中文字幕| 篠田优中文在线播放第一区| 欧美日本在线播放| 欧美黄色aaaa| 黄色亚洲大片免费在线观看| 午夜精品美女自拍福到在线| 欧美成人一区二区三区在线观看 | 亚洲综合三区| 在线一区二区视频| 另类成人小视频在线| 久久精品一区二区三区四区 | 亚洲丰满在线| 亚洲高清在线精品| 久久久综合网站| 免费观看成人鲁鲁鲁鲁鲁视频| 国产精品资源在线观看| 一区二区欧美国产| 亚洲视频综合在线| 国产精品swag| 亚洲欧美视频一区| 欧美在线视频全部完| 国产精品亚洲аv天堂网| 一二三四社区欧美黄| 亚洲婷婷综合久久一本伊一区| 欧美精品尤物在线| 在线视频你懂得一区| 香蕉成人久久| 国产欧美日本在线| 久久免费视频观看| 亚洲电影欧美电影有声小说| 99精品欧美一区二区三区综合在线 | 国产偷自视频区视频一区二区| 亚洲伊人观看| 欧美综合激情网| 伊人久久噜噜噜躁狠狠躁| 久久亚洲影院| 亚洲精品一区二区在线观看| 亚洲综合色婷婷| 国产欧美一区二区视频| 久久九九免费视频| 亚洲国产日韩欧美| 亚洲女性裸体视频| 黄色工厂这里只有精品| 欧美顶级艳妇交换群宴| 99视频一区二区| 久久久人成影片一区二区三区| 亚洲国产精品传媒在线观看 | 亚洲欧美中文日韩v在线观看| 久久精品国产欧美亚洲人人爽| 极品少妇一区二区| 欧美—级高清免费播放| 亚洲一区二区免费在线| 亚洲欧美日韩精品久久亚洲区| 欧美高清在线视频观看不卡| 亚洲一区二区三区视频| 久久久综合网站| 日韩午夜电影av| 国产日韩在线亚洲字幕中文| 欧美成人一区二区三区片免费| 亚洲一区二区少妇| 欧美激情欧美狂野欧美精品| 先锋影音一区二区三区| 亚洲国产老妈| 欧美在线视频一区二区| 欧美成人激情视频免费观看| 亚洲免费一在线| 亚洲国产专区校园欧美| 国产精品少妇自拍| 欧美激情综合色综合啪啪| 亚洲综合色自拍一区| 亚洲国产成人av好男人在线观看| 午夜精品影院| 亚洲精品一区二区三区四区高清 | 亚洲午夜在线| 亚洲国产精彩中文乱码av在线播放| 亚洲一区二区综合| 欧美一区二区三区在线观看| 欧美日韩一二三四五区| 欧美一区二区观看视频| 99精品视频一区| 亚洲国内精品| 欧美国产欧美综合 | 欧美精品成人| 久久亚洲不卡|