摘要:在項目中使用Solr作為搜索引擎對大數據量創建索引,提供服務,本文是作者對Solr的使用總結的一點心得體會,
具體包括使用DataImportHandler從數據庫中近實時同步數據、測試Solr創建索引的性能、以及測試Solr的搜索效率總結等。
具體搜索引擎概念、Solr搭建方法、數據庫mysql使用方法,假設讀者已有了基礎。本文操作均是在linux上進行的。
1. Solr
1.1 Solr從數據庫中讀取數據並創建索引速度(使用DataImportHandler)
l 一次性創建索引
在JVM內存配置為256M時,建立索引至1572865時出現Java heap異常;增加JVM內存配置至512M,設置系統環境變量:JAVA_OPTS -Xms256m -Xmx512m,能成功建立2112890條(花費2m 46s)。
平均索引創建速度為:12728/s(兩個string字段,長度大約為20字符)。
l 增量創建索引
注意:近實時增量索引需要寫數據庫服務的時間與搜索引擎服務器時間同步(數據庫服務時間先於搜索引擎服務器時間才行)。
使用默認的DIH創建增量索引速度較慢(50/s~400/s),不如全索引(1W/s),因為需要從數據庫中讀取多遍(1、要更新的IDs;2、每1ID去數據庫中重取所有列)。
故需要更改DIH增量索引程序,以全索引的方式讀數據;或采取全讀出的方式,一次全讀出所有列,具體文件配置如下:
<?xml version="1.0" encoding="UTF-8" ?> <dataConfig> <dataSource name="mysqlServer" type="JdbcDataSource" driver="com.mysql.jdbc.Driver" batchSize="-1" url="jdbc:mysql://192.103.101.110:3306/locationplatform" user="lpuser" password="jlitpassok"/> <document> <entity name="locatedentity" pk="id" query="select id,time from locationplatform.locatedentity where isdelete=0 and my_date > '${dataimporter.last_index_time}'" deletedPkQuery="select id from locationplatform.locatedentity where isdelete=1 and my_date > '${dataimporter.last_index_time}'" deltaQuery="select -1 id" deltaImportQuery="select id,time from locationplatform.locatedentity where isdelete=0 and my_date > '${dataimporter.last_index_time}'"> <field column="id" name="id"/> <field column="time" name="time"/> </entity> </document> </dataConfig> |
通過這樣的配置可以達到增量索引9000/s(兩個string字段)(數據庫里對時間建立索引,對這里的性能影響不大)。
l 注意:作者不推薦使用DataImportHandler,有其它更好更方便的實現可以使用。
1.2 Solr創建索引效率
l ConcurrentUpdateSolrServer使用http方式,embedded方式官方不推薦使用。ConcurrentUpdateSolrServer不需要commit,solrServer.add(doc)即可添加數據。SolrServer solrServer = newConcurrentUpdateSolrServer(solrUrl, 隊列大小, 線程數)其需要與autoCommit、autoSoftCommit配置搭配使用,網上建議配置如下:
<autoCommit> <maxTime>100000(1-10min)</maxTime> <openSearcher>false</openSearcher> </autoCommit> <autoSoftCommit> <maxTime>1000(1s)</maxTime> </autoSoftCommit> |
17個各種類型字段(原純文本Size約為200B,SolrInputDocument對象Size約為930B),以只保存ID、每字段均建立索引的方式創建索引。
如需具體的測試代碼可以聯系本人。
l 17個字段,四核CPU,16G內存,千兆網絡
數據量(W條) |
線程數 |
隊列大小 |
時間(s) |
網絡(MB/s) |
速率(W條/s) |
200 |
20 |
10000 |
88 |
10.0 |
2.27 |
200 |
20 |
20000 |
133 |
9.0 |
1.50 |
200 |
40 |
10000 |
163 |
10.0 |
1.22 |
200 |
50 |
10000 |
113 |
10.5 |
1.76 |
200 |
100 |
10000 |
120 |
10.5 |
1.67 |
l 速度:Solr創建索引速度與Solr機器CPU正相關,一般情況下CPU占用率能達到接近100%,內存占用率在默認情況下需達到接近100%,網絡、磁盤占用率均小。因此創建索引的效率瓶頸在CPU及內存。當內存占用率維持在接近100%,索引大小達到物理內存大小時,插入新的數據容易出現OOM錯誤,這時需要使用ulimit –v unlimited命令更改virtual memory配置為unlimited再啟動Solr便不會出現OOM錯誤。在64位機器系統上,官方推薦使用MMapDirectory。
l NRTCachingDirectory速度偏慢,會在某一時間索引添加停滯,Size先大后小,減小后索引添加繼續。
l 大小:1億索引大小約為13-16GB,2億索引大小約為30GB。
1.3 Solr搜索方式
l 交集:{name:億度 AND address:海淀} {text:海淀 AND 億度}。
l 聯集:{name:億度 OR address:海淀} {text:海淀 OR 億度}。
l 排除:{text:海淀 -億度}。
l 通配符:{bank:中國*銀}。
l 范圍:{num:[30 TO60]}。
l 分頁:start rows
l 排序:sort
l Group 權重中文分詞 ...
1.4 億級數據搜索速度
l 本節測試是基於1.2節創建的索引上的。
l精確搜索
數據量(億條) |
字段數 |
字段類型 |
時間(ms) |
1 |
1 |
long |
1 |
1 |
1 |
double |
80-1400 |
1 |
1 |
string |
7-800 |
1 |
1 |
date |
2-400 |
1 |
2(OR) |
long |
2 |
1 |
2(OR) |
double |
200-2400 |
1 |
2(OR) |
string |
500-1000 |
1 |
2(OR) |
date |
5-500 |
l 模糊搜索
數據量(億條) |
字段數 |
字段類型 |
時間(ms) |
1 |
1 |
long |
2000-10000 |
1 |
1 |
double |
1000-17000 |
1 |
1 |
string |
20-16000 |
1 |
1 |
date |
/ |
1 |
2(OR) |
long |
3000-25000 |
1 |
2(OR) |
double |
7000-45000 |
1 |
2(OR) |
string |
3000-48000 |
1 |
2(OR) |
date |
/ |
l 范圍搜索
數據量(億條) |
字段數 |
字段類型 |
時間(ms) |
1 |
1 |
long |
6-46000 |
1 |
1 |
double |
80-11000 |
1 |
1 |
string |
7-3000 |
1 |
1 |
date |
1000-2000 |
1 |
2(OR) |
long |
100-13000 |
1 |
2(OR) |
double |
100-60000 |
1 |
2(OR) |
string |
3000-13000 |
1 |
2(OR) |
date |
7000-10000 |
l 結論:
范圍越大,結果數據越多,搜索花費時間越長。
第一次搜索較慢,后來時間花費較少。