簡介
說明
本文介紹Redis模糊查詢的方法。
官網網址
https://redis.io/commands/keys/
https://redis.io/commands/scan/
Redis模糊查詢鍵的方法
Redis提供了兩種模糊查詢鍵的方法:KEYS , SCAN。推薦用SCAN,下邊會介紹。
模糊查詢的通配符
KEYS和SCAN都支援glob通配符中的三個:*,?,[]:
- *:通配任意多個字元
- ?:通配單個字元
- []:通配括号内的某一個字元
示例
- h?llo
- 比對 hello, hallo and hxllo
- h*llo
- 比對 hllo、heeeello
- h[ae]llo
- 比對 hello、hallo
- 不比對 hillo
- h[^e]llo
- 比對 hallo、hbllo…
- 不比對 hello
- h[a-b]llo 比對 hallo and hbllo
KEYS
說明
KEYS指令會一次性查出所有滿足條件的key(沒有 offset、limit 參數)。keys 算法是周遊算法,複雜度是 O(n)。
資料量大時會有問題:redis 是單線程的,操作都是原子的,如果執行個體中有千萬級以上的 key,這個指令就會導緻 Redis 服務卡頓,所有讀寫 Redis 的其它的指令都會被延後甚至會逾時報錯,可能會引起緩存雪崩甚至資料庫當機。
指令格式
KEYS pattern
pattern即key的正規表達式。
示例
先寫入一些資料:
192.168.xxx.21:6379[2]> set hello 1
OK
192.168.xxx.21:6379[2]> set word 1
OK
192.168.xxx.21:6379[2]> set hellp 1
OK
192.168.xxx.21:6379[2]> set ahellog 1
OK
192.168.xxx.21:6379[2]> set hellog 1
OK
查詢:
192.168.xxx.21:6379[2]> keys *
1) "hello"
2) "hellog"
3) "hellp"
4) "word"
5) "ahellog"
192.168.xxx.21:6379[2]> keys *hell*
1) "hello"
2) "hellog"
3) "hellp"
4) "ahellog"
192.168.xxx.21:6379[2]> keys hell*
1) "hello"
2) "hellog"
3) "hellp"
//知道前面的一些字母,忘記了最後一個字母
192.168.xxx.21:6379[2]> keys hell?
1) "hello"
2) "hellp"
//知道前面的一些字母,忘記了最後兩個個字母
192.168.xxx.21:6379[2]> keys hell??
1) "hellog"
//知道前面四個字母,最後一個字母有可能是p t y 其中的一個
192.168.xxx.21:6379[2]> keys hell[pty]
1) "hellp"
192.168.xxx.21:6379[2]>
SCAN
說明
Redis 2.8版本引入,目标是解決keys指令的一些問題,特點:
- 複雜度O(n),通過遊标分步進行的,不會阻塞線程;
- 提供 limit 參數,可以設定每次傳回結果的資料量,limit隻是對增量式疊代指令的hint,傳回的結果可多可少;
- 支援模式比對功能;
- 伺服器不需要為遊标儲存狀态,遊标的唯一狀态就是 scan 傳回給用戶端的遊标整數;
- 傳回的結果可能會有重複,需要用戶端去重複;
- 無法提供完整的快照周遊,即周遊過程中若有資料修改,改動後的資料可能周遊不到;每次傳回的資料條數不一定,極度依賴内部實作;
- 單次傳回的結果是空的并不意味着周遊結束,而要看傳回的遊标值是否為零
SCAN不是從第一維數組的第 0 位一直周遊到末尾,而是采用高位進位加法來周遊。之是以使用這樣特殊的方式進行周遊,是考慮到字典的擴容和縮容時避免槽位的周遊重複和遺漏。
指令格式
- cursor
- 遊标,當次周遊的起始位置
- pattern
- 與Keys指令中的patterns相同,支援通配符比對
- count
- 傳回資料條數。預設為10
- 如果MATCH選項沒有指定,則傳回條數可能大于等于這個數。因為Redis對全局哈希表的每個哈希槽進行周遊,一旦發現拿到的元素個數大于了count,就停止周遊。若一個桶裡有多個元素,這時傳回的元素就有可能多于count一點了。
- type:
- Redis 6.0 支援的參數,指定傳回Key的類型,類型可選值與 TYPE指令相同:string, list, set, zset, hash and stream。
示例
192.168.xxx.21:6379[2]> keys *
1) "hello"
2) "hellog"
3) "hellp"
4) "word"
5) "ahellog"
192.168.xxx.21:6379[2]> scan 0 match *ll* count 2
1) "5"
2) 1) "hellp"
2) "hello"
192.168.xxx.21:6379[2]> scan 5 match *ll* count 2
1) "0"
2) 1) "hellog"
2) "ahellog"
192.168.xxx.21:6379[2]>