From d88e2a449cf8ca8732abdc574c3c010240cd6210 Mon Sep 17 00:00:00 2001 From: naveenaechan Date: Mon, 4 Dec 2023 15:31:02 +0530 Subject: [PATCH] PLT-191: added cache config --- docs/configs/janusgraph-cfg.md | 3 ++ .../org/janusgraph/diskstorage/Backend.java | 37 +++++++++---------- .../cache/ExpirationKCVSRedisCache.java | 6 ++- .../keycolumnvalue/cache/RedissonCache.java | 6 +-- .../GraphDatabaseConfiguration.java | 12 ++++++ 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/docs/configs/janusgraph-cfg.md b/docs/configs/janusgraph-cfg.md index 54ab0deb55..ef199e3020 100644 --- a/docs/configs/janusgraph-cfg.md +++ b/docs/configs/janusgraph-cfg.md @@ -33,7 +33,10 @@ Configuration options that modify JanusGraph's caching behavior | cache.redis-cache-sentinel-urls | csv values for multiple redis sentinel host:port urls. | String | localhost:26379 | MASKABLE | | cache.redis-cache-server-mode | Redis connection mode, either single or sentinel connection | String | single | MASKABLE | | cache.redis-cache-server-url | Redis server url. | String | localhost:6379 | MASKABLE | +| cache.redis-cache-size | Maximum cache (map) size in redis, set 0 to unbound, default value is 100. Keys are evicted based on LFU mode. | Integer | 100 | MASKABLE | | cache.redis-cache-username | Username for Redis authentication. | String | default | MASKABLE | +| cache.redis-client-name | Redis client name | String | janusgraph | MASKABLE | +| cache.redis-db-id | Redis database id, usually can be set between 0 - 15 range. | Integer | 1 | MASKABLE | | cache.tx-cache-size | Maximum size of the transaction-level cache of recently-used vertices. | Integer | 20000 | MASKABLE | | cache.tx-dirty-size | Initial size of the transaction-level cache of uncommitted dirty vertices. This is a performance hint for write-heavy, performance-sensitive transactional workloads. If set, it should roughly match the median vertices modified per transaction. | Integer | (no default value) | MASKABLE | diff --git a/janusgraph-core/src/main/java/org/janusgraph/diskstorage/Backend.java b/janusgraph-core/src/main/java/org/janusgraph/diskstorage/Backend.java index 6dd203f8b4..29f030eb67 100644 --- a/janusgraph-core/src/main/java/org/janusgraph/diskstorage/Backend.java +++ b/janusgraph-core/src/main/java/org/janusgraph/diskstorage/Backend.java @@ -330,33 +330,32 @@ public void initialize(Configuration config) { Preconditions.checkArgument(expirationTime>=0,"Invalid cache expiration time: %s",expirationTime); if (expirationTime==0) expirationTime=ETERNAL_CACHE_EXPIRATION; - long cacheSizeBytes; - double cacheSize = configuration.get(DB_CACHE_SIZE); - Preconditions.checkArgument(cacheSize>0.0,"Invalid cache size specified: %s",cacheSize); - if (cacheSize<1.0) { - //Its a percentage - Runtime runtime = Runtime.getRuntime(); - cacheSizeBytes = (long)((runtime.maxMemory()-(runtime.totalMemory()-runtime.freeMemory())) * cacheSize); - } else { - Preconditions.checkArgument(cacheSize>1000,"Cache size is too small: %s",cacheSize); - cacheSizeBytes = (long)cacheSize; - } - log.info("Configuring total store cache size: {}",cacheSizeBytes); + long cleanWaitTime = configuration.get(DB_CACHE_CLEAN_WAIT); - Preconditions.checkArgument(EDGESTORE_CACHE_PERCENT + INDEXSTORE_CACHE_PERCENT == 1.0,"Cache percentages don't add up!"); - long edgeStoreCacheSize = Math.round(cacheSizeBytes * EDGESTORE_CACHE_PERCENT); - long indexStoreCacheSize = Math.round(cacheSizeBytes * INDEXSTORE_CACHE_PERCENT); String cacheType = configuration.get(CACHE_TYPE); if(REDIS_TAG.equals(cacheType)){ log.info("======== Configuring redis cache ========"); edgeStore = new ExpirationKCVSRedisCache(edgeStoreRaw,getMetricsCacheName(EDGESTORE_NAME)!=null?getMetricsCacheName(EDGESTORE_NAME) - :"edgeStore",expirationTime,cleanWaitTime, - edgeStoreCacheSize, configuration); + :"edgeStore",expirationTime,cleanWaitTime, configuration); indexStore = new ExpirationKCVSRedisCache(indexStoreRaw,getMetricsCacheName(INDEXSTORE_NAME)!=null? - getMetricsCacheName(INDEXSTORE_NAME):"indexStore",expirationTime,cleanWaitTime, - indexStoreCacheSize, configuration); + getMetricsCacheName(INDEXSTORE_NAME):"indexStore",expirationTime,cleanWaitTime, configuration); }else{ + long cacheSizeBytes; + double cacheSize = configuration.get(DB_CACHE_SIZE); + Preconditions.checkArgument(cacheSize>0.0,"Invalid cache size specified: %s",cacheSize); + if (cacheSize<1.0) { + //Its a percentage + Runtime runtime = Runtime.getRuntime(); + cacheSizeBytes = (long)((runtime.maxMemory()-(runtime.totalMemory()-runtime.freeMemory())) * cacheSize); + } else { + Preconditions.checkArgument(cacheSize>1000,"Cache size is too small: %s",cacheSize); + cacheSizeBytes = (long)cacheSize; + } + Preconditions.checkArgument(EDGESTORE_CACHE_PERCENT + INDEXSTORE_CACHE_PERCENT == 1.0,"Cache percentages don't add up!"); + long edgeStoreCacheSize = Math.round(cacheSizeBytes * EDGESTORE_CACHE_PERCENT); + long indexStoreCacheSize = Math.round(cacheSizeBytes * INDEXSTORE_CACHE_PERCENT); + log.info("Configuring total store cache size: {}",cacheSizeBytes); log.info("======== Configuring inmemory cache ========"); edgeStore = new ExpirationKCVSCache(edgeStoreRaw,getMetricsCacheName(EDGESTORE_NAME),expirationTime,cleanWaitTime,edgeStoreCacheSize); indexStore = new ExpirationKCVSCache(indexStoreRaw,getMetricsCacheName(INDEXSTORE_NAME),expirationTime,cleanWaitTime,indexStoreCacheSize); diff --git a/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/ExpirationKCVSRedisCache.java b/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/ExpirationKCVSRedisCache.java index d719de14ae..760334d2b7 100644 --- a/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/ExpirationKCVSRedisCache.java +++ b/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/ExpirationKCVSRedisCache.java @@ -27,6 +27,7 @@ import org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction; import org.janusgraph.diskstorage.util.CacheMetricsAction; import org.nustaq.serialization.FSTConfiguration; +import org.redisson.api.EvictionMode; import org.redisson.api.RLock; import org.redisson.api.RMapCache; import org.redisson.api.RedissonClient; @@ -41,6 +42,7 @@ import java.util.logging.Logger; import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.CACHE_KEYSPACE_PREFIX; +import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.REDIS_MAX_CACHE_SIZE; /** * @author naveenaechan @@ -56,7 +58,7 @@ public class ExpirationKCVSRedisCache extends KCVSCache { private static FSTConfiguration fastConf = FSTConfiguration.createDefaultConfiguration(); public ExpirationKCVSRedisCache(final KeyColumnValueStore store, String metricsName, final long cacheTimeMS, - final long invalidationGracePeriodMS, final long maximumByteSize, Configuration configuration) { + final long invalidationGracePeriodMS, Configuration configuration) { super(store, metricsName); Preconditions.checkArgument(cacheTimeMS > 0, "Cache expiration must be positive: %s", cacheTimeMS); Preconditions.checkArgument(System.currentTimeMillis() + 1000L * 3600 * 24 * 365 * 100 + cacheTimeMS > 0, "Cache expiration time too large, overflow may occur: %s", cacheTimeMS); @@ -66,7 +68,7 @@ public ExpirationKCVSRedisCache(final KeyColumnValueStore store, String metricsN redissonClient = RedissonCache.getRedissonClient(configuration); redisCache = redissonClient.getMapCache(String.join("-", configuration.get(CACHE_KEYSPACE_PREFIX), metricsName)); redisIndexKeys = redissonClient.getMapCache(String.join("-", configuration.get(CACHE_KEYSPACE_PREFIX), REDIS_INDEX_CACHE_PREFIX, metricsName)); - + redisCache.setMaxSize(configuration.get(REDIS_MAX_CACHE_SIZE), EvictionMode.LFU); logger.info("********************** Configurations are loaded **********************"); } diff --git a/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/RedissonCache.java b/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/RedissonCache.java index fbbf66b78e..6053a4be81 100644 --- a/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/RedissonCache.java +++ b/janusgraph-core/src/main/java/org/janusgraph/diskstorage/keycolumnvalue/cache/RedissonCache.java @@ -33,7 +33,6 @@ public class RedissonCache { private static final Logger log = LoggerFactory.getLogger(RedissonCache.class); private static final String REDIS_URL_PREFIX = "redis://"; private static final String COMMA = ","; - private static final String JANUSGRAPH_REDIS = "janusgraph-redis"; private static final String SENTINEL = "sentinel"; private static final String STANDALONE = "single"; private static String redisServerMode; @@ -52,7 +51,8 @@ public static RedissonClient getRedissonClient(Configuration configuration) { case SENTINEL: config.setLockWatchdogTimeout(watchdogTimeoutInMS) .useSentinelServers() - .setClientName(JANUSGRAPH_REDIS) + .setDatabase(configuration.get(REDIS_DATABASE_ID)) + .setClientName(configuration.get(REDIS_CLIENT_NAME)) .setReadMode(ReadMode.MASTER_SLAVE) .setCheckSentinelsList(false) .setConnectTimeout(connectTimeout) @@ -65,7 +65,7 @@ public static RedissonClient getRedissonClient(Configuration configuration) { case STANDALONE: config.setLockWatchdogTimeout(watchdogTimeoutInMS) .useSingleServer() - .setClientName(JANUSGRAPH_REDIS) + .setClientName(configuration.get(REDIS_CLIENT_NAME)) .setAddress(formatUrls(configuration.get(REDIS_CACHE_SERVER_URL).split(COMMA))[0]) .setConnectTimeout(connectTimeout) .setKeepAlive(keepAlive) diff --git a/janusgraph-core/src/main/java/org/janusgraph/graphdb/configuration/GraphDatabaseConfiguration.java b/janusgraph-core/src/main/java/org/janusgraph/graphdb/configuration/GraphDatabaseConfiguration.java index ef18bd19ec..e58a7e28e2 100644 --- a/janusgraph-core/src/main/java/org/janusgraph/graphdb/configuration/GraphDatabaseConfiguration.java +++ b/janusgraph-core/src/main/java/org/janusgraph/graphdb/configuration/GraphDatabaseConfiguration.java @@ -406,6 +406,18 @@ public boolean apply(@Nullable String s) { "Enables TCP keepAlive for connection.", ConfigOption.Type.MASKABLE, true); + public static final ConfigOption REDIS_DATABASE_ID = new ConfigOption<>(CACHE_NS,"redis-db-id", + "Redis database id, usually can be set between 0 - 15 range.", + ConfigOption.Type.MASKABLE, 1); + + public static final ConfigOption REDIS_CLIENT_NAME = new ConfigOption<>(CACHE_NS,"redis-client-name", + "Redis client name", + ConfigOption.Type.MASKABLE, "janusgraph"); + + public static final ConfigOption REDIS_MAX_CACHE_SIZE = new ConfigOption<>(CACHE_NS,"redis-cache-size", + "Maximum cache (map) size in redis, set 0 to unbound, default value is 100. Keys are evicted based on LFU mode.", + ConfigOption.Type.MASKABLE, 100); + /** * The size of the database level cache. * If this value is between 0.0 (strictly bigger) and 1.0 (strictly smaller), then it is interpreted as a