.NET Core 實現 Redis 批量查詢指定格式的Key

一. 問題場景

Redis 作為當前最流行的內存型 NoSQL 數據庫,被許多公司所使用,作為分佈式緩存。我們在實際使用中一般都會為 key 帶上指定的前綴或者其他定義的格式。當由於我們程序出現bug,造成 redis 裡面的存儲的值,與我們預期的不一致時,我們可以通過查詢指定格式的 key,來定位到我們具體的出現問題的key,從而方便我們解決問題。

二. 解決辦法

1.Keys 命令

Keys 命令用於查找所有符合給定模式 pattern 的 key 。要求 Redis 版本大於 1.0.0。keys在查詢大數量key時,會長時間阻塞Redis,由於Redis是單線程的,這就是一個突出的問題,需要注意。

2.Scan 命令

Scan 命令相對於 Keys 命令來說,優點就是不會阻塞服務器。要求 Redis 版本大於 2.8。

三. 代碼實現

這裡採用的Redis驅動是 StackExchange.Redis。

在 StackExchange.Redis 裡封裝 Redis 命令時分為了兩種,一種是針對於集群的命令,一種是針對於單個Redis服務器的命令,Keys 和 Scan 命令便是後者,我們在使用的時候必須在單獨的服務器上執行。

Keys 和 Scan 命令都支持模糊查詢,這裡介紹三種匹配符:

  1. * 表示可以匹配多個任意字符
  2. ? 表示可以匹配單個任意字符
  3. [] 表示可以匹配指定範圍內的字符

因為我們的key可能分佈在集群內多個Redis服務器上,所以我們需要在每臺服務器上都執行命令。我們可以通過 ConnectionMultiplexer.GetEndPoints() 方法來獲取所有的終結點信息。

在 StackExchange.Redis 對於 keys 和 scan 命令統一封裝為了 IServer.Keys()方法,它會自動根據Redis服務器版本來決定使用keys命令還是scan命令。

為了方便測試,我在 Redis 裡面準備了四個以 test 為前綴的key,放在序號為1的db裡面:

.NET Core 實現 Redis 批量查詢指定格式的Key

1.遍歷所有前綴為 test 的key 代碼如下:

static async Task Main(string[] args)
{
//創建連接
var conn = await ConnectionMultiplexer.ConnectAsync("192.168.10.110");
//獲取db
var db = conn.GetDatabase(1);
//遍歷集群內服務器
foreach (var endPoint in conn.GetEndPoints())
{
//獲取指定服務器
var server = conn.GetServer(endPoint);
//在指定服務器上使用 keys 或者 scan 命令來遍歷key
foreach (var key in server.Keys(1,"test.*"))
{
//獲取key對於的值
var val = db.StringGet(key);
Console.WriteLine($"key: {key}, value: {val}");
}
}
}

執行結果:

.NET Core 實現 Redis 批量查詢指定格式的Key

2.[]的用法

假設我要遍歷 key為 test.1-test.3 的數據,可以這樣寫:

static async Task Main(string[] args)
{
//創建連接
var conn = await ConnectionMultiplexer.ConnectAsync("192.168.10.110");
//獲取db
var db = conn.GetDatabase(1);
//遍歷集群內服務器
foreach (var endPoint in conn.GetEndPoints())
{
//獲取指定服務器
var server = conn.GetServer(endPoint);
//在指定服務器上使用 keys 或者 scan 命令來遍歷key
foreach (var key in server.Keys(1,"test.[1-3]"))
{
//獲取key對於的值
var val = db.StringGet(key);
Console.WriteLine($"key: {key}, value: {val}");
}
}
}

執行結果:

.NET Core 實現 Redis 批量查詢指定格式的Key

假設我要遍歷 key為 test.1和test.4 的數據,可以這樣寫:

static async Task Main(string[] args)
{
//創建連接
var conn = await ConnectionMultiplexer.ConnectAsync("192.168.10.110");
//獲取db
var db = conn.GetDatabase(1);
//遍歷集群內服務器
foreach (var endPoint in conn.GetEndPoints())
{
//獲取指定服務器
var server = conn.GetServer(endPoint);
//在指定服務器上使用 keys 或者 scan 命令來遍歷key
foreach (var key in server.Keys(1,"test.[1,4]"))
{
//獲取key對於的值
var val = db.StringGet(key);
Console.WriteLine($"key: {key}, value: {val}");
}
}
}

執行結果:

.NET Core 實現 Redis 批量查詢指定格式的Key

好了,關於 Redis 查詢指定格式的 key 的方法就介紹到這裡了


分享到:


相關文章: