FROM:http://architects.dzone.com/articles/solr-hadoop-big-data-love
許多人使用Hadoop的開源項目來處理大數據的大數據集,因為它是一個偉大的解決方案可擴展,可靠的數據處理工作流程。Hadoop是目前最流行 的大數據處理系統,與企業使用數千台服務器上的數據存儲和處理PB級的大規模集群。
Nutch的開源網絡爬蟲項目於2006年出現以來,Hadoop已種植在各方面都可以想象-用戶,開發相關的項目(又名“Hadoop生態系統”)。
在大致相同的時間開始,Solr的開源項目已經成為地球上最廣泛使用的搜索解決方案。Solr的包裝API級別的索引和搜索功能的Lucene的一個RESTful API,GUI,和很多有用的管理和數據集成功能。
結合這兩個開源項目的有趣的事情是,你可以使用Hadoop處理數據,然后為它在Solr。而且我們不是在談論剛剛自由文本搜索Solr的,可以作為一個 key-value存儲(即NoSQL數據庫),通過其支持范圍查詢。
即使一台服務器上,可以很容易地處理Solr的數以百萬計的記錄(“文件”在Lucene的行話)。更妙的是,Solr的現在支持通過新的,尖端的的SolrCloud功能的分片和復制。
背景
我大約五年前開始使用Hadoop和Solr的Krugle的代碼搜索啟動,我在2005年共同創立的,作為關鍵件。
那時候,Hadoop的仍然是我們用來提取信息的開源項目Nutch的網絡爬蟲的一部分。和Solr是新鮮出烤箱,剛剛被發布為開放源代碼由CNET。
在Bixo Labs 我們使用的Hadoop,Solr的,層疊, 亨利馬烏,和許多其他開源技術來創建自定義的數據處理工作流程。該網站是一個常見的來源,我們的輸入數據,這是我們抓取使用的Bixo開源項目。
存在的問題
在網頁抓取,抓取的狀態包含的東西通常被稱為“爬行DB”。對於廣泛的抓取,這是數十億條記錄的一些作品,因為你需要一個條目為每個已知的URL。每一個“紀錄”的網址為關鍵,並包含重要的狀態信息,如時間和結果的最后請求。
如Nutch和Bixo的基於Hadoop的爬蟲抓取DB通常保持在一個平面文件,其中每個文件是一個Hadoop SequenceFile“。這些都只是填充數組的鍵/值對象序列化。
有時候我們需要去捅這個數據,這里就是簡單的平面文件結構產生了一個問題。有沒有簡單的方式運行,對數據的查詢,但我們不能將其存儲在傳統的數據庫,因為數十億條記錄+ RDBMS ==痛苦和苦難。
這里是可伸縮的NoSQL解決方案閃耀。例如,目前Nutch的項目是重新理抓取DB層,讓堵在HBase中。其他選項包括卡桑德拉的人員,MongoDB,CouchDB的,等
但較小的數據集上進行簡單的分析和探索,基於Solr的解決方案的工作原理,並更容易配置。另外,你會得到有用的和令人驚訝的有趣的功能,如面,空間查詢,范圍查詢,自由格式的文本搜索,和很多其他的好東西免費。
構建
那么究竟是什么將這樣一個Hadoop + Solr的系統是什么樣子?
正如前面提到的,在這個例子中,我們輸入的數據來自一個網絡爬蟲Bixo的CrawlDB,一個條目為每個已知的URL。但輸入的數據可以很容易的日志文件,或從傳統的RDBMS記錄,或另一個數據處理流程的輸出。
關鍵的一點是,我們要輸入數據,拿一把(可選)也得用它成一個有用的格式,然后生成一個Lucene索引,我們通過訪問Solr的。
Hadoop的
對於外行的Hadoop實現了一個分布式文件系統(又名“HDFS)和執行層支持的map-reduce編程模型。
通常情況下,數據加載和轉化在地圖階段,然后結合/保存在reduce階段。在我們的例子中,map階段讀在Hadoop壓縮SequenceFiles的包含我們的網站抓取的狀態,並降低相位寫出來的Lucene索引。
這篇文章的重點是如何寫的Hadoop的map-reduce工作,但我想告訴你的代碼,實現工作的膽量。請注意,這不是典型的Hadoop鍵/值操作的代碼,這是痛苦的編寫,調試和維護。相反,我們使用的級聯,這是一個開源的工作流規划和數據處理的API,創建Hadoop作業較短,比較有代表性的代碼。
下面的代碼片段讀取從HDFS的反序列化和管道的那些記錄,並將它們存儲使用的LuceneScheme,這反過來又作為Lucene的索引文件記錄保存到一個接收器(輸出)。
Tap source = new Hfs(new SequenceFile(CRAWLDB_FIELDS), inputDir); Pipe urlPipe = new Pipe("crawldb urls"); urlPipe = new Each(urlPipe, new ExtractDomain()); Tap sink = new Hfs(new LuceneScheme(SOLR_FIELDS, STORE_SETTINGS, INDEX_SETTINGS, StandardAnalyzer.class, MAX_FIELD_LENGTH), outputDir, true); FlowConnector fc = new FlowConnector(); fc.connect(source, sink, urlPipe).complete();
我們定義CRAWLDB_FIELDS和SOLR_FIELDS,輸入和輸出數據元素的集合,使用的名稱,如“URL”和“狀態”。我們利用Lucene的計划,我們已經創建級聯,它可以讓我們輕松地從層疊的世界觀(記錄字段)映射到Lucene的索引(文件字段)。我們沒有直接支持級聯計划Solr的(那不是很方便嗎?),但我們可以做的,因為我們現在可以做簡單的分析這個例子。
我們索引的所有字段,這樣我們就可以對他們進行查詢。只有狀態消息包含正常的英文文本,讓我們來分析(即,突破到使用空格和其他標記分隔符的文本)是唯一一個。此外,拉ExtractDomain操作域的URL字段,建立一個新的Solr場只包含域。這將使我們能夠做查詢的域名的URL,以及完整的URL。
我們也可以選擇應用自定義分析儀的URL,它分解成幾個部分(即,協議,域名,端口,路徑,查詢參數),本來是可以單獨查詢。
運行在Hadoop作業
為了簡化和支付你去,這是很難被擊敗亞馬遜的EC2彈性MapReduce提供運行Hadoop作業。您可以輕松地旋轉起來的50台服務器的集群,運行作業,保存結果,並將其關閉 - 所有,而無需購買硬件或IT支持支付。
創建和配置Hadoop集群的方法有很多,對於我們來說,我們很熟悉(修改)EC2的Hadoop的腳本,你可以找到在Bixo分布。一步一步的指令可在http://openbixo.org/documentation/running-bixo-in-ec2/
這篇文章的代碼是通過GitHub上http://github.com/bixolabs/hadoop2solr中。該網頁上顯示的README包含一步一步的指示,建設和運行工作。
作業完成后,我們將復制指數的Hadoop分布式文件系統(HDFS),到Hadoop集群的主服務器,然后殺死我們使用一個從屬。現在已經准備好我們的Solr服務器被配置為Hadoop的主。
Solr的
Solr的方面的東西,我們需要創建一個模式匹配索引,我們正在產生。我們的schema.xml文件的關鍵部分是我們定義的字段。
1 <fields> 2 3 <field name="url" type="string" indexed="true" stored="true" /> 4 5 <field name="domain" type="string" indexed="true" stored="false" /> 6 7 <field name="status" type="string" indexed="true" stored="true" /> 8 9 <field name="statustime" type="string" indexed="true" stored="true" /> 10 11 <field name="statusmsg" type="simpletext" indexed="true" stored="true" /> 12 13 </fields>
一旦我們有了這個定義,所有剩下的就是建立一個服務器,我們就可以使用。為了簡單起見,我們將使用單一的EC2實例在亞馬遜的雲(m1.large),我們使用我們的主人為Hadoop作業,運行簡單的Solr搜索服務器依賴於提供嵌入式Jetty web應用容器。
類似Hadoop的工作,一步一步的指示的hadoop2solr項目在GitHub上的自述文件中。但簡而言之,我們將復制並解壓縮的Solr 1.4.1設置EC2的服務器上,做我們的自定義Solr的配置相同,創建一個符號鏈接的索引,然后開始運行:
給它一個嘗試
現在到了有趣的部分。因為我們開辟了默認碼頭Solr的(8983)這EC2實例上使用的端口,我們可以直接訪問Solr的方便的管理控制台指向我們瀏覽器在http:// <ec2-public-name>的,8983/solr/admin
% cd solr
% java -Dsolr.solr.home=../solr-conf -Dsolr.data.dir=../solr-data -jar start.jar
從這里我們可以運行Solr的查詢:
我們也可以使用curl談通過HTTP請求到服務器:
curl http://<ec2-public-name>:8983/solr/select/?q=-status%3AFETCHED+and+-status%3AUNFETCHED
默認情況下是XML響應。下面是一個例子上述要求,在那里我們發現了2,546場比賽,94ms的響應。
現在,這里就是我的發現驚人的。索引82萬個文檔,相當懦弱箱(EC2 m1.large = 2個虛擬內核)上運行,獲取典型響應時間為一個簡單的查詢,如“狀態:”只有400毫秒,要找到9M文件。即使是一個復雜的查詢(如狀態不牽強,不未獲得)只需要6秒。
縮放
很顯然,我們可以使用比較強大的盒子。如果我們切換到的東西像m1.xlarge(15GB內存,4個虛擬內核),那么我們很可能會向上200M“記錄”在我們的Solr索引處理,仍然可以得到合理的響應時間。
如果我們想擴展到超過一個盒子,也有一些解決方案。即使開箱Solr的支持分片,你的HTTP請求可以指定多個服務器並行使用。
最近,Solr的主干有支持SolrCloud。這使用的ZooKeeper 開源項目簡化協調多個Solr服務器。
最后,凱塔 開源項目支持Lucene的分布式搜索,許多分布式搜索尚未被添加到SolrCloud生產質量所需的功能。
總結
結合了Hadoop和Solr可以很容易地緊縮大量的數據,然后迅速提供一個快速,靈活的搜索和查詢API的結果通過。由於Solr的支持查詢的風格的請求,這是適合作為在許多情況下,一個NoSQL替代傳統的數據庫,特別是當數據的大小超過一個典型的RDBMS什么是合理。
Solr的,你應該知道的,特別是有一定的局限性:
·更新索引最好作為批處理作業。個人可以更新記錄,但每個提交(更新索引)生成一個新的Lucene段,這將影響性能。
·當前支持復制,故障轉移和其他屬性,你會希望在生產級的解決方案尚未有在SolrCloud。如果這對你很重要,而不是考慮凱塔。
·許多SQL查詢不能很容易地映射到Solr的查詢。
這篇文章的代碼是通過GitHub上http://github.com/bixolabs/hadoop2solr中。該網頁上顯示的README包含額外的技術細節。