1 什麼是solr?
「內事不決問百度,外事不決問谷歌」,相信大家對百度、谷歌等搜尋引擎都很熟悉了。網上信息浩瀚萬千,而且毫無秩序,所以搜尋引擎對用戶的作用就體現出來了。
不過,因為商業原因,百度、谷歌等搜尋引擎都不是開源的。但是,大家不用擔心,有閉源的,當然也有開源的搜尋引擎。優秀的開源搜尋引擎有Apache Solr、Elastic Search、Index Tank等等,今天我們主要介紹Apache Solr。
Apache Solr是一個高性能,基於Lucene的全文搜索伺服器。做為一款搜尋引擎,solr不具備爬蟲一樣採集信息的能力,而是專注於信息的存儲和檢索。許多朋友誤認為solr是資料庫,從廣義上講也可認為是資料庫,但是它和傳統意義上的資料庫還是有些區別的。
相信使用過關係型資料庫的朋友們一定都做過搜索的功能,比如:有100條記錄,我想搜索記錄中含有「雲計算」欄位的記錄,可以使用關係型資料庫提供的「模糊搜索」的功能。「模糊搜索」能不能滿足你的要求呢?如果記錄數小,100條、1000條記錄當然沒問題。但是,如果有100萬條、1000萬條甚至上億,那麼「模糊搜索」的效果就會大大折扣。而這時,我們就需要用到solr等搜尋引擎了。
Solr是基於lucene的倒排索引技術(也叫全文索引,mysql等關係型資料庫也有這個概念,但是「術業有專攻」,solr實現的更好),什麼是倒排索引,下面我會做具體介紹。
1.1倒排索引
傳統意義的資料庫,做索引時,都是一個文檔id對應一個或者多個內容欄位。而倒排索引則是一個內容欄位對應多個文檔id。什麼意思呢?舉個例子,假設分別把下面三句話存儲到mysql和solr中:
I like sportsI like readingI like reading books
在mysql中,一個文檔id對應一條記錄,一條記錄中就會有一個或多個內容欄位。比如:文檔id為1,對應「I like sports」;文檔id為2,對應「I like reading」。而在搜索時,就會一條記錄一條記錄的去檢索,比如:我想搜索「books」欄位,就會先從文檔1找起,文檔1沒有,文檔2也沒有,文檔3找到了,好,返回數據。相對來說,這樣效率有點低。
而在solr中,倒排索引就相反了。它會這樣做索引,「I」內容欄位,對應文檔id為1和2;「like」內容欄位,對應文檔id為1和2;「sports」內容欄位,對應文檔id為1;「reading」內容欄位,對應文檔id為2和3;「books」內容欄位,對應文檔id為3,等等。這樣做的好處在哪呢?
比如:我想搜索「like reading books」這句話,我會把這句話分成三個單詞「like」、「reading」、「books」(這在solr中叫分詞,後面會詳細講),這時我開始通過內容欄位查找文檔id。比如我找「like」,文檔id為1、2、3,那麼這三個文檔都可以取出來。然後,我接著找「reading」,這時,文檔id為1的沒有,只剩下2和3了。最後,我找「books」,只剩下文檔id為3的存在了。根據一定的算法,這次搜索結果,會給三個文檔打分,從高到低:文檔3、文檔2、文檔1。返還給用戶優先級,也是3、2、1。
這樣做的好處是:不用按照文檔id,一個一個的遍歷內容欄位了,而是根據多個內容欄位,去找交叉最多的文檔id(當然了,匹配文檔id不止內容欄位交叉,還有時間、權重等因素,方便理解,省略了),這樣做的話,搜索速度立馬上升。
1.2基本操作
Solr是基於Java語言開發的開源搜尋引擎,內部嵌入了jetty,提供了web界面,用戶可以很方便的在web上操作。當然,考慮到穩定性,我沒有使用solr自帶的jetty,而是選擇了tomcat。
1.2.1 下載solr和tomcat
從Apache官網上下載solr和tomcat並解壓到你希望保存的文件夾(我是都保存在「/usr」中的)。然後把「/usr/solr/server/solr-webapp/」下的「webapp」目錄,複製到「/usr/tomcat/server/webapps/」中並改名為「solr」。
在「/usr/tomcat/server/webapps/solr/WEB-INF/」中創建「classes」目錄,並複製「/usr/solr/server/resources/」下的「log4j.properties」文件到「classes」文件夾中;把「/usr/solr/server/lib/ext/」下的所有jar包複製一份到「/usr/tomcat/server/webapps/lib/」目錄中。
1.2.2 配置tomcat的web.xml
該配置文件指定了solr的具體位置,好為tomcat控制solr做準備。文件在「/usr/tomcat/server/webapps/solr/WEB-INF」目錄下:
1.2.3 配置tomcat的log4j.properties
該配置文件在「/usr/tomcat/server/webapps/solr/WEB-INF/classes」目錄下,指定了solr的日誌保存地址:
1.2.4 啟動tomcat
因為我是用tomcat做solr的web容器,所以啟動tomcat,自然也就會把solr也啟動了。啟動tomcat的命令,在tomcat的二進位命令目錄中。進入「/usr/tomcat/server/bin」,執行「./startup.sh」。Tomcat啟動後,在瀏覽器輸入「http://solr伺服器ip:8080/solr/index.html#/」後,就會顯示下圖所示的畫面,表示solr啟動成功。
1.3中文分詞
Solr與mysql一樣,查詢數據之前,需要先插入數據做成索引。做成索引的方式之前已經有過介紹,下面我開始著重講述solr的分詞部分。
Solr提供了許多的方式用來充當索引的數據源,比如傳遞xml數據、json數據給solr,mysql等關係型資料庫,甚至solr還提供了許多程式語言的擴展給用戶,用戶可以直接使用php、python等語言的solr擴展給solr伺服器傳遞數據。這部分solr官網比較詳細,不再細述。
分詞是solr在做索引和查詢的時候,非常重要的一個步驟。比如說,「I like reading books」,這句英文,我們就可以分成四個單詞(內容欄位),「I」、「like」、「reading」、「books」,這很容易,根據空格就能分詞了。我們搜索「books」單詞,可以把solr中的這句話搜索出來。
但是,solr對於中文分詞就不友好了。再舉個例子:「我喜歡讀書」,這句話怎麼分詞,我們人類可以很容易區分,把它分成「我」、「喜歡」、「讀書」或者「我」、「喜歡讀書」;但是,電腦怎麼做,它可不懂怎麼區分中文。上面這句話,它極有可能分成「我喜」、「歡讀」、「書」,或者更離譜的分詞都有可能,但是這樣做就沒意義了。
下面我們就需要引入一款優秀的關於solr的中文分詞器了:IKAnalyzer。它也是java開發的,大致原理:導入一定數量的中文詞語,然後通過詞庫的詞語分詞。比如:我們從一開始,就把「我」、「喜歡」、「讀書」這樣的中文詞語導入到IKAnalyzer中,然後分詞的時候,按照一定的邏輯,遇到「喜歡」就分一個詞,遇到「讀書」就再分一個詞等等。每次產生新的詞語,就重新導入詞庫一次。這樣,中文分詞的問題就大致解決了。
下面簡單說下IKAnalyzer的使用:
在「/usr/tomcat/server/webapps/solr/WEB-INF/classes」下創建「IKAnalyzer.cfg.xml」配置文件:
2. 在同目錄下創建「dict.txt」和「stopword.dic」文件,「dict.txt」是擴展詞庫,「stopword.dic」是停用詞詞庫。
3. 從IKAnalyzer網站下載「ik-analyzer-solr-6.3.0.jar」,並把它放到tomcat的「/usr/tomcat/server/webapps/solr/WEB-INF/lib」,重新啟動tomcat,就可以使用它了。
2 Solrcloud?
Solrcloud是solr的分布式版本,如果要求不高,我們可以只使用solr就足夠了。但是,如果訪問量或者信息量比較大的話,可能就需要升級成solrcloud了。
不過,如果solr想做成分布式的solrcloud,需要有一組件來對不同的solr節點進行控制和保證配置文件一致性。在原有的基礎上,我們需要藉助zookeeper。
Zookeeper是一個開源的分布式協調服務,提供配置維護、域名服務、分布式同步、組服務等功能,非常強大和方便。在solrcloud中通常充當配置維護和分布式同步的功能。整體架構如下圖所示:
2.1 zookeeper配置
在zookeeper的配置文件目錄中,zoo.cfg為其主要配置文件。裡面主要配置了zookeeper的數據文件夾、日誌文件夾以及全部節點的ip和通信埠。另外需要注意的是:如果你修改好zoo.cfg文件,重啟zookeeper之後,zoo.cfg文件會被初始化,之前的zoo.cfg會備份成zoo.cfg.bak。所以,在你關閉zookeeper之後,想要重啟zookeeper之前,你需要刪除zoo.cfg,並且把zoo.cfg.bak改名為zoo.cfg。
修改好zookeeper的配置文件後,去到zookeeper下的bin目錄,啟動zookeeper:「./zkServer.sh start」。
2.2 tomcat引入zookeeper相關信息
進入tomcat的bin目錄,修改「catalina.sh」文件。在「cygwin=false」前面加上以下代碼,這是指定zookeeper的ip和埠號,tomcat開啟前,需要知道zookeeper節點的信息,為solrcloud做準備。再次啟動成功tomcat,整個solrcloud就算啟動成功了。
3總結
由於篇幅有限,對於solr的介紹還只是冰山一角。主要是希望能夠起到拋磚引玉的作用,solr的功能點比如:權重設置、分面查詢、結果高亮、數據導入、各種程式語言的solr擴展等都沒有介紹,以後有機會的話,再與大家一一探討。