第一章 Solr 簡單介紹算法
本章速覽:數據庫
·搜索引擎處理的數據特性設計模式
·常見搜索引擎用例安全
·Solr核心模塊介紹性能優化
·選擇Solr的理由網絡
·功能概述數據結構
伴隨着社交媒體、雲計算、移動互聯網和大數據等技術的快速發展。咱們正迎來一個使人激動的計算時代。軟件架構師們開始面對的主要挑戰之中的一個,即是怎樣處理全球巨大的用戶基數所產生及使用的海量數據。此外,用戶們開始期待在線軟件應用永遠都是穩定可用的。並且能夠一直保持響應,這相應用就提出了更高的可擴展性和穩定性需求。爲了知足這些需求,一些專用的非關係型數據存儲及處理技術,統稱爲NoSQL(Not Only SQL)技術。開始得到愈來愈多的青睞。這些系統並不強制要求將所有的數據都存儲在之前成爲其實標準的關係型數據模型其中。而是共用了一個通用的設計模式。在數據存儲處理引擎和特定的數據類型之間進行匹配。換句話說,NoSQL技術爲處理特定數據類型的特定類別問題作了性能優化。由於對可擴展性的需求和性能的需求不斷添加,致使各類NoSQL技術和傳統關係型數據庫開始混合使用。這樣的跨界架構變得愈來愈流行。架構
過去那種一種數據處理方案就能吃遍天下的時代已經一去不復返了。工具
本書主要討論一種特殊的NoSQL技術。即Apache Solr。和她的其它非關係型兄弟們同樣,Solr也爲一類特定問題的處理作了優化。詳細來講,Solr 是一個可擴展的,可高速部署的,對搜索海量文本中心的數據和對返回結果作相關性排序方面作了優化的企業級搜索引擎。post
這句話讀上去有點拗口。只是不要緊。咱們把這個定義中的亮點分解出來看:
·可擴展性:Solr可以把創建索引和查詢處理的運算分佈到一個集羣內的多臺server上。
·高速部署:Solr是開源軟件,安裝和配置都很是方便,可以依據安裝包內的Sample配置直接上手。
·優化的搜索功能:Solr搜索夠快。對於複雜的搜索查詢,Solr可以作到亞秒級的處理。一般幾十毫秒就能處理完一次複雜查詢
·海量文本:Solr是針對百萬級以上的海量文本處理而設計的,可以很是好地處理海量數據。
·文本中心的數據:Solr爲搜索包括天然語言的文本內容作了優化,比方電子郵件。網頁,簡歷,PDF文檔,或是推特、微博、博客這些社交內容等等。都適合用Solr來處理。
·結果是按相關性排序的:Solr的搜索返回結果是依照結果文檔與用戶查詢之間的相關程度度作排序的,保證最相關的結果會優先返回。
在本書中,你將學到怎樣使用Solr來設計實現一個可擴展的搜索方案。
咱們的學習旅程從瞭解Solr支持的數據類型和典型用例開始。
這樣你能更好的理解在整個現代軟件應用架構全景圖中Solr所處的位置,以及Solr到底是設計來處理哪些問題的。
1.1我究竟需要一個搜索引擎嗎?
咱們推測你已經有了些想法要準備使用搜索引擎了,不然你也不會翻開這本書。所以。咱們就不浪費時間來揣度你到底是爲何開始考慮用Solr的了,咱們直接來討論點乾貨。看看關於你的數據和用例方面。 有哪些問題是你在決定是否使用搜索引擎以前所必須要回答的。這終於會歸結爲怎樣深入理解你的數據和你的用戶。以選用一個合適的技術來同一時候知足兩者的需求。
咱們先從討論一下哪些數據屬性是搜索引擎適合處理的。
-
1.1.1 管理文本中心的數據
合理選用同數據匹配的存儲及處理引擎,是現代軟件應用架構的標誌性要求之中的一個。假設你是一個優秀的程序猿,那麼你應該知道要依據在算法中使用數據的方式來選取最合適的數據結構。比方,假設你需要實現高速隨機查找,你就不會使用鏈表結構來存儲數據。
相同的道理也適用於搜索引擎的選取。這裏列出了適合用相似Solr這種搜索引擎來處理的數據的4種主要特色:
-
文本中心的數據
-
讀取遠多於寫入的數據
-
面向文檔的數據
-
靈活的Schema
或許在這兒應該加上第五個數據特性,即:海量數的據量。也就是」大數據「,但是咱們主要關注的是Solr差異於其它NoSQL技術的主要特性。而可以處理海量的數據並不是它們的主要差異之中的一個。
儘管這裏列出了相似Solr這種搜索引擎可以有效處理的數據類型的4個主要特色,但是這僅僅是一個粗略的準則,並不是一個嚴格的標準。
咱們來深刻的討論一下這些數據特性,看看爲何它們對於搜索來講這麼重要。咱們現在僅僅關注概念,詳細的實現細節在稍後的章節討論。
文本中心的數據
你確定見過有人用「非結構化數據「這個術語來描寫敘述搜索引擎處理的數據。咱們以爲「非結構化」這個詞有些模糊不清,因爲不論什麼一個基於人類語言產生的文檔都是隱含有必定的結構的。
要理解「非結構化」這個術語你可以以爲這是從計算機的角度來看的。
在計算機眼中,文本文檔就是一個字符流。這個字符流必須經過特定的語言規則解析出語義結構。才幹被檢索到。而這正是搜索引擎的工做所在。
咱們以爲「文本中心的數據」這個詞更適合用來描寫敘述Solr處理的數據類型。因爲搜索引擎的設計初衷就是用來提取文本數據的隱含結構,並生成相關索引以提升查詢檢索的效率。「文本中心的數據」這個詞隱含代表了文檔中的文本信息包括用戶感興趣的查詢內容。
固然,搜索引擎也支持非文本數據,比方數字類型的數據。但是其主要強項,仍是在於處理基於天然語言的文本數據。
前面說的都是「文本」。事實上「中心」這個部分也很是重要,因爲假設你的用戶對於文本部分的內容不感興趣,那麼搜索引擎可能就不是處理你的問題的最佳選擇。舉個樣例,對於一個給員工用來建立差旅支出報告的應用,每份報告都包括一些結構化的數據,比方日期。費用類型,匯率,數量等等,另外每項費用後面可能會包括一些備註信息。用於描寫敘述該項費用的大體狀況。
這樣一個應用就是一個包括文本信息。但並不是「文本中心的數據」的一個樣例。因爲會計部門在使用這些員工的支出費用報告來生成月度支出報告時,並不會經過查找備註裏的文本信息來作,文本在這裏並不是其關心的主要內容。簡單來講。就是否是所有包括文本信息的數據都適合搜索引擎來處理。
因此現在先花幾分鐘好好想一想你的數據是不是「文本中心的數據」。考慮的重點主要就是數據中的文本信息用戶是否是會拿來作檢索。
假設答案是YES,那麼搜索引擎很是多是一個好的方案選擇。
咱們在第5章和第6章會討論怎樣利用Solr的文本分析來提取文本數據的結構的細節。
讀取遠多於寫入的數據:
另一個搜索引擎可以高效處理的數據特性是「讀取遠多於寫入的數據」。首先,需要聲明的是Solr是贊成你更新索引中的現有文檔內容的。你可以把「讀取遠多於寫入」解讀爲對於文檔的讀取操做頻率要遠遠高於建立文檔和更新文檔的頻率。但是別狹隘的理解爲你就全然不能寫入數據了,或是你會被限制在一個特定頻率之下更新數據。其實Solr4的一個關鍵特性就是「近乎實時的查詢」。這個功能可以贊成你每秒鐘爲數千的文檔創建索引並且差點兒立馬就能查詢到這些新增長的文檔。
「讀取遠多於寫入的數據」背後的關鍵點是你的數據在寫入Solr後,在其生命週期內應該是要被反覆讀取很是屢次的。
你可以理解爲搜索引擎並不是主要用來存儲數據的。而是主要用於查詢存儲的數據的(查詢請求是一種讀取操做)。因此假設你需要很是頻繁的更新數據。那麼搜索引擎可能不太適合你的需求,其它的NoSQL技術,比方Cassandra,可能更適合你的高速隨機寫入的需求。
面向文檔的數據
到眼下爲止,咱們一直使用更通用的「數據」這一術語,但是實際中搜索引擎處理的都是文檔數據。在搜索引擎中。一個文檔是由值域(field)組成的獨立集合,每一個值域都僅僅保存數據值。不能再嵌套包括其它值域。換句話說。在Solr這種搜索引擎中,文檔都是扁平結構的,文檔之間不存在相互依賴關係。Solr中「扁平」的概念是比較寬鬆的。一個值域可以保存多個數據值,但是值域不能再嵌套包括子值域。
也就是說你可以在一個值域裏存儲多個數據值。但是你不能往值域裏頭嵌套別的值域。
Solr中這樣的扁平化的、面向文檔的方式可以很是好的處理已經文檔化的數據。比方網頁,博客。pdf文檔等等。那麼假設要用solr來處理關係型數據庫中已經結構化好的數據應該怎麼辦呢?這樣的狀況下你需要先把關係型數據庫中跨表存儲的數據取出來,去結構化。而後放到扁平化的自包括文檔結構裏。咱們會在第三章學習怎麼處理這樣的問題。
你還需要考慮你的文檔數據中的哪些值域需要存儲在Solr中,哪些值域需要存儲在其它系統中(比方數據庫中)。簡單來講。搜索引擎僅僅存儲需要被檢索到的數據,以及用於顯示檢索結果的數據。
舉個樣例。假設你有一個在線視頻的搜索索引。你應該不會但願把視頻文件自己存儲在Solr中。合理的方案應該是把大的視頻文件都放在內容分發網絡(CDN)中。一般你僅僅需要在搜索引擎中存儲知足搜索需求的最少數據就能夠。剛纔這個在線視頻的樣例清楚的說明了不要把Solr當成通用數據存儲技術,Solr的工做是找到用戶感興趣的視頻文件,而不是存儲視頻文件自己。
靈活的Schema
最後一個搜索引擎數據的主要特性是有靈活的schema。
這意味着查詢索引中的文檔不需要擁有統一的結構。在關係型數據庫中,表中的每一行數據都必須擁有一樣的結構。而在Solr中,文檔們可以有不一樣的值域。固然同一個索引中的文檔們至少應該擁有一部分你們都有的值域以便於檢索,但是並不要求所有文檔中的值域結構全然同樣。
舉個樣例。假如要作一個用於查找出租和出售房源的搜索應用。顯然每條房源文檔都會有地段。房間數,衛生間數等一些共同擁有的值域,但是依據類型是出租仍是出售的不一樣。不一樣的房源文檔會有不一樣的值域。一條出售的房源會有售價值域,財產稅值域。而一條出租的房源文檔則會有月租金和寵物政策等等不一樣的值域。
總結一下,Solr這種搜索引擎是專門優化用於處理文本中心的,讀取遠多於寫入的,面向文檔的。擁有靈活Schema的數據用的。Solr並不是一種通用數據存儲處理技術,這也是差異於其它NoSQL技術的主要因素。
有衆多不一樣的數據存儲和處理方案可供選擇的優勢是你再也不需要費勁腦汁地尋找一種可以知足所有需求的通用技術方案。搜索引擎在某些特定任務上表現出色。但是在其它一些方面性能很是差。這意味着在大多數狀況下,你可以用Solr來做爲關係型數據庫和其它NoSQL技術的有力補充,而並不是要代替後者。
既然咱們已經談到了Solr所針對優化處理的數據類型,那咱們就接着來討論一下像solr這種搜索引擎主要是設計來解決哪些實際用例的。
理解這些用例可以幫助你理解搜索引擎技術是怎樣差異於其它數據處理技術的。
-
1.1.2 常見的搜索引擎用例
在這一節中,咱們來看看Solr這種搜索引擎都能幹些什麼。正如咱們在1.1.1節中所提到的那樣。這些討論僅僅是一種指南性質的建議,不要把它們當成嚴格的使用規則來看。在咱們開始以前。你需要意識到想作出一個優秀的搜索服務,其門檻是很是高的。
現在的用戶都習慣於使用像Google和Bing這樣又快又高效的網絡搜索引擎。而很是多受歡迎的站點也有本身強大的搜索方案來幫助用戶高速的獲取想要的信息, 因此用戶對搜索服務並不陌生並且會很是的挑剔。當你在評估像Solr這種搜索引擎時,或是在設計你本身的搜索方案時,必定要有根弦兒。要把用戶體驗放在高優先級上來考慮。
主要的keyword查詢
很是明顯,做爲一個搜索引擎來講, 首先必須要能夠支持主要的關鍵詞查詢。
這也是搜索引擎的主要功能之中的一個。只是關鍵詞查詢功能仍是值得在這裏強調一下的,因爲這是用戶使用搜索引擎最典型的方式。
很是少實用戶想要會一上來就填寫一個很是完整的複雜搜索表單來進行搜索的。考慮到關鍵詞搜索功能將會是用戶和你的搜索引擎之間最多見的交互方式。這個基本功能必須能夠提供給用戶以很是好的用戶體驗才行。
通常來講,用戶但願僅僅輸入幾個簡單的關鍵詞就能獲取到很是好的搜索結果。
這或許聽上去像是一個簡單的匹配任務:把查詢字串和文檔進行匹配就能夠。只是請考慮一下要實現良好的用戶體驗所必須解決的幾個問題:
· 相關結果必須迅速返回,大多數狀況下要求一秒鐘以內就行返回
· 用戶的查詢字串出現拼寫錯誤時能夠本身主動糾錯
· 用戶輸入時經過本身主動補全建議來下降用戶的輸入負擔,這在移動應用中非常常見
· 處理查詢字串中的同義詞近義詞
· 對包括查詢字串的語言變異的文檔進行匹配(譯者注:語言變異是語義學術語,即用詞不全然同樣的近似表達)
· 短語處理。用戶是但願匹配短語中所有的單詞,仍是僅僅要匹配短語中的部分單詞便可
· 對一些通用介詞的處理,比方「a,」 「an」, 「of」, 「the」等等
· 假設最靠前的查詢結果用戶不愜意。 怎樣給用戶返回不少其它的查詢結果
就像你看到的那樣,不使用特定的處理方法的話。這樣一堆問題會使得看上去如此簡單的功能實現起來變得很是困難。然而利用像Solr這種搜索引擎,這些功能就能立等可取,實現起來變得很是easy。當你給用戶提供了一個強大的關鍵詞搜索工具以後,接下來你就需要考慮怎樣去展現查詢的結果,這就引出了下一個用例,依照結果同查詢請求之間的相關性順序。對搜索返回的查詢結果進行排序。
排序的檢索結果
搜索引擎爲查詢返回「最靠前「的結果。在SQL查詢關係型數據庫的時候,某一行數據記錄要麼匹配查詢被返回,要麼不匹配查詢被忽略,查詢結果也是依照數據記錄的某一列屬性來排序的。而對於搜索引擎來講,返回的結果文檔是依照得分作降序排列的。該得分表示文檔和查詢的匹配程度。匹配程度得分根據一系列的因子來計算。只是通常說來得分越高。代表結果文檔同查詢之間的相關度越高。
有好幾個因素決定了將結果文檔依照相關度排序的方式很是重要。首先,現代搜索引擎通常都存儲着海量的文檔,都是上百萬甚至數十億記的。假設不正確查詢結果進行相關度排序。那用戶就會被海量的返回結果所淹沒,沒法清晰有效的瀏覽搜索的結果。其次。用戶使用其它搜索引擎的經驗使得用戶已經習慣於使用少數的幾個關鍵詞就能得到不錯的查詢結果。也使得用戶廣泛比較缺少耐心。
他們會期待搜索引擎依照他們想要的意思來工做,而不管其所輸入的信息是否全然正確。比方對於移動應用的後臺搜索服務來講,用戶會期待在輸入了簡短的幾個可能還包括有拼寫錯誤的查詢詞以後,搜索服務就行返回正確的搜索結果。
假設要人工干預排序的結果,你可以給特定的文檔、值域、或者查詢字串添加權重,或着直接提升某個文檔的相關度分值。比方你假設但願把新添加的文檔推送到最靠前的位置,就可以經過依照建立時間來提升文檔排序的方式實現。咱們在第三章中會學習關於文檔排序的知識。
除了關鍵詞查詢以外
利用像Solr這種搜索引擎,用戶可以輸入少數幾個關鍵詞就能獲取到一些搜索結果。然而對於很是多用戶來講這不過一個查詢交互的第一步。他們需要在查詢結果中可以繼續地瀏覽。驅動一個信息發現的交互會話過程也是搜素引擎的一個主要應用場景。通常用戶在搜索前並不是很是精確的知道想要查詢的信息什麼樣的。他們事先也不知道你的系統中究竟存儲了哪些信息。一個好的搜索引擎可以幫助用戶不斷地細化信息需求,一步步到達最需要的信息。
這裏的核心思想是在返回用戶最初的查詢所相應的文檔結果的同一時候,提供給用戶一個工具,使其能夠不斷地改進查詢以得到更需要的信息。換句話說。在返回匹配的文檔以外,你應該返回一個工具讓用戶知道下一步該怎麼辦。舉個樣例。你能夠對查詢結果依照屬性進行分類,便於用戶依據需求作進一步的瀏覽。
這樣的功能稱之爲分類檢索(Faceted-Search),這也是Solr的功能亮點之中的一個。
咱們會在1.2節中看到一個關於房地產的分類檢索實例,在第八章中會具體介紹分類檢索功能的細節。
搜索引擎不適合作的事…
最後。咱們來討論一下不適合應用搜索引擎的一些用例場景。
首先。搜索引擎通常的設計是,爲每個查詢返回一個小的文檔集,一般包括10個到100個的結果文檔。不少其它的結果文檔能夠經過Solr自帶的結果分頁功能來獲取。對於一個查詢結果有好幾百萬個文檔的狀況。假設你要求所有的匹配文檔都要能夠一次返回,那麼你會等待很是長的時間。
查詢自己會運行的很是快,但是從索引結構中重建上百萬的文檔絕對是一件很是耗時間的事情。因爲Solr這種搜索引擎在硬盤上存儲值域的方式僅僅適用於高速生成少許的文檔結果,假設需要一次生成大量的查詢結果。在這種存儲方式之下生成大量文檔結果就會耗費大量的時間。
還有一個不適合應用搜索引擎的使用場景是需要讀取索引文件的大部分子集的才幹完畢的深度分析任務場景。
即便你經過結果分頁技術避免了剛剛說的那個問題。假設一次分析需要讀取索引文件裏的大量數據。你也會遇到很是大的性能問題,因爲索引文件的底層數據結構就不是爲一次大量讀取來設計的。
咱們前面有提到過一點。但是在這裏仍是要再次強調一下。那就是搜索引擎技術並不適合用於在文檔的相互關係之間進行查詢。Solr確實是可以支持基於父子關係的查詢。但是並不支持在複雜的關係型數據結構之間查詢。在第三章。你會學習到怎樣將關係型數據結構適配到適合solr處理的扁平型文檔結構中進行查詢。
最後,絕大多數搜索引擎都沒有直接的文檔級安全支持,至少Solr是沒有。
假設你需要嚴格管理文檔的權限,那你僅僅能在搜索引擎以外來想辦法。
到這裏咱們已經瞭解了適合搜索引擎處理的用例場景和數據類型,下一步該是時候討論Solr究竟能作些什麼。以及這些功能是怎樣實現的了。在下一節中,你將學習到Solr究竟有哪些主要功能。以及她是怎樣實現外部系統集成、可擴展性、以及高可用性等軟件設計原則的。