侦听来自 Redis 客户端跟踪(客户端-服务器缓存)的失效消息

时间:2021-04-05 08:39:12

标签: c# redis stackexchange.redis clientside-caching

StackExchange.Redis NuGet 包尚不支持 Redis 6 client-side caching feature,但似乎可以手动启用此功能。

我未能成功接收预期的失效消息。

在下面的示例代码中,建立了三个连接。

第一个连接用于订阅 __redis__:invalidate 以接收失效消息。

另外两个启用了客户端跟踪,并使用 REDIRECT 选项将失效消息重定向到第一个连接。 这是为了复制 RESP2 所需的协议。 假设(但我未确认)StackExchange.Redis 使用默认协议 RESP2 启动连接。

然后在两个客户端连接上设置密钥,以便 redis 服务器可以跟踪两者的密钥并发送失效消息。

最后,无限循环每秒更新 a ket。 第一个连接订阅了 __redis__:invalidate 通道,并且是其他两个客户端的重定向源。 预计将调用 OnMessage 处理程序并将失效消息打印到控制台,但是,这永远不会发生。

// connection 1 - used to receive invalidation messages
var redis1 = ConnectionMultiplexer.Connect("localhost:6379", Console.Out);
var db1 = redis1.GetDatabase();
var clientId1 = db1.Execute("CLIENT", "ID");

// connection 2 - used to test client tracking
var redis2 = ConnectionMultiplexer.Connect("localhost:6379", Console.Out);
var db2 = redis2.GetDatabase();
var clientId2 = db2.Execute("CLIENT", "ID");

// connection 3 - used to test client tracking
var redis3 = ConnectionMultiplexer.Connect("localhost:6379", Console.Out);
var db3 = redis2.GetDatabase();
var clientId3 = db2.Execute("CLIENT", "ID");

// subsribe to invalidation messages
redis1.GetSubscriber().Subscribe("__redis__:invalidate").OnMessage(message =>
{
    Console.WriteLine($"__redis__:invalidate: {message}");
});

// enable client tracking
Console.Write("db2 tracking: ");
Console.WriteLine(await db2.ExecuteAsync("CLIENT", "TRACKING", "ON", "REDIRECT", (string)clientId1));

Console.Write("db3 tracking: ");
Console.WriteLine(await db3.ExecuteAsync("CLIENT", "TRACKING", "ON", "REDIRECT", (string)clientId1));

// register keys to enable tracking
await db2.StringSetAsync("a", "Hi");
await db3.StringSetAsync("a", "Hey");

// test client tracking by updating of the keys
// it is expected that messages will be published by the server to the `__redis__:invalidate` channel
// the subscriber handler above, should print the invalidation message to the console
int i = 0;
while (!stoppingToken.IsCancellationRequested)
{
    db2.StringSet("a", $"A{i++}");
    Console.WriteLine(db3.StringGet("a"));

    //_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
    await Task.Delay(1000, stoppingToken);
}

有人知道如何使用 StackExchange.Redis 正确使用此功能吗?

更新

看起来 StackExchange.Redis 实际上创建了两个连接:一个用于数据库,一个用于订阅者。

因此,var clientId1 = db1.Execute("CLIENT", "ID"); 获取数据库连接的客户端 ID,而不是订阅者连接。

这意味着 db2.ExecuteAsync("CLIENT", "TRACKING", "ON", "REDIRECT", (string)clientId1) 正在设置重定向到错误的连接。

我还没有找到以编程方式获取订阅者的客户端 ID 的方法...

0 个答案:

没有答案