solr 的commit, soft commit等
来源:互联网 发布:java测试工程师面试 编辑:程序博客网 时间:2024/05/18 16:39
背景
最近又被soft commit 和 hard commit搞得有点迷糊,其实都怪自己没有早点看源代码。问题出自这段代码,这也是我一开始接触solr时,查到的代码sample(事实证明问题都出在这里,引以为戒,有问题真的不要不求甚解)
if (rs.next()){ while (true) { NiuniuSolrInputDocument doc = new NiuniuSolrInputDocument(rs); docs.add(doc); idx++; if(idx>=1000){ httpSolrServer.add(docs); httpSolrServer.commit(); docs.clear(); idx = 0; } if (!rs.next()) break; } if(idx!=0){ httpSolrServer.add(docs); httpSolrServer.commit(); }}
问题
可以看到我每次执行完add方法以后,都会commit一下,认为只有commit过后文档才会真正的提交。如果按照这个思路走,批量建索引等可能问题不算大,但是如果研究solrconfig的autoCommit和autoSoftCommit就会有问题了。
问题来了,如果有autoCommit那我为毛要手动commit?
事实是,每次执行httpSolrServer.add(docs)
方法,就会进行如下工作:
public UpdateResponse add(Iterator<SolrInputDocument> docIterator) throws SolrServerException, IOException { UpdateRequest req = new UpdateRequest(); req.setDocIterator(docIterator); return req.process(this); }
即add方法已经把文档加入到solr中了,只要你的solr设置过autoCommit,那么每隔一段时间或者每当累积的文档到达一定数量,就会进行一次commit。而如果我们每次添加文档都手动commit,就会新开一个searcher,那么就会报“maxWarmingSearchers exceeded limit”,因为你的配置文件里配置了searcher的上限,每个searcher是需要占内存的,你不能开太多,也没有必要开太多,这样就可以理解后续的问题了。
hard commit AND soft commit
看了manual里的autoCommit和autoSoftCommit的介绍,autoCommit就是自动commit,这里的commit指的是hard commit,里面有几个参数:
maxDocs:add到solr缓冲区的文档数量超过这个值时,自动执行commit把结果写入到磁盘索引文件中
maxTime:最长多久执行一次commit,即如果文档一直没有通过commit沉淀到磁盘上,那么持久性就可能出问题,所以要隔一段时间就执行一次commit
openSearcher:要不要新开一个searcher,如果要新开,那么目前已有的cache就会失效,具体代码可以看SolrIndexSearcher,它里面有几个Cache成员变量,如果你新建立一个searcher那么cache失效也是正常的了,除非你有autoWarming机制
上面提到了hard commit,那么对应的就是softCommit,softCommit和NRTCachingDirectoryFactory息息相关。NRT是Near Realtime的缩写,即近实时的索引方式。
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
solr.NRTCachingDirectoryFactory, the default,
wraps solr.StandardDirectoryFactory and caches small files in memory
for better NRT performance.
solr.RAMDirectoryFactory is memory based, not persistent, and doesn't work with replication
这个有什么用呢?淘宝的增量商品架构走的就是这种方式,解释一下用它的理由:
- 用户增量添加商品,我们需要让这些增量商品尽早能被检索到
- 按照标准的索引文件的格式,文档想要被检索到就需要改写磁盘上的文件,频繁的改写带来了难以接受的IO开销
- 那么我们需要一种折中的方案,可以先把这部分增量放到内存中,这也是cache的意思,在检索时会去索引文件和内存中都去查询,这样的话就能实时把文档检索到,同时不会太频繁的更新磁盘
- 放在内存而不是磁盘就意味着存在persistence的问题,如果服务crash,内存中的文档就会丢失,这个时候我们就需要autoCommit了。
所以如果我们面临的是heavy index和heavy query的场景,需要在提交后就能立马检索到,就需要对每次增量都进行soft commit,然后设置一个我们能够容忍的时间interval或者数量上限,定时或者定量去执行一次hard commit,这样即使系统crash我们也只会丢失这个时间段的文档,而之前的文档已经都持久化了。而如果能够容忍提交后隔20秒才能搜索到,那么就设置autoSoftCommit参数为20000就好了,这样add到index中的文档每隔20s就会自动softCommit一次,就能被检索到了。
最终方案,我们把UpdateHandler的参数设置成:
<autoCommit> <maxTime>600000</maxTime> <openSearcher>true</openSearcher></autoCommit><autoSoftCommit> <maxTime>5000</maxTime></autoSoftCommit>
然后在增量提交文档时,不需要指定commit或者softCommit,新的文档会根据autoSoftCommit来自动进行软提交,然后会根据autoCommit来自定进行hard commit,这样新添加的文档在5秒之内就可以被检索到,然后每隔10分钟,这些文档就会写到磁盘上。这里注意,operSearcher一定要是true,不然用的是旧的cache的话,新的文档还是没办法被检索到。 curl
http://localhost:8080/solr/niuniu_resource/update?softCommit=true -H "Content-Type: text/xml" --data-binary
'
<add>
<doc>
<field name="raw_id">123478</field>
</doc>
</add>
'
参考
Understanding Solr Soft Commits and Data Durability
Understanding Transaction Logs, Soft Commit and Commit in SolrCloud
Uploading Data with Index Handlers
UpdateHandlers in SolrConfig
- solr 的commit, soft commit等
- Commit
- Solr通过配置自动Commit
- solr之commit和softcommit
- solr之commit和softcommit
- Solr 中的commit与optimize
- 如何使SOLR系统自动AUTO COMMIT?
- solr中commit和opimize理解
- COMMIT的过程
- FastDB的commit
- oracle数据库的commit
- 有关svn的commit
- 关于oracle的commit
- SharedPreferences 的commit问题
- oracle的commit
- commit的误解
- 删除git的commit
- oracle的commit详解
- 他人AS项目导入自己AS中的替换方法
- 登陆输入为空或错误时的提示信息
- String、StringBuffer与StringBuilder之间区别
- Bom和Dom的基本使用
- Java中的数组和方法
- solr 的commit, soft commit等
- win7下安装 Ubuntu双系统(直接硬盘安装)错误问题完美解决,卡屏,无法启动
- log4j按不同级别输出到日志文件
- BottomSheet
- openwrt STA+AP共存模式
- 套接字socket
- angularJS常用的表单验证指令
- Unity3d AssetPostprocessor简单用法
- Android WebView JS交互 混淆打包需要注意的问题