主頁(yè) > 知識(shí)庫(kù) > redis keys與scan命令的區(qū)別說(shuō)明

redis keys與scan命令的區(qū)別說(shuō)明

熱門(mén)標(biāo)簽:服務(wù)外包 地方門(mén)戶網(wǎng)站 百度競(jìng)價(jià)排名 呼叫中心市場(chǎng)需求 網(wǎng)站排名優(yōu)化 AI電銷 鐵路電話系統(tǒng) Linux服務(wù)器

redis keys和scan的區(qū)別

redis的keys命令,通常在用來(lái)刪除相關(guān)key時(shí)使用,但這個(gè)命令有一個(gè)弊端,在redis擁有數(shù)百萬(wàn)及以上的keys時(shí),執(zhí)行速度會(huì)比較慢,更致命的是,這個(gè)命令會(huì)阻塞redis多路復(fù)用的io主線程,如果這個(gè)線程阻塞,在此期間,其他發(fā)向redis服務(wù)端的命令,都會(huì)被阻塞,從而引發(fā)一系列級(jí)聯(lián)反應(yīng),導(dǎo)致瞬間相應(yīng)卡頓,從而引發(fā)超時(shí)等問(wèn)題,所以應(yīng)該在生產(chǎn)環(huán)境禁止用使用keys和類似的命令smembers,這種時(shí)間復(fù)雜度為O(N),且會(huì)阻塞主線程的命令,是非常危險(xiǎn)的。

如果在生產(chǎn)環(huán)境上,我們有需要查找然后刪除key的需求,我們應(yīng)該使用scan命令,來(lái)替代key。scan也是O(N)復(fù)雜度,支持通配查找key的命令,不同keys的是它采用的是游標(biāo)按批次迭代返回?cái)?shù)據(jù),可以不用阻塞主線程。

scan:漸進(jìn)式遍歷鍵

SCAN cursor [MATCH pattern] [COUNT count]

scan 參數(shù)提供了三個(gè)參數(shù)(6.0后增加了一個(gè)type參數(shù),具體看官方文檔),第一個(gè)是 cursor 整數(shù)值(hash桶的索引值),第二個(gè)是 key 的正則模式,第三個(gè)是一次遍歷的key的數(shù)量(參考值,底層遍歷的數(shù)量不一定),并不是符合條件的結(jié)果數(shù)量。

第一次遍歷時(shí),cursor 值為 0,然后將返回結(jié)果中第一個(gè)整數(shù)值作為下一次遍歷的 cursor。

一直遍歷到返回的 cursor 值為 0 時(shí)結(jié)束。

使用案例如下:

從運(yùn)行結(jié)果,我們可以看出幾個(gè)問(wèn)題:

雖然我們指定了掃描的count是10,但它實(shí)際掃描出來(lái)的數(shù)量不一定是10

scan他可能遍歷出重復(fù)的key

這邊解釋一下,為什么掃描出來(lái)得數(shù)量不一定是10。這是因?yàn)閙atch實(shí)際上相當(dāng)于過(guò)濾器的作用,所以scan其實(shí)是先掃描10個(gè)元素出來(lái),然后再根據(jù)pattern一過(guò)濾,那么剩下來(lái)的滿足條件元素就可能沒(méi)有10個(gè)了,甚至可能一個(gè)都沒(méi)有。

此外呢,如果在scan的過(guò)程中有鍵的變化(增加、刪除、修改),那么新增的鍵可能不會(huì)被遍歷出來(lái),即scan不能保證完整的遍歷出所有的鍵,這是我們開(kāi)發(fā)的時(shí)候需要考慮的。

關(guān)于更多的細(xì)節(jié),比如為什么新增的鍵可能不能被遍歷出來(lái),等我后面更深入的學(xué)習(xí)了redis底層的數(shù)據(jù)結(jié)構(gòu)在回來(lái)補(bǔ)充。

總之,對(duì)于redis的大數(shù)量操作,很難做到很精確。

補(bǔ)充:redis模糊查詢keys和scan的比較和用法

一、keys

1、語(yǔ)法

keys pattern 

2、說(shuō)明

redis中允許模糊查詢的有3個(gè)通配符,分別是:*,?,[]

*:通配任意多個(gè)字符

?:通配單個(gè)字符

[]:通配括號(hào)內(nèi)的某一個(gè)字符

3、操作

192.168.230.21:6379[2]> set hello 1
OK
192.168.230.21:6379[2]> set word 1
OK
192.168.230.21:6379[2]> set hellp 1
OK
192.168.230.21:6379[2]> set ahellog 1
OK
192.168.230.21:6379[2]> set hellog 1
OK
192.168.230.21:6379[2]> keys *
1) "hello"
2) "hellog"
3) "hellp"
4) "word"
5) "ahellog"
192.168.230.21:6379[2]> keys *hell*
1) "hello"
2) "hellog"
3) "hellp"
4) "ahellog"
192.168.230.21:6379[2]> keys hell*
1) "hello"
2) "hellog"
3) "hellp"
//知道前面的一些字母,忘記了最后一個(gè)字母
192.168.230.21:6379[2]> keys hell?
1) "hello"
2) "hellp"
//知道前面的一些字母,忘記了最后兩個(gè)個(gè)字母
192.168.230.21:6379[2]> keys hell??
1) "hellog"
//知道前面四個(gè)字母,最后一個(gè)字母有可能是p t y 其中的一個(gè)
192.168.230.21:6379[2]> keys hell[pty]
1) "hellp"
192.168.230.21:6379[2]> 

二、scan

1、語(yǔ)法

SCAN cursor [MATCH pattern] [COUNT count]

2、說(shuō)明

scan 游標(biāo) MATCH 給定模式相匹配的元素> count 每次迭代所返回的元素?cái)?shù)量 ,SCAN 命令是增量的循環(huán),每次調(diào)用只會(huì)返回一小部分的元素。scan會(huì)返回兩個(gè)結(jié)果,一個(gè)是用于下次遍歷的游標(biāo),一個(gè)是結(jié)果集;

SCAN 命令是一個(gè)基于游標(biāo)的迭代器(cursor based iterator): SCAN 命令每次被調(diào)用之后, 都會(huì)向用戶返回一個(gè)新的游標(biāo), 用戶在下次迭代時(shí)需要使用這個(gè)新游標(biāo)作為 SCAN 命令的游標(biāo)參數(shù), 以此來(lái)延續(xù)之前的迭代過(guò)程。

當(dāng) SCAN 命令的游標(biāo)參數(shù)被設(shè)置為 0 時(shí), 服務(wù)器將開(kāi)始一次新的迭代, 而當(dāng)服務(wù)器向用戶返回值為 0 的游標(biāo)時(shí), 表示迭代已結(jié)束

3、操作

192.168.230.21:6379[2]> keys *
1) "hello"
2) "hellog"
3) "hellp"
4) "word"
5) "ahellog"
192.168.230.21:6379[2]> scan 0 match *ll* count 2
1) "5"
2) 1) "hellp"
 2) "hello"
192.168.230.21:6379[2]> scan 5 match *ll* count 2
1) "0"
2) 1) "hellog"
 2) "ahellog"
192.168.230.21:6379[2]> 

三、性能對(duì)比

1、我們?cè)讷@取redis里面的某個(gè)db里面的所有數(shù)據(jù)可以用 `keys `這樣的指令來(lái)實(shí)現(xiàn)。但是存在一個(gè)問(wèn)題就是這樣做的話,在數(shù)據(jù)量很大的情況下效率是很不理想的;

2、Keys模糊匹配,請(qǐng)大家在實(shí)際運(yùn)用的時(shí)候忽略掉。因?yàn)镵eys會(huì)引發(fā)Redis鎖,并且增加Redis的CPU占用,情況是很惡劣的;如果數(shù)據(jù)龐大的話可能需要幾秒或更長(zhǎng),對(duì)于生產(chǎn)服務(wù)器上鎖定幾秒這絕對(duì)是災(zāi)難了;

3、新的命令SCAN出現(xiàn),它可以幫助我們解決因?yàn)橛胟eys遍歷大數(shù)據(jù)量的數(shù)據(jù)庫(kù)而導(dǎo)致服務(wù)器阻塞的情況,因?yàn)樗看味贾槐憷恍〔糠謹(jǐn)?shù)據(jù),每次操作對(duì)應(yīng)的時(shí)間復(fù)雜度是O(1);

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • Redis遍歷所有key的兩個(gè)命令(KEYS 和 SCAN)
  • 解決spring中redistemplate不能用通配符keys查出相應(yīng)Key的問(wèn)題
  • 在RedisTemplate中使用scan代替keys指令操作
  • Redis的KEYS 命令千萬(wàn)不能亂用
  • Redis命令使用技巧之Keys的相關(guān)操作
  • Redis不使用 keys 命令獲取鍵值信息的方法
  • redis 用scan指令 代替keys指令(詳解)
  • 淺談Redis的keys命令到底有多慢

標(biāo)簽:蘭州 黃山 銅川 衡水 仙桃 湘潭 崇左 湖南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《redis keys與scan命令的區(qū)別說(shuō)明》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266