-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
429 additions
and
125 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
...netease/nim/camellia/redis/proxy/upstream/embedded/storage/cache/BytesSizeCalculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.netease.nim.camellia.redis.proxy.upstream.embedded.storage.cache; | ||
|
||
/** | ||
* Created by caojiajun on 2025/1/8 | ||
*/ | ||
public class BytesSizeCalculator implements SizeCalculator<byte[]> { | ||
|
||
@Override | ||
public long size(byte[] element) { | ||
return element.length; | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
...e/nim/camellia/redis/proxy/upstream/embedded/storage/cache/CacheCapacityConfigParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.netease.nim.camellia.redis.proxy.upstream.embedded.storage.cache; | ||
|
||
import com.netease.nim.camellia.redis.proxy.conf.ProxyDynamicConf; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* Created by caojiajun on 2025/1/8 | ||
*/ | ||
public class CacheCapacityConfigParser { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(CacheCapacityConfigParser.class); | ||
|
||
public static long parse(String configKey, String defaultValue) { | ||
String string = ProxyDynamicConf.getString(configKey, defaultValue).toUpperCase(); | ||
try { | ||
long bytes = bytes(string); | ||
if (bytes < 0) { | ||
logger.warn("illegal config = {} for config-key = {}, use default config = {}", string, configKey, defaultValue); | ||
} | ||
bytes = bytes(defaultValue); | ||
return bytes; | ||
} catch (Exception e) { | ||
logger.warn("error config = {} parse for config-key = {}, use default config = {}", string, configKey, defaultValue); | ||
return bytes(defaultValue); | ||
} | ||
} | ||
|
||
public static String toString(long capacity) { | ||
return (capacity / 1024 / 1024) + "M"; | ||
} | ||
|
||
private static long bytes(String string) { | ||
int size = Integer.parseInt(string.substring(string.length() - 2)); | ||
if (string.endsWith("M")) { | ||
return size * 1024 * 1024L; | ||
} else if (string.endsWith("G")) { | ||
return size * 1024 * 1024 * 1024L ; | ||
} | ||
return -1; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
...n/java/com/netease/nim/camellia/redis/proxy/upstream/embedded/storage/cache/CacheKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.netease.nim.camellia.redis.proxy.upstream.embedded.storage.cache; | ||
|
||
import com.netease.nim.camellia.redis.proxy.upstream.kv.cache.EstimateSizeValue; | ||
|
||
import java.util.Arrays; | ||
import java.util.Objects; | ||
|
||
/** | ||
* Created by caojiajun on 2025/1/8 | ||
*/ | ||
public record CacheKey(byte[] key) implements EstimateSizeValue { | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
CacheKey cacheKey = (CacheKey) o; | ||
return Objects.deepEquals(key, cacheKey.key); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Arrays.hashCode(key); | ||
} | ||
|
||
@Override | ||
public long estimateSize() { | ||
return key.length; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...nim/camellia/redis/proxy/upstream/embedded/storage/cache/EstimateSizeValueCalculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.netease.nim.camellia.redis.proxy.upstream.embedded.storage.cache; | ||
|
||
import com.netease.nim.camellia.redis.proxy.upstream.kv.cache.EstimateSizeValue; | ||
|
||
/** | ||
* Created by caojiajun on 2025/1/8 | ||
*/ | ||
public class EstimateSizeValueCalculator<T extends EstimateSizeValue> implements SizeCalculator<T> { | ||
|
||
@Override | ||
public long size(T element) { | ||
return element.estimateSize(); | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
...n/java/com/netease/nim/camellia/redis/proxy/upstream/embedded/storage/cache/LRUCache.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.netease.nim.camellia.redis.proxy.upstream.embedded.storage.cache; | ||
|
||
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; | ||
import com.netease.nim.camellia.redis.proxy.util.Utils; | ||
import com.netease.nim.camellia.tools.executor.CamelliaThreadFactory; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.Map; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* Created by caojiajun on 2025/1/8 | ||
*/ | ||
public class LRUCache<K, V> { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(LRUCache.class); | ||
|
||
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new CamelliaThreadFactory("lru-cache-scheduler")); | ||
|
||
private final String name; | ||
private final String configKey; | ||
private final SizeCalculator<K> keySizeCalculator; | ||
private final SizeCalculator<V> valueSizeCalculator; | ||
|
||
private String config; | ||
|
||
private final ConcurrentLinkedHashMap<K, V> cache; | ||
private long capacity; | ||
|
||
private int cacheSize; | ||
|
||
private int loop = 0; | ||
|
||
public LRUCache(String name, String configKey, String defaultConfig, int estimateSizePerKV, SizeCalculator<K> keySizeCalculator, SizeCalculator<V> valueSizeCalculator) { | ||
this.name = name; | ||
this.configKey = configKey; | ||
this.config = defaultConfig; | ||
this.keySizeCalculator = keySizeCalculator; | ||
this.valueSizeCalculator = valueSizeCalculator; | ||
this.capacity = CacheCapacityConfigParser.parse(configKey, defaultConfig); | ||
this.config = CacheCapacityConfigParser.toString(capacity); | ||
this.cacheSize = (int) (capacity / estimateSizePerKV); | ||
this.cache = new ConcurrentLinkedHashMap.Builder<K, V>() | ||
.initialCapacity(cacheSize) | ||
.maximumWeightedCapacity(cacheSize) | ||
.build(); | ||
scheduler.scheduleAtFixedRate(this::schedule, 10, 10, TimeUnit.SECONDS); | ||
} | ||
|
||
public void put(K key, V value) { | ||
cache.put(key, value); | ||
} | ||
|
||
public void delete(K key) { | ||
cache.remove(key); | ||
} | ||
|
||
public V get(K key) { | ||
return cache.get(key); | ||
} | ||
|
||
private void schedule() { | ||
this.capacity = CacheCapacityConfigParser.parse(configKey, config); | ||
this.config = CacheCapacityConfigParser.toString(capacity); | ||
long size = 0; | ||
long count = cache.size(); | ||
for (Map.Entry<K, V> entry : cache.entrySet()) { | ||
size += keySizeCalculator.size(entry.getKey()); | ||
size += valueSizeCalculator.size(entry.getValue()); | ||
} | ||
size += count * 8; | ||
if (size > capacity) { | ||
double ratio = size * 1.0 / capacity; | ||
cacheSize = (int) (count / ratio); | ||
this.cache.setCapacity(cacheSize); | ||
} else { | ||
if (count >= cacheSize) { | ||
double ratio = size * 1.0 / capacity; | ||
cacheSize = (int) (count / ratio); | ||
this.cache.setCapacity(cacheSize); | ||
} | ||
} | ||
loop ++; | ||
if (loop == 6) {//print log every 60s | ||
logger.info("lru-cache, name = {}, target.capacity = {}, current.estimate.size = {}, current.key.count = {}, current.key.max.count = {}", | ||
name, config, Utils.humanReadableByteCountBin(size), count, cacheSize); | ||
loop = 0; | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
.../com/netease/nim/camellia/redis/proxy/upstream/embedded/storage/cache/SizeCalculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.netease.nim.camellia.redis.proxy.upstream.embedded.storage.cache; | ||
|
||
/** | ||
* Created by caojiajun on 2025/1/8 | ||
*/ | ||
public interface SizeCalculator<T> { | ||
|
||
StringSizeCalculator STRING_INSTANCE = new StringSizeCalculator(); | ||
BytesSizeCalculator BYTES_INSTANCE = new BytesSizeCalculator(); | ||
|
||
long size(T element); | ||
} |
14 changes: 14 additions & 0 deletions
14
...etease/nim/camellia/redis/proxy/upstream/embedded/storage/cache/StringSizeCalculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.netease.nim.camellia.redis.proxy.upstream.embedded.storage.cache; | ||
|
||
/** | ||
* Created by caojiajun on 2025/1/8 | ||
*/ | ||
public class StringSizeCalculator implements SizeCalculator<String> { | ||
|
||
public static final BytesSizeCalculator INSTANCE = new BytesSizeCalculator(); | ||
|
||
@Override | ||
public long size(String element) { | ||
return element.length(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.