Closed tky753 closed 1 year ago
If not, does FreeRedis
support independent server for receiving key expire message from redis
提供测试 demo
var cli = new RedisClient("192.168.1.9:6379,password=xxxxxx,defaultDatabase=xx");
bool CheckExpired(string key, DateTime dt) => DateTime.Now.Subtract(dt) > TimeSpan.FromSeconds(5);
bool KeyFilter(string key) => key.StartsWith("k");
cli.UseClientSideCaching(new ClientSideCachingOptions
{
//本地缓存的容量
Capacity = 3,
//过滤哪些键能被本地缓存
KeyFilter = KeyFilter,
//检查长期未使用的缓存
CheckExpired = CheckExpired
});
const string script = """
local rst = redis.call('HSETNX', KEYS[1], 'absexp', ARGV[1])
if rst ~= 1 then
return rst
end
redis.call('HSET', KEYS[1], 'sldexp', ARGV[2], 'data', ARGV[4])
if ARGV[3] ~= '-1' then
redis.call('EXPIRE', KEYS[1], ARGV[3])
end
return 1
""";
var rst = cli.Eval(script, new[] { "key" }, 1, 1, 5, "{}");
var d1 = cli.HMGet("key");
Thread.Sleep(TimeSpan.FromSeconds(1));
var d2 = cli.HMGet("key"); //should use client side cache
If I invoke this function,
void ClientTracking(bool on_off, long? redirect, string[] prefix, bool bcast, bool optin, bool optout, bool noloop)
how can i receive tracked information?
如果我没记错,ClientSideCaching 只针对 strings 类型。
hash 及其他复合类型不支持。
如果我没记错,ClientSideCaching 只针对 strings 类型。
hash 及其他复合类型不支持。
我尝试这样调用
var cli = new RedisClient("192.168.1.9:6379,password=xxxxxx,defaultDatabase=xx");
bool CheckExpired(string key, DateTime dt)
{
return DateTime.Now.Subtract(dt) > TimeSpan.FromSeconds(1);
}
bool KeyFilter(string key)
{
return key.StartsWith("k");
}
cli.UseClientSideCaching(new ClientSideCachingOptions
{
//本地缓存的容量
Capacity = 3,
//过滤哪些键能被本地缓存
KeyFilter = KeyFilter,
//检查长期未使用的缓存
CheckExpired = CheckExpired
});
cli.HSet("k:1", "f1", "v");
cli.Expire("k:1", 10);
var h = cli.HGet("k:1", "f1");
然后在FreeRedis\src\FreeRedis\ClientSideCaching.cs
的
void InValidate(string chan, object msg)
{
if (msg == null)
{
//flushall
lock (_dictLock) _dictSort.Clear();
_dict.Clear();
return;
}
var keys = msg as object[];
if (keys != null)
{
foreach (var key in keys)
RemoveCache(string.Concat(key));
}
}
这个方法设断点,在10秒后,我发现是会调用到InValidate
这个方法的
能否在InValidate方法内 触发一个事件,让使用者可以进行一定程度地自定义处理expire key事件 比如我已经自定义了一个InMemoryCache,想要在用它来存储 client side cache,这样我只需要一个InValidate事件就够了。 不需要FreeRedis默认的UseClientSideCaching实现
能否提供一个例子,我想要用
client tracking on bcast prefix 前缀
这种方式来使用 client side caching,
用freeredis应该怎么写?
我尝试这样写:
cli.ClientTracking(true, null, new []{"k"}, true, false, false, false);
cli.Subscribe("__redis__:invalidate", InValidate);
void InValidate(string chan, object msg)
{
_output.WriteLine($"{chan}:{JsonSerializer.Serialize(msg)}");
}
但是收不到消息,是不是因为redirect
传空了?
成了:
var sub = cli.Subscribe("__redis__:invalidate", InValidate) as IPubSubSubscriber;
cli.ClientTracking(true, sub.RedisSocket.ClientId, new []{"k"}, true, false, false, false);
上面的写法有个严重的问题:调用 HSet,调用Expire 以及真expire时 都会触发一次 __redis__:invalidate
要改成这样写就只在 真expire 的时候触发一次了:
var sub = cli.Subscribe("__redis__:invalidate", InValidate) as IPubSubSubscriber;
cli.ClientTracking(true, sub.RedisSocket.ClientId, new []{"k"}, true, false, false, true);
区别就是ClientTracking
最后那个参数 noloop要设置为true
I use script something like
to set cache data. And I need to use HMGET to get data, Now I want to use redis 6 client side caching to cache
'data': ARGV[4]
, does FreeRedis support this?