Solr的软提交与硬提交

Solr的软提交与硬提交

硬提交是关于持久化的,软提交是关于可见性的。硬提交和软提交是相关的概念,但是它们的目的是不一样的。这句话隐含了很多细节,我们将就其中一些进行阐明。首先是几个定义:

Transaction Log(Tlog)

记录了原始文档,用于索引恢复功能。在 SolrCloud 中,每个节点都有自己的 tlog。在更新的时候,整个文档会写入 tlog 中。Tlog 是保证一致性的关键,有了它,就算索引段(segment)关闭前 JVM 崩溃了,索引也不会丢失。

【注意】一旦服务器没有正常关闭,则重新启动时,tlog 会进行回放。因此,如果你的 tlog 很大(我们见过 GB 级别的 tlog),则重启会非常慢,例如几个小时才启动成功。

Hard commit

硬提交通过 solrconfig.xml 的选项来实现,或者客户端显式调用。硬提交会结束当前索引段的构建,并开启新的索引段的构建。

openSearcher

选项的子属性,用来控制新提交的数据是否能被后来的搜索操作检索到(是否可见)。

Soft commit

软提交是比硬提交(openSearcher=true)使文档可见的更轻量级的操作,而且软提交不会结束当前索引段的构建。

【注意】虽然软提交是轻量级的操作,但是也不是完全没有代价的。你应该使软提交的时间间隔尽可能长来保证更好的性能。

Fsynch

底层 IO 命令,当 fsynch 调用返回后,数据必定已写到了磁盘中。这个和 java 程序的 flush 是不一样的。java 的 flush 只是保证已经向操作系统提交了数据,操作系统并没有立刻写到磁盘中,而是在适当的时候才会真正写入磁盘。

Flush

java 程序把数据提交给操作系统。这个操作返回后,数据并没有真正落盘,如果操作系统崩溃了,数据有可能会丢失掉。

【注意】

特别是在 solrcloud,多于一个副本的情况下,所有副本同时挂掉,并且数据都没有落盘,才会发生数据丢失,这种情况是很少见的。

操作系统在 flush 命令后大概 10-50 毫秒就会把数据写入磁盘。如果 jvm 崩溃了,操作系统仍然会把数据写到磁盘,但是,如果是操作系统崩溃,而 IO 子系统又没来得及把数据刷到磁盘,则会丢失数据。

 

Transaction Logs

索引构建的流程如下:

写入的数据被一个节点接收,然后转交到正确的 leader 节点。

从那个 leader 节点发送到所有相关分片的所有副本。

所有副本索引完后回应 leader 节点。

leader 节点回应一开始的接收节点。

当所有的 leader 节点都回应之后,接收节点回应客户端,在这个点上,所有的数据都已经 flush 到了集群中的所有相关节点的 tlog 中

如果 jvm 崩溃了,文档也已经安全地写到了 tlog 中,但是,如果是操作系统奔溃,那就不一定了。如果 jvm 崩溃(或者 killed -9 杀掉),然后重启,tlog 会回放。

【注意】你可以修改 solrconfig.xml 里面的配置,在返回前用 fsynch 而不是 flush,但这样是没有必要的。所有 leaders 和 replicas 同时因为硬件挂掉而丢失数据的几率是很小的。有些场景,就算存在细微的几率丢失数据也是不允许的,则可以采用这种牺牲吞吐量的方式。

Soft commit

对于 soft commit 的理解是,它能使文档可见,但是会有一些代价。尤其是在 solrconfig.xml 里定义的顶层的 cache(filterCache、queryResultCache 等)会失效,autowarning 会在顶层 cache 发生(比如 filterCache、queryResultCache)。这时候,newSearcher 的查询都会被执行,而且,fieldvaluecache 也会失效,因此,facet 查询也不得不等 cache 重新生成。在频繁的 soft commit 下,cache 基本上没什么效果,在某些场景下,最好去掉它。然而,索引段级别的 cache(译者注:比如 fieldcache),用于 function 查询,排序等,是基于索引段的,因此不会因为 soft commit 而失效,它们能继续被使用。

【注意】soft commit 用来支持近实时搜索,但是是有代价的,因此,设置 soft commit 的时间间隔尽可能长,来获取更好的性能。

Hard commit

hard commit 是有关持久化的,softcommit 是有关可见性的。这里,还要分两种情况,openSearcher=true 和 openSearcher=false。首先,我会解析一下这两种情况下都会发生的事情。不管 openSearcher=true 还是 openSearcher=false,都会出现以下的结果:

tlog 会截断:当前 tlog 会关闭,一个新的 tlog 会开始,在已关闭的 tlog 中,如果较新的 tlog 超过了 100 个文档,则老的 tlog 会删除掉。

当前正在索引的索引段会关闭,并 flush。

可能会触发后台的段合并。

这些就是 hardcommit 一定会发生的事情,无论 openSearcher 怎样设置。

openSearcher=true:Solr/Lucene searchers 被重新打开,所有的 cache 都失效(译者注:索引段级别的 cache 不会失效),autowarming 会执行。这是老版本唯一能看到新增加的文档的方法。

openSearcher=false:除了以上四点以外没有其他动作了。如果要搜索新的文档,需要执行一次 soft commit。

总结

Hard commits are about durability, hard commit实际上是将tlog中的修改写入到Lucene index中。硬提交是提交数据持久化到磁盘里面,并且能够查询到这条数据。硬提交是提交数据持久化到磁盘里面,并且能够查询到这条数据。

<autoCommit>

    <!--表示软提交达到1万条的时候会自动进行一次硬提交-->
    <maxDocs>10000</maxDocs>

    <!--表示软提交10秒之后会执行一次硬提交-->
    <maxTime>10000</maxTime>

    <!--true表示每一次硬提交都开启一个新的Searcher-->
    <openSearcher>false</openSearcher>
</autoCommit>

软提交是提交数据到内存里面,并没有持久化到磁盘,但是他会把提交的记录写到tlog的日志文件里面

下面就是自动软提交的配置,不需要自己维护提交(默认没有开启):

<autoSoftCommit> 

  <!--5秒执行一次软提交-->
  <maxTime>5000</maxTime> 
</autoSoftCommit>

两者结合着使用,既能保证数据的完整性,又能确保速度。

常见的应用场景

  1. 大批量索引构建

假设你希望设置 soft commit 时间间隔足够长,比如 10 分钟或更长(配置为 -1 则不自动 soft commit)。soft commit 是有关可见性的,我想大批量索引构建应该不是为了满足实时搜索的,所以没必要额外地打开任何类型的 searcher。

设置 hard commit 时间间隔为 15 秒,openSearcher=false。重申一下,这里假设你只是为了把大量数据导入 solr,而不是为了实时搜索。这样设置,就是最坏的情况也只是当你重启,你最多只需要从 tlog 回放 15 秒的数据。如果你的系统频繁重启,则先找到频繁重启的原因。把大批量的数据尽可能快地写入系统,将来用于搜索。比如,数据源的初始化。

一般是一些不常见的做法,它们包括:

+ 在批量索引时完全关闭tlog。

+ 离线构建索引,比如mapreduce方式构建索引。

+ 在构建索引时,每个分片只有一个leader节点,没有副本,构建完成后,再开启副本,让它们进行传统的复制来保持一致。注意,这个是自动实现的,如果副本发现和leader相差太远,就会触发传统的复制。复制完成后,它会继续接受leader节点的文档,并保存到自己的tlog中。

  1. 索引更新很频繁,检索请求量很少

比如,日志检索。这个场景下,每天有大量的日志要写进来,但是检索请求却很少,主要用作故障排除和日志分析。

设置 soft commit 时间间隔足够长,设置为你能忍受新文档不可见的最长时间。这可能是几分钟或更长。甚至几个小时,直到执行一次 hard commit(openSearcher=true)或 soft commit。

设置 hard commit(openSearcher=false)的时间间隔为 15 秒。

  1. 索引更新很频繁,检索请求量大

这是近实时搜索的场景,是最复杂的场景,这需要有较多的经验,我是这样做的

设置 soft commit 的时间间隔为你能忍受的最大长度。不要听信你的产品经理的话“我需要不超过 1 秒钟的延迟”。时间间隔从长到短,逐渐尝试,看看用户服务是否满足,是否用户注意到了延迟,直到找到一个合适的值。soft commit 和近实时搜索非常好用,但是并非没有代价的。

设置 hardcommit 的时间间隔为 15 秒。


 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/FullStackDeveloper0/article/details/86589028