我目前的任务是找出在solr中加载数百万个文档的最佳方法。 数据文件是以csv格式从DB导出的。
目前,我正在考虑将文件拆分为较小的文件并使用脚本,同时使用curl发布这些较小的文件。
我注意到如果您发布大量数据,大部分时间请求都会超时。
我正在研究数据导入器,它似乎是一个不错的选择
高度赞赏任何其他想法
由于
答案 0 :(得分:22)
除非数据库已经是您解决方案的一部分,否则我不会为您的解决方案增加额外的复杂性。引用SOLR FAQ它是发出会话超时的servlet容器。
在我看来,你有几个选择(按我的偏好顺序):
增加容器超时。 (“maxIdleTime”参数,如果您使用的是嵌入式Jetty实例)。
我假设你只是偶尔索引这么大的文件?暂时增加暂停可能只是最简单的选择。
这是将完成工作的简单unix脚本(以500,000行块分割文件):
split -d -l 500000 data.csv split_files.
for file in `ls split_files.*`
do
curl 'http://localhost:8983/solr/update/csv?fieldnames=id,name,category&commit=true' -H 'Content-type:text/plain; charset=utf-8' --data-binary @$file
done
以下groovy脚本使用opencsv和solrj来解析CSV文件,并每隔500,000行将更改提交给Solr。
import au.com.bytecode.opencsv.CSVReader
import org.apache.solr.client.solrj.SolrServer
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer
import org.apache.solr.common.SolrInputDocument
@Grapes([
@Grab(group='net.sf.opencsv', module='opencsv', version='2.3'),
@Grab(group='org.apache.solr', module='solr-solrj', version='3.5.0'),
@Grab(group='ch.qos.logback', module='logback-classic', version='1.0.0'),
])
SolrServer server = new CommonsHttpSolrServer("http://localhost:8983/solr/");
new File("data.csv").withReader { reader ->
CSVReader csv = new CSVReader(reader)
String[] result
Integer count = 1
Integer chunkSize = 500000
while (result = csv.readNext()) {
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", result[0])
doc.addField("name_s", result[1])
doc.addField("category_s", result[2])
server.add(doc)
if (count.mod(chunkSize) == 0) {
server.commit()
}
count++
}
server.commit()
}
答案 1 :(得分:12)
在SOLR 4.0(目前在BETA中)中,可以使用UpdateHandler直接导入本地目录中的CSV。修改the SOLR Wiki
中的示例curl http://localhost:8983/solr/update?stream.file=exampledocs/books.csv&stream.contentType=text/csv;charset=utf-8
这会从本地位置传输文件,因此无需将其整理并通过HTTP发布。
答案 2 :(得分:3)
以上答案已经很好地解释了单机的摄取策略。
如果您拥有大型数据基础架构并希望实现分布式数据提取管道,则可以选择更多选项。
hive- solr connector,spark- solr connector。
PS:
StandardDirectoryFactory
。autoCommit
文件中的autoSoftCommit
和solrconfig.xml
配置。SolrServerException:没有可用于处理此问题的实时SolrServers 请求
答案 3 :(得分:1)
绝对只是先将它们加载到普通数据库中。有各种各样的工具来处理CSV(例如,postgres' COPY),所以应该很容易。使用Data Import Handler也非常简单,因此这似乎是加载数据最无摩擦的方式。此方法也会更快,因为您不会有不必要的网络/ HTTP开销。
答案 4 :(得分:-1)
The reference guide says ConcurrentUpdateSolrServer
可以/应该用于批量更新。
Javadocs有些不正确(v 3.6.2,v 4.7.0):
ConcurrentUpdateSolrServer缓冲所有添加的文档,并将它们写入打开的HTTP连接。
它不会无限期地缓冲,但最多为int queueSize
缓冲区,这是一个构造函数参数。