本文承接文档的增删改(上)、文档的增删改(中)、继续介绍文档的增删改,为了能深入理解,还是得先介绍下几个预备知识。
预备知识
DocumentsWriterStallControl
在文档的增删改(中)我们知道,多线程(持有相同的IndexWriter对象的引用)执行添加/更新操作时,每个线程都会获取一个ThreadState,每次执行完一次添加/更新的后,如果持有的DWPT对象收集的索引信息没有达到flush的要求,该索引信息的大小会被累加到activeBytes,否则会被累加到flushBytes中,并且执行flush操作,这种方式即 添加/更新和flush为异步操作。
异步操作即某些ThreadState执行添加/更新,而其他ThreadState执行flush,故可能会存在 添加/更新的速度一直快于flush的情况,导致内存中堆积索引信息,那么很容 易出现OOM的错误。所以DocumentsWriterStallControl类就是用来通过阻塞添加/更新的操作来保证写入(indexing)的健康度(This class used to block incoming indexing threads if flushing significantly slower than indexing to ensure the healthiness)
满足下面的条件时需要阻塞添加/更新的操作:
(activeBytes + flushBytes) > limit && activeBytes < limit
其中limit的值为 2*ramBufferSizeMB,ramBufferSizeMB描述了索引信息被写入到磁盘前暂时缓存在内存中允许的最大使用内存值。
如何阻塞执行添加/更新操作的线程:
- wait(1000):等待1秒的方法来实现阻塞,源码中的注释给出了使用这种方式的原因: Defensive, in case we have a concurrency bug that fails to .notify/All our thread, just wait for up to 1 second here, and let caller re-stall if it's still needed
- stall:该值是一个对所有线程可见的变量,当stall的值为true,那么需要执行阻塞
看这里:https://www.amazingkoala.com.cn/Lucene/Index/2019/0701/70.html