在Solr中有两种方式索引数据:硬提交和软提交。html
软提交是在Solr4.0开始,增长的一个新功能。java
那么为何须要软提交呢?咱们先在这里简单介绍一下,后续有详细介绍软提交和硬提交的区别。SolrJ方法apache
没有软提交以前咱们提交索引是这么实现的:缓存
client = new HttpSolrClient("http://localhost:8080/solr/"); //简写
SolrinputDocurnent doc= new SolrinputDocurnent() ;
doc.addF工eld(fieldName , fieldValue) ;
client .add(doc) ;
client.commit();
复制代码
经过上述代码咱们能够看到,咱们每次添加一下索引,都要commit()一下,这个操做极其耗费资源,平均耗时600毫秒。服务器
因此咱们改用另外一种方式来进行提交——软提交。ide
硬提交是关于持久化的,软提交是关于可见性的。函数
硬提交是将数据持久化到磁盘里面,而且可以查询到这条数据。post
硬提交能够经过客户端显式调用实现,也能够经过在solrconfig.xml配置文件中添加相关配置实现。性能
为了达到灵活提交目的,Solr为硬提交和软提交设计了自动提交策略,自动提交主要靠maxDocs和maxTime两个参数控制,maxTime参数表示每间隔多少毫秒就触发一次索引提交,maxDocs表示当队列中累计了多少个索引文档就触发一次索引提交。两个条件只要知足其中之一便可。优化
硬提交使用事务日志来获取最新的Document ID,同时对索引文件调用fsync方法确保索引数据写入到磁盘,而且保证即使在断电的极端状况下也不会形成数据丢失。
硬提交它会要求全部的段文件必须当即合并为一个段文件,并重写整个索引,这个操做执行开销很大,不能执行太频繁。段文件合并应该合理配置合并策略,并按期执行索引优化,提高查询性能。
<!-- 自动(硬)提交策略 -->
<!-- autoCommit是硬提交, 开启后会进行以下操做: -->
<!-- 生成一个新的tlog文件, 删除旧的tlog文件; -->
<!-- 把内存中缓存的文档fsync(OS内部的函数)到磁盘中, 并建立一个index descriptor, 用来记录各个文档的存储位置;此时就算JVM奔溃或系统宕机, 也不影响这部分数据, 不利之处是: 占用资源较多; -->
<!-- 若是<openSearcher>true</openSearcher>, 就会打开查询器, 让这次硬提交的文档可供搜索. -->
<autoCommit>
<!-- 多少个文档提交一次: 要添加的文档数达到此值时自动触发新的提交 -->
<maxDocs>${solr.autoCommit.maxDocs:1000}</maxDocs>
<!-- 多少毫秒提交一次: 添加文档操做的时间持续到此值时自动触发新的提交, 与maxDocs配置其一便可 -->
<maxTime>${solr.autoCommit.maxTime:1000}</maxTime>
<!-- 若是为false, 提交操做会将最近的更改信息刷新到磁盘, 但不会当即打开查询器 - 也就是说客户端查询不到; 实时性要求高的项目, 须要设置为true - 在6.0以后的版本中默认为true -->
<openSearcher>true</openSearcher>
</autoCommit>
复制代码
软提交并无将数据持久化到硬盘上,只是将更新的索引数据对查询请求可见。
<!-- 软提交策略,配置后会进行以下操做 -->
<!-- 把内存中缓存的文档fsync(OS内部的函数)到磁盘中, 但不会建立index descriptor——也就是说各个文档的真实存储位置并无被记录下来; -->
<!-- 打开文档查询器, 涉及到的索引数据能够被查询到——近实时(NRT)更好; -->
<!-- 软提交不会等待后台合并、整理文档等操做, 只确保了修改的可见行, 没有获取到文档的具体存储位置 —— 也就是说若是此时JVM奔溃或系统宕机, 就找不到这些数据了. -->
<!-- 软提交比硬提交更快, 更能作到近实时查询, 可是若是服务器不稳定, 或JVM奔溃, 会致使提交的数据没法被检索到. -->
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
</autoSoftCommit>
复制代码
Transaction Log:事务日志,记录了原始文档,用于索引恢复功能。 此处未完待续………………
<!-- The default high-performance update handler -->
<!-- 更新处理器 -->
<!-- Solr默认使用的高可用的updateHandler是下面这个: -->
<updateHandler class="solr.DirectUpdateHandler2">
<!-- 索引库的事务日志 -->
<!-- 默认路径: ${SOLR_HOME}/data/tlog. -->
<!-- 启用事务日志用于实时查询、持久化索引数据、Solr Cloud中副本的恢复... -->
<!-- 随着索引库的频繁更新, tlog日志文件会愈来愈大, 因此建议提交索引时采用硬提交 - 即批量提交的方式 - hard autoCommit. -->
<updateLog>
<!-- dir: 事务日志的存储目录 -->
<str name="dir">${solr.data.dir:}</str>
</updateLog>
<maxPendingDeletes>100000</maxPendingDeletes>
<autoCommit>
<maxDocs>${solr.autoCommit.maxDocs:1000}</maxDocs>
<maxTime>${solr.autoCommit.maxTime:1000}</maxTime>
<openSearcher>true</openSearcher>
</autoCommit>
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
</autoSoftCommit>
</updateHandler>
复制代码
在Lucene中,索引提交分两个阶段提交,prepareCommit操做属于第一个阶段。第一个阶段会作一些准备工做,好比将队列中待添加和标记为待删除的索引文档刷新到索引文件中,而后同步索引文件、建立并写入段文件,当第一阶段执行完以后,须要显式调用commit结束提交操做,或者调用rollback去回滚提交操做。若是直接调用commit。那么内部会隐式的先调用prepareCommit。