Skip to content

Commit 1fb0d58

Browse files
committed
feat: add dynamic cache limit for snapshot repository data based on heap size
- `opensearch.snapshot.cache.size.percentage` JVM flag to adjust cache size as a percentage of heap. - Default remains 500KB to minimize impact on existing users. Signed-off-by: inpink <[email protected]>
1 parent 6f1b59e commit 1fb0d58

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
3333
- Add support for restoring from snapshot with search replicas ([#16111](https://github.com/opensearch-project/OpenSearch/pull/16111))
3434
- Add logic in master service to optimize performance and retain detailed logging for critical cluster operations. ([#14795](https://github.com/opensearch-project/OpenSearch/pull/14795))
3535
- Add Setting to adjust the primary constraint weights ([#16471](https://github.com/opensearch-project/OpenSearch/pull/16471))
36+
- Add dynamic cache limit for snapshot repository data based on heap size ([#16489](https://github.com/opensearch-project/OpenSearch/pull/16489))
3637

3738
### Dependencies
3839
- Bump `com.azure:azure-identity` from 1.13.0 to 1.13.2 ([#15578](https://github.com/opensearch-project/OpenSearch/pull/15578))

server/src/main/java/org/opensearch/repositories/blobstore/BlobStoreRepository.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3050,12 +3050,15 @@ private void cacheRepositoryData(BytesReference updated, long generation) {
30503050
try {
30513051
serialized = CompressorRegistry.defaultCompressor().compress(updated);
30523052
final int len = serialized.length();
3053-
if (len > ByteSizeUnit.KB.toBytes(500)) {
3053+
long dynamicCacheSizeLimit = determineCacheSizeLimit();
3054+
3055+
if (len > dynamicCacheSizeLimit) {
30543056
logger.debug(
3055-
"Not caching repository data of size [{}] for repository [{}] because it is larger than 500KB in"
3057+
"Not caching repository data of size [{}] for repository [{}] because it is larger than [{}] bytes in"
30563058
+ " serialized size",
30573059
len,
3058-
metadata.name()
3060+
metadata.name(),
3061+
dynamicCacheSizeLimit
30593062
);
30603063
if (len > ByteSizeUnit.MB.toBytes(5)) {
30613064
logger.warn(
@@ -3083,6 +3086,22 @@ private void cacheRepositoryData(BytesReference updated, long generation) {
30833086
}
30843087
}
30853088

3089+
protected long determineCacheSizeLimit() {
3090+
final String cacheSizeProperty = System.getProperty("opensearch.snapshot.cache.size.percentage");
3091+
long defaultCacheSizeLimit = ByteSizeUnit.KB.toBytes(500);
3092+
3093+
if (Strings.hasLength(cacheSizeProperty)) {
3094+
long maxHeapSize = Runtime.getRuntime().maxMemory();
3095+
double cacheSizeRatio = Double.parseDouble(cacheSizeProperty) / 100.0;
3096+
3097+
long heapBasedCacheSize = (long) (maxHeapSize * cacheSizeRatio);
3098+
3099+
return Math.max(defaultCacheSizeLimit, heapBasedCacheSize);
3100+
}
3101+
3102+
return defaultCacheSizeLimit;
3103+
}
3104+
30863105
private RepositoryData repositoryDataFromCachedEntry(Tuple<Long, BytesReference> cacheEntry) throws IOException {
30873106
try (InputStream input = CompressorRegistry.defaultCompressor().threadLocalInputStream(cacheEntry.v2().streamInput())) {
30883107
return RepositoryData.snapshotsFromXContent(

server/src/test/java/org/opensearch/repositories/blobstore/BlobStoreRepositoryTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ public class BlobStoreRepositoryTests extends BlobStoreRepositoryHelperTests {
111111

112112
static final String REPO_TYPE = "fsLike";
113113

114+
static final String CACHE_SIZE_PROPERTY = "opensearch.snapshot.cache.size.percentage";
115+
114116
protected Collection<Class<? extends Plugin>> getPlugins() {
115117
return Arrays.asList(FsLikeRepoPlugin.class);
116118
}
@@ -653,4 +655,37 @@ public void testGetRestrictedSystemRepositorySettings() {
653655
assertTrue(settings.contains(BlobStoreRepository.REMOTE_STORE_INDEX_SHALLOW_COPY));
654656
repository.close();
655657
}
658+
659+
public void testCacheSizeUsesHeapPercentageWhenFlagEnabled() {
660+
// given
661+
BlobStoreRepository blobStoreRepository = setupRepo();
662+
double percentage = 1.5;
663+
System.setProperty(CACHE_SIZE_PROPERTY, String.valueOf(percentage));
664+
665+
long maxHeapSize = Runtime.getRuntime().maxMemory();
666+
double cacheSizeRatio = percentage / 100.0;
667+
long defaultCacheSize = 500 * 1024;
668+
long heapBasedCacheSize = (long) (maxHeapSize * cacheSizeRatio);
669+
long expectedCacheSize = Math.max(defaultCacheSize, heapBasedCacheSize);
670+
671+
// when
672+
long actualCacheSize = blobStoreRepository.determineCacheSizeLimit();
673+
674+
// then
675+
assertEquals(expectedCacheSize, actualCacheSize);
676+
}
677+
678+
public void testDefaultCacheSizeWhenFlagDisabled() {
679+
// given
680+
System.clearProperty(CACHE_SIZE_PROPERTY);
681+
682+
BlobStoreRepository blobStoreRepository = setupRepo();
683+
long expectedCacheSize = 500 * 1024;
684+
685+
// when
686+
long actualCacheSize = blobStoreRepository.determineCacheSizeLimit();
687+
688+
// then
689+
assertEquals(expectedCacheSize, actualCacheSize);
690+
}
656691
}

0 commit comments

Comments
 (0)