@Override protected final void writerSegmentStats(SegmentsStats stats) { stats.addVersionMapMemoryInBytes(versionMap.ramBytesUsed()); stats.addIndexWriterMemoryInBytes(indexWriter.ramBytesUsed()); stats.addIndexWriterMaxMemoryInBytes( (long) (indexWriter.getConfig().getRAMBufferSizeMB() * 1024 * 1024)); }
@Override public void writeIndexingBuffer() throws EngineException { // we obtain a read lock here, since we don't want a flush to happen while we are writing // since it flushes the index as well (though, in terms of concurrency, we are allowed to do it) try (ReleasableLock lock = readLock.acquire()) { ensureOpen(); // TODO: it's not great that we secretly tie searcher visibility to "freeing up heap" here... // really we should keep two // searcher managers, one for searching which is only refreshed by the schedule the user // requested (refresh_interval, or invoking // refresh API), and another for version map interactions. See #15768. final long versionMapBytes = versionMap.ramBytesUsedForRefresh(); final long indexingBufferBytes = indexWriter.ramBytesUsed(); final boolean useRefresh = versionMapRefreshPending.get() || (indexingBufferBytes / 4 < versionMapBytes); if (useRefresh) { // The version map is using > 25% of the indexing buffer, so we do a refresh so the version // map also clears logger.debug( "use refresh to write indexing buffer (heap size=[{}]), to also clear version map (heap size=[{}])", new ByteSizeValue(indexingBufferBytes), new ByteSizeValue(versionMapBytes)); refresh("write indexing buffer"); } else { // Most of our heap is used by the indexing buffer, so we do a cheaper (just writes // segments, doesn't open a new searcher) IW.flush: logger.debug( "use IndexWriter.flush to write indexing buffer (heap size=[{}]) since version map is small (heap size=[{}])", new ByteSizeValue(indexingBufferBytes), new ByteSizeValue(versionMapBytes)); indexWriter.flush(); } } catch (AlreadyClosedException e) { ensureOpen(); maybeFailEngine("writeIndexingBuffer", e); } catch (EngineClosedException e) { throw e; } catch (Throwable t) { failEngine("writeIndexingBuffer failed", t); throw new RefreshFailedEngineException(shardId, t); } }
@Override public long getIndexBufferRAMBytesUsed() { return indexWriter.ramBytesUsed() + versionMap.ramBytesUsedForRefresh(); }