You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
Client Side Caching (#2947)
* CSC POC ontop of Parser * add csc file that weren't merged after patch * address review comments * nits to try and fix github * last change from review * Update client-side cache and improve documentation * Add client side caching RESP3 validation * Add documentation for RESP and unstableResp3 options * Add comprehensive cache statistics The `CacheStats` class provides detailed metrics like hit/miss counts, load success/failure counts, total load time, and eviction counts. It also offers derived metrics such as hit/miss rates, load failure rate, and average load penalty. The design is inspired by Caffeine. `BasicClientSideCache` now uses a `StatsCounter` to accumulate these statistics, exposed via a new `stats()` method. The previous `cacheHits()` and `cacheMisses()` methods have been removed. A `recordStats` option (default: true) in `ClientSideCacheConfig` allows disabling statistics collection. --------- Co-authored-by: Shaya Potter <shaya@redislabs.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { ChannelListeners, PUBSUB_TYPE, PubSubTypeListeners } from '../client/pu
|
||||
import { RedisArgument, RedisFunctions, RedisModules, RedisScripts, RespVersions, TypeMapping } from '../RESP/types';
|
||||
import calculateSlot from 'cluster-key-slot';
|
||||
import { RedisSocketOptions } from '../client/socket';
|
||||
import { BasicPooledClientSideCache, PooledClientSideCacheProvider } from '../client/cache';
|
||||
|
||||
interface NodeAddress {
|
||||
host: string;
|
||||
@@ -111,6 +112,7 @@ export default class RedisClusterSlots<
|
||||
replicas = new Array<ShardNode<M, F, S, RESP, TYPE_MAPPING>>();
|
||||
readonly nodeByAddress = new Map<string, MasterNode<M, F, S, RESP, TYPE_MAPPING> | ShardNode<M, F, S, RESP, TYPE_MAPPING>>();
|
||||
pubSubNode?: PubSubNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
clientSideCache?: PooledClientSideCacheProvider;
|
||||
|
||||
#isOpen = false;
|
||||
|
||||
@@ -118,12 +120,28 @@ export default class RedisClusterSlots<
|
||||
return this.#isOpen;
|
||||
}
|
||||
|
||||
#validateOptions(options?: RedisClusterOptions<M, F, S, RESP, TYPE_MAPPING>) {
|
||||
if (options?.clientSideCache && options?.RESP !== 3) {
|
||||
throw new Error('Client Side Caching is only supported with RESP3');
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
options: RedisClusterOptions<M, F, S, RESP, TYPE_MAPPING>,
|
||||
emit: EventEmitter['emit']
|
||||
) {
|
||||
this.#validateOptions(options);
|
||||
this.#options = options;
|
||||
this.#clientFactory = RedisClient.factory(options);
|
||||
|
||||
if (options?.clientSideCache) {
|
||||
if (options.clientSideCache instanceof PooledClientSideCacheProvider) {
|
||||
this.clientSideCache = options.clientSideCache;
|
||||
} else {
|
||||
this.clientSideCache = new BasicPooledClientSideCache(options.clientSideCache)
|
||||
}
|
||||
}
|
||||
|
||||
this.#clientFactory = RedisClient.factory(this.#options);
|
||||
this.#emit = emit;
|
||||
}
|
||||
|
||||
@@ -164,6 +182,8 @@ export default class RedisClusterSlots<
|
||||
}
|
||||
|
||||
async #discover(rootNode: RedisClusterClientOptions) {
|
||||
this.clientSideCache?.clear();
|
||||
this.clientSideCache?.disable();
|
||||
try {
|
||||
const addressesInUse = new Set<string>(),
|
||||
promises: Array<Promise<unknown>> = [],
|
||||
@@ -219,6 +239,7 @@ export default class RedisClusterSlots<
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
this.clientSideCache?.enable();
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
@@ -314,6 +335,8 @@ export default class RedisClusterSlots<
|
||||
#createClient(node: ShardNode<M, F, S, RESP, TYPE_MAPPING>, readonly = node.readonly) {
|
||||
return this.#clientFactory(
|
||||
this.#clientOptionsDefaults({
|
||||
clientSideCache: this.clientSideCache,
|
||||
RESP: this.#options.RESP,
|
||||
socket: this.#getNodeAddress(node.address) ?? {
|
||||
host: node.host,
|
||||
port: node.port
|
||||
|
Reference in New Issue
Block a user