Solr的提交方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Solr的提交方式相关的知识,希望对你有一定的参考价值。

参考技术A

网上的解释真的不能看,全是错的,因为生产中遇到的一次问题对该原理研究了3天,查看了大量书籍,官方文档终于有了较为深刻的认识
Solr的提交方式只有两种,标准提交(硬提交,hard commit)和软提交(soft commit),说三种的错误

1.默认的提交即硬提交,commit之后会立刻将文档同步到硬盘,在开启新搜索器之前会阻塞,直到同步完成
2.默认情况下commit后会开启一个新搜索器(newSearcher),然后进行预热,预热完成后顶替旧搜索器,使旧缓存失效,但是开启新searcher及预热的过程(IO消耗)耗费资源过大,且可能被阻塞,所以应尽量避免在高峰期开启newsearcher,搜索器同一时间只能有一个处于active状态
3.为了避免频繁commit,solr提供了autocommit功能,可以设置每隔多久提交一次,或者待提交文档量达到阀值提交一次,并且可定义是否在提交后开启新的搜索器,若不开启,则缓存不能够被刷新,新更新文档不能够被实时读取到

1.软提交是将文档提交到内存,并不实时写入硬盘,减少了耗时的I/O操作
2.为了保证实时搜索,solr在软提交基础上引入了近实时搜索(NRT),NRT并不会被文档更新所阻塞,也不会等待文档合并完成再打开一个搜索器(以下摘自官方文档)

3.在lucene4.x 之前,solr采用NRTManager实现NRT,之后使用ControlledRealTimeReopenThread实现,它通过IndexWriter对象来监控内存中的文档变化,从而得到最新的文档信息,该过程既不需要高耗时的I/O操作,也不需要刷新搜索器,所以非常之快,耗费资源很少
4.所以 近实时搜索(NRT)是软提交的一个特性
5.同样的软提交也支持自动提交的方式,配置如下

5.这 两种提交方式并不冲突 ,试想我们程序使用了软提交,但何时可以把数据真正同步到磁盘呢?这时候就可以两者结合达到目的

我们设置每隔5000ms进行一次软提交,文档存入了内存,也可以实时搜索,然后每隔300000ms又会进行进行一次硬提交,同步到磁盘,无需刷新Searcher,如此两者兼顾
6.在配置文件中配置后,在客户端就不需要维护提交方式和提交时间了

1.很多人说由于软提交不及时写入硬盘,所以在jvm崩溃时会丢失部分数据,但其实不会,因为软提交和硬提交在commit时都会记录下操作log,若发生崩溃,会在重启时会从log恢复,这点很像mysql的事务日志操作
2.若maxDocs和maxTime都配置了,则那个条件先到就按那个执行,官方建议使用maxTime,因为solr文档较多,通常更新量也大,使用maxTime可能更能减少提交的频次,但在此建议根据实际情况来决定
3.commit操作后,可执行optimize操作,该操作会合并索引碎片,合并后索引性能会有所提升,但该操作消耗较大,每晚定时操作一次即可

JSON方式提交文档时SOLR报:AtomicUpdateDocumentMerger Unknown operation for the an atomic update, operation ig

文档是数组转成的json

原数组:

array(
  0 =>3,
  1 =>3,
  2 =>4,
  3 =>5,
  4 =>5,
  5 =>6
)

用array_unique去掉数组中重复的元素后,插入时报错。

原因:

  array_unique去重之后,原数组的下标被保留了。数组为

array(
  0 =>3,
  2 =>4,
  3 =>5,
  5 =>6
)

在json_encode数组时,会把下标不连续的数组解析成json字符串例如{"0":"3","2":"4","3":"5","5":6}。期望的是{["3","4","5","6"]}。造成这个报错的原因是下标不连续。需重组一下索引,因此在array_unique之后,再执行array_values,将数组的下标重排列。这样,在向solr的update handler 提交时就不会被认为是在做原子更新了。













以上是关于Solr的提交方式的主要内容,如果未能解决你的问题,请参考以下文章

Solr搜索引擎索引提交事务日志原子更新

选择 solr/lucene 提交策略

JSON方式提交文档时SOLR报:AtomicUpdateDocumentMerger Unknown operation for the an atomic update, operation ig

触发所有待处理文档的 SOLR 提交的最简单方法(URL?)?

在solr 6.4.2上提交数据时遇到问题

向Solr数据集提交Json格式数据(Scala,Post)