嚴格來說,我這篇內容,主要是根據Solr in Action關於配置的說明,以及參考Solr的wiki寫的算是讀書筆記吧,所有的圖片默認來自Solr in Action這本書。
這本書我覺得對學習Solr來說非常有用,雖然目前沒有中文版,另外對於其理解可能有偏差的地方,大家謹慎閱讀。
一、總覽
solr的配置重要的有三個:solr.xml、solrConfig.xml、schema.xml
solr.xml 是整個Solr節點的配置,是定義關於core的管理、collection分片、solr雲
和http請求處理,不過目前改動不多,也沒仔細研究。
solrConfig.xml:關於core或collection的主要配置信息。
schema.xml :定義索引中的文檔結構,包括字段名、字段類型、字段處理方法等,類似於表結構定義,比它更復雜。
二、Solr啟動過程
1、solr啟動的時候會找Java的全局變量:solr.solr.home ,作為根目錄。
2、solr到根目錄下面的每個子目錄,去查找是否包含core.properties的文件,有的話自動啟動這個collection或core的恢復工作。
core.properties 配置文件主要配置,core或collection名字、shard分片信息、存儲的數據和日志信息以及定義的schemal.xml等。
在恢復過程中,solr會在這個子目錄下面的conf文件夾下去找solrconfig.xml的配置。
下圖是solr的例子程序啟動過程:

三、solrconfig.xml 配置說明
3.1 基本概述
- 基本說明
1、在solr的管理界面上選擇具體的core就可以在files里面找到這個配置文件。
2、solr的配置的xml元素里面有兩個比較特別的元素,一個是<arr>標示是命名的數組,
<lst>標示是排序的name/pairs對。
3、如何使修改的配置生效那,可以通過:前台core管理地方通過reload或通過http請求進行reload。
比如:http://xx.xx.xx.xx:8983/solr/admin/collections?action=RELOAD&name=testspeed3
- 具體內容
1、solr使用的Lucene版本、使用到的Jar路徑配置;JMX配置,用於MBeans監控。
2、定義如何處理查詢、如何處理索引的內容。
3.2 查詢配置
solr最重要的功能之一是查詢,我們看下當我們發起一個查詢的時候,它的處理過程如何的,
發起的solr的http的ulr例子如下:

如果按照solr官方的利用Jetty服務器的話,那么處理過程如下圖:

組件調用說明:
1、客戶端發送HTTP的GET請求,查詢關鍵字作為一個部分發送給Jetty服務器。
2、Jetty通過查詢路徑中的/solr上下文,通過調度器將這個請求映射到solr這個
web程序中去。
3、solr請求處理器,利用collection1這個路徑來確定core或collection名字,通過select來找到注冊在
solrconfig.xml中的請求處理器。
4、solrconfig.xml中注冊的查詢請求處理器執行一系列配置組件去處理。
5、按照solrconfig.xml中配置的返回處理組件,去設置返回的具體格式,執行返回。
查詢請求處理器定義:
<requestHandler class="solr.SearchHandler" name="/select">
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
<str name="df">text</str>
</lst>
</requestHandler>
solr.SearchHandler 最終被解析為:org.apache.solr.handler.component.SearchHandler這個類進行處理。
solr其他的配置類似。
solr的查詢過程的詳細情況分為幾個階段,如下圖:

1、請求參數裝飾
1)defaults - 幫忙指定默認參數。
2)invariants-設置特定參數為固定值,重寫客戶端提供的值。
3)append - 在客戶端的參數基礎上進行參數的添加。
2、 第一組件
可選擇配置的,用於查詢處理前的預處理。
3、查詢組件鏈
至少包含查詢組件,用於執行具體的查詢工作。
4、最后組件
用於處理查詢后最后工作,比如拼寫檢查組件。
具體的定義,可以看下solrconfig.xml中提供的一個/browse定義的相關查詢整個過程的配置。
3.3 搜索器(Searcher)
- 搜索器說明
在solr中,具體執行的搜索工作是通過搜索器執行的,如上面的圖所示。在一個solr節點中,只有一個注冊的搜索器。
它是一個基於Lucene索引的可讀快照,當文檔被添加到索引中,不是立刻可以搜索到。
讓新添加的文檔可以被搜索到,需要關閉老的搜索器,打開新的搜索器。一般來說commit操作就會執行這個操作。
這個過程是比較耗時的,關閉老的搜索器的時候,如果有用戶正在查詢,你的關閉動作需要等待。
另外所有的緩存都是基於舊的索引的,所以所有的緩存將失效,除非重新預熱。
- 預熱搜索器
如上文所述,搜索器在commit后需要重新打開,如果原來用戶正在執行查詢,緩存數據完全失效了,會促使重新執行查詢,
導致用戶體驗差,所以需要預熱。
一般來說,預熱做兩個事情,一執行預熱語句、二用新的查詢到的緩存數據代替老的緩存數據。
注意,多的預熱語句,將會導致打開新的搜索器變慢,影響實時性,頻繁提交的話將會導致內存等占用過大問題。
- 使用冷搜索器
如果說預熱好的搜索器稱為熱的搜索器:)雖然沒看到這個說法,那么沒有預熱的搜索器稱為冷搜索器,配置如下:
<useColdSearcher>false</useColdSearcher> 如果這個配置為true,則來查詢的時候,如果沒有注冊的
搜索器,有的搜索器正在預熱,那不管是否預熱完成,直接使用這個搜索器。
(這里面有個矛盾,既然所有的搜索器都是在新的預熱好,老的才被關閉的,那么這種情況怎么存在,也許是第一次執行查詢的時候)。
- 最大預熱搜索器
當每次commit都會打開一個新的搜索器進行預熱,那么如果commit操作在程序里面控制,在並發的情況下,可能有多個搜索器被打開,
有個配置項:<maxWarmingSearchers>2</maxWarmingSearchers>,通過它來配置可以打開的最大搜索器的個數,超過這個閥值,
commit操作會失敗,如果經常因為這個失敗,要看下是不是因為預熱的時間過長。
3.4 緩存配置
- solr中緩存管理
1)緩存的尺寸和管理策略
Solr中設置緩存的尺寸是對象的數量,當超過這個數量的時候,Solr利用相關策略進行清除。
有兩個主要策略LRU(即Least Recently Used )將最近最少使用的實體移出緩存;
LFU(least frequently used)是將最少使用次數的實體移出緩存,過濾器緩存比較適合LFU策略。
有個誤區是在內存准許的情況下,盡可能設置你的緩存為盡可能的大。這個認識是錯誤的。
因為在commit后,緩存會失效,這將導致JVM回收這些內存,緩存大,導致JVM回收垃圾時間長,
服務被暫停的時間長。
2)緩存的命中和拆遷
命中率是指在緩存中發現一個查詢請求的比例。代表你的程序從緩存中獲得的好處。
期望是100%,驅逐數量顯示根據前面的緩存策略,多少對象被驅逐出緩存,拆遷量大
可能意味着你的緩存設置的小。
3)緩存對象的失效
在solr中,所有的緩存對象和搜索器都是關聯的,只要這個搜索器不關閉,這些緩存就是有效的。
4)自動預熱新緩存
在一個commit之后,新的搜索器被打開,但是不立刻關閉老的搜索器,直到這個新的搜索器被完全預熱。這個晚關閉策略主要用於填充新的搜索器的緩存。
每個solr緩存都支持一個autowarmCount的屬性去設置最大的對象數量或者老的緩存的尺寸比例,去自動預熱。
- 過濾器緩存( Filter Cache)
過濾器緩存影響最終文檔結果,不影響打分。當你執行不同的查詢語句,而相同過濾條件的時候,過濾器緩存就可以起作用。
過濾器緩存可以跨查詢應用,可以顯著優化查詢的性能。
配置如下:
<filterCache class="solr.FastLRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
當你的過濾條件復雜,或你索引中的文檔數量很多的時候,過濾器的創建和保存在內存中是很耗時間的,所以你希望可以預熱過濾器緩存。如果一個過濾在你的程序中對很多請求都通用,那么緩存過濾器是有意義的。
每個對象在緩存中都有個key,在過濾器緩存中,這個key就是過濾器的查詢語句,比如前面例子中:manu:belkin. 當預熱一個過濾器緩存時候,舊的緩存中的key被抽取出來,在新的搜索器上被重新執行。如果你有上百個過濾器緩存,那么在預熱的時候,solr必須執行這個100個過濾器的查詢,這將消耗大量的時間。
我們建議預熱的過濾器緩存,應該將autowarmCount設置為一個比較小的值。此外建議使用
LFU策略,下面是建議的配置:

過濾緩存器所占用的內存大小,當然和你在內存中緩存的文檔數量有關,需要的內存是你文檔數這么多的byte內存。
1000萬的文檔數大概占1.2MB內存。
- 查詢結果緩存(Query result cache)
查詢結果集緩存保存的是查詢結果集。多次執行同一個查詢的時候,后面的查詢結果一般從查詢結果緩存中直接得到,而不是在索引中再次執行相同的查詢,這是優化花費高查詢的強大方法。
查詢結果集緩存定義如下:
<queryResultCache class="solr.LRUCache"
size="512" initialSize="512" autowarmCount="0">
查詢結果集緩存了查詢語句作為key,內部的Lucene文檔ID鏈表作為value。
文檔ID在索引中增加新的文檔的時候或合並的時候可能發生變化,所以預熱的時候,
緩存值需要被重新計算。
為了預熱一個結果集,solr必須重新執行查詢,相同的建議是保持autowarmCount為一個較小的值而不是默認的0,你將從中獲益。還有些關於些雜項來設置查詢結果集。
- 查詢結果窗口大小
查詢窗口<queryResultWindowsSize> 元素,在你執行一個查詢的時候,給你提供額外的頁面。
假設你的程序一頁提供10個文檔,在大多數情況下,用戶只看第一和第二頁。你可以設置這個值為20,這樣在查看第二頁的時候就不用再次查詢了。
一般情況下,這個值設置為你一頁需要查詢的文檔數量2-3倍,多了會給你的查詢帶來不必要的負擔。
- 查詢結果最大文檔緩存
在前面,給緩存設置的值的大小,代表緩存的數量,每個緩存的最大大小也可以設置一個值。
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>就是設置一個緩存實體可以緩存的最大文檔數量。
- 准許延遲字段加載
具體配置為:<enableLazyFieldLoading>true</enableLazyFieldLoading>,設置了后,如果你的查詢是查詢文檔集
中的一部分,那么只有需要的字段才被加載,其他字段不加載。
(默認的值為true。這樣solr在根據讀取Document信息時,如果enableLazyFieldLoading為True,把要返回的Field集合封裝為一個SetNonLazyFieldSelector,
這里的Field的值都是立即加載的,即到索引庫里把該Field的值取出來保存到Doc中的。doc的其他的Field的值則是通過延遲加載的。
也是就在document調用具體的get(String name)方式時,由LazyField去取值的。可見設置延遲加載為enableLazyFieldLoading 為True,
而且我們要返回的Field也很少時,那我們去讀索引庫所花的時間就少了)
- 文檔緩存(Document Cache)
查詢結果緩存是保存匹配查詢的一系列文檔內部ID,即使查詢結果在緩存中。solr仍然需要從磁盤中加載搜索結果的文檔信息。文檔緩存,存儲的key為內部文檔ID,值為從磁盤加載進來的文檔內容。因此查詢結果集緩存可以利用文檔緩存去查詢在查詢結果集中對應的文檔信息。
<documentCache class="solr.LRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
- 字段值緩存(Field Cache)
它在排序的時候使用,嚴格來說屬於Lucen來管理的。字段值緩存提供了通過文檔ID來快速訪問字段值。
