婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁(yè) > 知識(shí)庫(kù) > Redis的KEYS 命令千萬(wàn)不能亂用

Redis的KEYS 命令千萬(wàn)不能亂用

熱門(mén)標(biāo)簽:四川穩(wěn)定外呼系統(tǒng)軟件 b2b外呼系統(tǒng) 400電話辦理的口碑 廊坊外呼系統(tǒng)在哪買(mǎi) 高碑店市地圖標(biāo)注app 南京手機(jī)外呼系統(tǒng)廠家 臺(tái)灣電銷 一個(gè)地圖標(biāo)注多少錢(qián) 地圖標(biāo)注工廠入駐

KESY 命令

時(shí)間復(fù)雜度: O(N) , 假設(shè)Redis中的鍵名和給定的模式的長(zhǎng)度有限的情況下,N為數(shù)據(jù)庫(kù)中key的個(gè)數(shù)。

Redis Keys 命令用于查找所有符合給定模式 pattern 的 key

盡管這個(gè)操作的時(shí)間復(fù)雜度是 O(N), 但是常量時(shí)間相當(dāng)?shù)汀@?,在一個(gè)普通筆記本上跑Redis,掃描100萬(wàn)個(gè)key只要40毫秒。

命令格式 KEYS pattern

Warning: 生產(chǎn)環(huán)境使用 KEYS 命令需要非常小心。在大的數(shù)據(jù)庫(kù)上執(zhí)行命令會(huì)影響性能。這個(gè)命令適合用來(lái)調(diào)試和特殊操作,像改變鍵空間keyspace布局。不要在你的代碼中使用 KEYS 。如果你需要一個(gè)尋找鍵空間中的key子集,考慮使用SCAN 或 集合結(jié)構(gòu)sets。

支持的匹配模式 patterns:

  • h?llo 匹配 hello, hallo 和 hxllo
  • h*llo 匹配 hllo 和 heeeello
  • h[ae]llo 匹配 hello 和 hallo, 不匹配 hillo
  • h[^e]llo 匹配 hallo, hbllo, … 不匹配 hello
  • h[a-b]llo 匹配 hallo 和 hbllo

使用 \ 轉(zhuǎn)義你想匹配的特殊字符。

背景

1、Redis是單線程的,其所有操作都是原子的,不會(huì)因并發(fā)產(chǎn)生數(shù)據(jù)異常

2、使用高耗時(shí)的Redis命令是很危險(xiǎn)的,會(huì)占用唯一的一個(gè)線程的大量處理時(shí)間,導(dǎo)致所有的請(qǐng)求都被拖慢

場(chǎng)景

在生產(chǎn)環(huán)境中執(zhí)行 KEYS 命令的時(shí),因?yàn)镽edis是單線程的,KEYS 命令的性能隨著數(shù)據(jù)庫(kù)數(shù)據(jù)的增多而越來(lái)越慢,使用 KEYS 命令時(shí)會(huì)占用唯一的一個(gè)線程的大量處理時(shí)間,引發(fā)Redis阻塞并且增加Redis的CPU占用,導(dǎo)致所有的請(qǐng)求都被拖慢,可能造成Redis所在的服務(wù)器宕機(jī),情況是很惡劣的,在實(shí)際生產(chǎn)運(yùn)用的過(guò)程中請(qǐng)忽略掉。試想如果Redis阻塞超過(guò)10秒,如果有集群的場(chǎng)景,可能導(dǎo)致集群判斷Redis已經(jīng)故障,從而進(jìn)行故障切換。

如果所有的線程在Redis那取不到數(shù)據(jù),情況嚴(yán)重時(shí)可能會(huì)導(dǎo)致應(yīng)用程序出現(xiàn)雪崩的情況,一瞬間全去數(shù)據(jù)庫(kù)取數(shù)據(jù),數(shù)據(jù)庫(kù)就宕機(jī)了。

其他危險(xiǎn)命令

但凡發(fā)現(xiàn)時(shí)間復(fù)雜度為O(N)的命令,都要慎重,不要在生產(chǎn)上隨便使用。例如hgetall、lrange、smembers、zrange、sinter等命令,它們并非不能使用,但這些命令的時(shí)間復(fù)雜度都為O(N),使用這些命令需要明確N的值,否則也會(huì)出現(xiàn)緩存宕機(jī)。

1、flushdb 命令用于清空當(dāng)前數(shù)據(jù)庫(kù)中的所有 key

2、flushall 命令用于清空整個(gè) Redis 服務(wù)器的數(shù)據(jù)(刪除所有數(shù)據(jù)庫(kù)的所有 key )

3、config 客戶端連接后可配置服務(wù)器

如何禁用危險(xiǎn)命令

在redis.conf中,在SECURITY這一項(xiàng)中,新增以下配置禁用指定命令:

rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command KEYS ""

另外,對(duì)于flushall命令,需要設(shè)置配置文件中appendonly no,否則服務(wù)器是無(wú)法啟動(dòng)。

如果想要保留命令,但是不輕易使用,可以重命名命令來(lái)設(shè)定:

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

TIP:更改記錄到AOF文件或傳輸?shù)綇膶俜?wù)器的命令的名稱可能會(huì)導(dǎo)致問(wèn)題。

改良建議

一、如果有這種需求的話可以自己對(duì)鍵值做索引,比如把各種鍵值存到不同的set里面,分類建立索引,這樣就可以很快的得到數(shù)據(jù),但是這樣也存在一個(gè)明顯的缺點(diǎn),就是浪費(fèi)寶貴的空間,所以還是要合理考慮,當(dāng)然也可以想辦法,比如對(duì)于有規(guī)律的鍵值,可以存儲(chǔ)他們的始末值等等。

二、針對(duì)改良keys和smembers命令也可以使用scan命令

SCAN 命令

Redis從2.8版本開(kāi)始支持scan命令,可以用來(lái)分批次掃描Redis記錄,這樣肯定會(huì)導(dǎo)致整個(gè)查詢消耗的總時(shí)間變大,影響服務(wù)使用,但不會(huì)影響redis服務(wù)卡頓,SCAN命令的基本用法如下:

命令格式 SCAN cursor [MATCH pattern] [COUNT count]

SCAN 命令提供三個(gè)參數(shù),第一個(gè)是cursor(游標(biāo)),第二個(gè)是要匹配的正則,第三個(gè)是單次遍歷的槽位

SCAN 命令及其相關(guān)的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代(incrementally iterate)一集元素(a collection of elements):

  • SCAN 命令用于迭代當(dāng)前數(shù)據(jù)庫(kù)中的數(shù)據(jù)庫(kù)鍵。
  • SSCAN 命令用于迭代集合鍵中的元素。
  • HSCAN 命令用于迭代哈希鍵中的鍵值對(duì)。
  • ZSCAN 命令用于迭代有序集合中的元素(包括元素成員和元素分值)。

以上列出的四個(gè)命令都支持增量式迭代,它們每次執(zhí)行都只會(huì)返回少量元素,所以這些命令可以用于生產(chǎn)環(huán)境,而不會(huì)出現(xiàn)像 KEYS 命令、SMEMBERS 命令帶來(lái)的問(wèn)題 —— 當(dāng) KEYS 命令被用于處理一個(gè)大的數(shù)據(jù)庫(kù)時(shí),又或者 SMEMBERS 命令被用于處理一個(gè)大的集合鍵時(shí),它們可能會(huì)阻塞服務(wù)器達(dá)數(shù)秒之久。

不過(guò),增量式迭代命令也不是沒(méi)有缺點(diǎn)的:舉個(gè)例子,使用 SMEMBERS 命令可以返回集合鍵當(dāng)前包含的所有元素,但是對(duì)于 SCAN 這類增量式迭代命令來(lái)說(shuō),因?yàn)樵趯?duì)鍵進(jìn)行增量式迭代的過(guò)程中,鍵可能會(huì)被修改,所以增量式迭代命令只能對(duì)被返回的元素提供有限的保證(offer limited guarantees about the returned elements)。

因?yàn)?SCAN 、 SSCAN 、 HSCAN 和 ZSCAN 四個(gè)命令的工作方式都非常相似, 所以接下來(lái)會(huì)一并介紹這四個(gè)命令,但是要記?。?/p>

  • SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一個(gè)參數(shù)總是一個(gè)數(shù)據(jù)庫(kù)鍵。
  • 而 SCAN 命令則不需要在第一個(gè)參數(shù)提供任何數(shù)據(jù)庫(kù)鍵 —— 因?yàn)樗氖钱?dāng)前數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)庫(kù)鍵。

SCAN 命令的基本用法

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é)束。

以下是一個(gè) SCAN 命令的迭代過(guò)程示例:

redis 127.0.0.1:6379> scan 0
1) "17"
2) 1) "key:12"
 2) "key:8"
 3) "key:4"
 4) "key:14"
 5) "key:16"
 6) "key:17"
 7) "key:15"
 8) "key:10"
 9) "key:3"
 10) "key:7"
 11) "key:1"

redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
 2) "key:18"
 3) "key:0"
 4) "key:2"
 5) "key:19"
 6) "key:13"
 7) "key:6"
 8) "key:9"
 9) "key:11"

在上面這個(gè)例子中, 第一次迭代使用 0 作為游標(biāo), 表示開(kāi)始一次新的迭代。

第二次迭代使用的是第一次迭代時(shí)返回的游標(biāo), 也即是命令回復(fù)第一個(gè)元素的值 —— 17 。

從上面的示例可以看到, SCAN 命令的回復(fù)是一個(gè)包含兩個(gè)元素的數(shù)組, 第一個(gè)數(shù)組元素是用于進(jìn)行下一次迭代的新游標(biāo), 而第二個(gè)數(shù)組元素則是一個(gè)數(shù)組, 這個(gè)數(shù)組中包含了所有被迭代的元素。

在第二次調(diào)用 SCAN 命令時(shí), 命令返回了游標(biāo) 0 , 這表示迭代已經(jīng)結(jié)束, 整個(gè)數(shù)據(jù)集(collection)已經(jīng)被完整遍歷過(guò)了。

以 0 作為游標(biāo)開(kāi)始一次新的迭代, 一直調(diào)用 SCAN 命令, 直到命令返回游標(biāo) 0 , 我們稱這個(gè)過(guò)程為一次完整遍歷(full iteration)。

SCAN 命令的保證(guarantees)

SCAN 命令, 以及其他增量式迭代命令, 在進(jìn)行完整遍歷的情況下可以為用戶帶來(lái)以下保證:從完整遍歷開(kāi)始直到完整遍歷結(jié)束期間, 一直存在于數(shù)據(jù)集內(nèi)的所有元素都會(huì)被完整遍歷返回;這意味著, 如果有一個(gè)元素, 它從遍歷開(kāi)始直到遍歷結(jié)束期間都存在于被遍歷的數(shù)據(jù)集當(dāng)中, 那么 SCAN 命令總會(huì)在某次迭代中將這個(gè)元素返回給用戶。

然而因?yàn)樵隽渴矫顑H僅使用游標(biāo)來(lái)記錄迭代狀態(tài), 所以這些命令帶有以下缺點(diǎn):

  • 同一個(gè)元素可能會(huì)被返回多次。處理重復(fù)元素的工作交由應(yīng)用程序負(fù)責(zé), 比如說(shuō), 可以考慮將迭代返回的元素僅僅用于可以安全地重復(fù)執(zhí)行多次的操作上。
  • 如果一個(gè)元素是在迭代過(guò)程中被添加到數(shù)據(jù)集的, 又或者是在迭代過(guò)程中從數(shù)據(jù)集中被刪除的, 那么這個(gè)元素可能會(huì)被返回, 也可能不會(huì), 這是未定義的(undefined)。

SCAN 命令每次執(zhí)行返回的元素?cái)?shù)量

增量式迭代命令并不保證每次執(zhí)行都返回某個(gè)給定數(shù)量的元素。

增量式命令甚至可能會(huì)返回零個(gè)元素, 但只要命令返回的游標(biāo)不是 0 , 應(yīng)用程序就不應(yīng)該將迭代視作結(jié)束。

不過(guò)命令返回的元素?cái)?shù)量總是符合一定規(guī)則的, 在實(shí)際中:

  • 對(duì)于一個(gè)大數(shù)據(jù)集來(lái)說(shuō), 增量式迭代命令每次最多可能會(huì)返回?cái)?shù)十個(gè)元素
  • 而對(duì)于一個(gè)足夠小的數(shù)據(jù)集來(lái)說(shuō), 如果這個(gè)數(shù)據(jù)集的底層表示為編碼數(shù)據(jù)結(jié)構(gòu)(encoded data structure,適用于是小集合鍵、小哈希鍵和小有序集合鍵), 那么增量迭代命令將在一次調(diào)用中返回?cái)?shù)據(jù)集中的所有元素。

最后, 用戶可以通過(guò)增量式迭代命令提供的 COUNT 選項(xiàng)來(lái)指定每次迭代返回元素的最大值。

COUNT 選項(xiàng)

雖然增量式迭代命令不保證每次迭代所返回的元素?cái)?shù)量, 但我們可以使用 COUNT 選項(xiàng), 對(duì)命令的行為進(jìn)行一定程度上的調(diào)整。

基本上, COUNT 選項(xiàng)的作用就是讓用戶告知迭代命令, 在每次迭代中應(yīng)該從數(shù)據(jù)集里返回多少元素。

雖然 COUNT 選項(xiàng)只是對(duì)增量式迭代命令的一種提示(hint), 但是在大多數(shù)情況下, 這種提示都是有效的。

  • COUNT 參數(shù)的默認(rèn)值為 10 。
  • 在迭代一個(gè)足夠大的、由哈希表實(shí)現(xiàn)的數(shù)據(jù)庫(kù)、集合鍵、哈希鍵或者有序集合鍵時(shí), 如果用戶沒(méi)有使用 MATCH 選項(xiàng), 那么命令返回的元素?cái)?shù)量通常和 COUNT 選項(xiàng)指定的一樣, 或者比 COUNT 選項(xiàng)指定的數(shù)量稍多一些。
  • 在迭代一個(gè)編碼為整數(shù)集合(intset,一個(gè)只由整數(shù)值構(gòu)成的小集合)、 或者編碼為壓縮列表(ziplist,由不同值構(gòu)成的一個(gè)小哈希或者一個(gè)小有序集合)時(shí), 增量式迭代命令通常會(huì)無(wú)視 COUNT 選項(xiàng)指定的值, 在第一次迭代就將數(shù)據(jù)集包含的所有元素都返回給用戶。

并非每次迭代都要使用相同的 COUNT 值

用戶可以在每次迭代中按自己的需要隨意改變 COUNT 值, 只要記得將上次迭代返回的游標(biāo)用到下次迭代里面就可以了

MATCH 選項(xiàng)

和 KEYS 命令一樣, 增量式迭代命令也可以通過(guò)提供一個(gè) glob 風(fēng)格的模式參數(shù), 讓命令只返回和給定模式相匹配的元素, 這一點(diǎn)可以通過(guò)在執(zhí)行增量式迭代命令時(shí), 通過(guò)給定 MATCH參數(shù)來(lái)實(shí)現(xiàn)。

以下是一個(gè)使用 MATCH 選項(xiàng)進(jìn)行迭代的示例:

redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood
(integer) 6

redis 127.0.0.1:6379> sscan myset 0 match f*
1) "0"
2) 1) "foo"
 2) "feelsgood"
 3) "foobar"

需要注意的是, 對(duì)元素的模式匹配工作是在命令從數(shù)據(jù)集中取出元素之后, 向客戶端返回元素之前的這段時(shí)間內(nèi)進(jìn)行的, 所以如果被迭代的數(shù)據(jù)集中只有少量元素和模式相匹配, 那么迭代命令或許會(huì)在多次執(zhí)行中都不返回任何元素。

以下是這種情況的一個(gè)例子:

redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"

redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)

redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)

redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)

redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2) 1) "key:611"
 2) "key:711"
 3) "key:118"
 4) "key:117"
 5) "key:311"
 6) "key:112"
 7) "key:111"
 8) "key:110"
 9) "key:113"
 10) "key:211"
 11) "key:411"
 12) "key:115"
 13) "key:116"
 14) "key:114"
 15) "key:119"
 16) "key:811"
 17) "key:511"
 18) "key:11"

如你所見(jiàn), 以上的大部分迭代都不返回任何元素。

在最后一次迭代, 我們通過(guò)將 COUNT 選項(xiàng)的參數(shù)設(shè)置為 1000 , 強(qiáng)制命令為本次迭代掃描更多元素, 從而使得命令返回的元素也變多了。

并發(fā)執(zhí)行多個(gè)迭代

在同一時(shí)間, 可以有任意多個(gè)客戶端對(duì)同一數(shù)據(jù)集進(jìn)行迭代, 客戶端每次執(zhí)行迭代都需要傳入一個(gè)游標(biāo), 并在迭代執(zhí)行之后獲得一個(gè)新的游標(biāo), 而這個(gè)游標(biāo)就包含了迭代的所有狀態(tài), 因此, 服務(wù)器無(wú)須為迭代記錄任何狀態(tài)。

中途停止迭代

因?yàn)榈乃袪顟B(tài)都保存在游標(biāo)里面, 而服務(wù)器無(wú)須為迭代保存任何狀態(tài), 所以客戶端可以在中途停止一個(gè)迭代, 而無(wú)須對(duì)服務(wù)器進(jìn)行任何通知。

即使有任意數(shù)量的迭代在中途停止, 也不會(huì)產(chǎn)生任何問(wèn)題。

使用錯(cuò)誤的游標(biāo)進(jìn)行增量式迭代

使用間斷的(broken)、負(fù)數(shù)、超出范圍或者其他非正常的游標(biāo)來(lái)執(zhí)行增量式迭代并不會(huì)造成服務(wù)器崩潰, 但可能會(huì)讓命令產(chǎn)生未定義的行為。

未定義行為指的是, 增量式命令對(duì)返回值所做的保證可能會(huì)不再為真。

只有兩種游標(biāo)是合法的:

1、在開(kāi)始一個(gè)新的迭代時(shí), 游標(biāo)必須為 0 。

2、增量式迭代命令在執(zhí)行之后返回的, 用于延續(xù)(continue)迭代過(guò)程的游標(biāo)。

迭代終結(jié)的保證

增量式迭代命令所使用的算法只保證在數(shù)據(jù)集的大小有界(bounded)的情況下, 迭代才會(huì)停止, 換句話說(shuō), 如果被迭代數(shù)據(jù)集的大小不斷地增長(zhǎng)的話, 增量式迭代命令可能永遠(yuǎn)也無(wú)法完成一次完整迭代。

從直覺(jué)上可以看出, 當(dāng)一個(gè)數(shù)據(jù)集不斷地變大時(shí), 想要訪問(wèn)這個(gè)數(shù)據(jù)集中的所有元素就需要做越來(lái)越多的工作, 能否結(jié)束一個(gè)迭代取決于用戶執(zhí)行迭代的速度是否比數(shù)據(jù)集增長(zhǎng)的速度更快。

時(shí)間復(fù)雜度:

增量式迭代命令每次執(zhí)行的復(fù)雜度為 O(1) , 對(duì)數(shù)據(jù)集進(jìn)行一次完整迭代的復(fù)雜度為 O(N) , 其中 N 為數(shù)據(jù)集中的元素?cái)?shù)量。

返回值:

SCAN 命令、 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都返回一個(gè)包含兩個(gè)元素的 multi-bulk 回復(fù):回復(fù)的第一個(gè)元素是字符串表示的無(wú)符號(hào) 64 位整數(shù)(游標(biāo)), 回復(fù)的第二個(gè)元素是另一個(gè) multi-bulk 回復(fù), 這個(gè) multi-bulk 回復(fù)包含了本次被迭代的元素。

SCAN 命令返回的每個(gè)元素都是一個(gè)數(shù)據(jù)庫(kù)鍵。

SSCAN 命令返回的每個(gè)元素都是一個(gè)集合成員。

HSCAN 命令返回的每個(gè)元素都是一個(gè)鍵值對(duì),一個(gè)鍵值對(duì)由一個(gè)鍵和一個(gè)值組成。

ZSCAN 命令返回的每個(gè)元素都是一個(gè)有序集合元素,一個(gè)有序集合元素由一個(gè)成員(member)和一個(gè)分值(score)組成。

更多用法可查看Redis SCAN命令:

http://doc.redisfans.com/key/scan.html

參考:

https://redis.io

https://www.dazhuanlan.com/2019/12/17/5df832fd189f6

​總結(jié)

到此這篇關(guān)于Redis的KEYS 命令千萬(wàn)不能亂用的文章就介紹到這了,更多相關(guān)Redis的KEYS 命令內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

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

標(biāo)簽:南寧 拉薩 甘南 畢節(jié) 定州 河源 伊春 泰州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Redis的KEYS 命令千萬(wàn)不能亂用》,本文關(guān)鍵詞  Redis,的,KEYS,命令,千萬(wà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)文章
  • 下面列出與本文章《Redis的KEYS 命令千萬(wàn)不能亂用》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Redis的KEYS 命令千萬(wàn)不能亂用的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 黄梅县| 天柱县| 华容县| 乌鲁木齐市| 盐源县| 保康县| 赫章县| 无为县| 博兴县| 张家界市| 兰溪市| 安宁市| 上杭县| 万载县| 简阳市| 瓮安县| 西丰县| 阿合奇县| 阿巴嘎旗| 汕尾市| 平定县| 鄱阳县| 彭山县| 新郑市| 兴安县| 昭觉县| 临夏市| 高雄市| 平原县| 九江市| 定边县| 阳西县| 天峻县| 亚东县| 定边县| 福建省| 丰县| 阆中市| 循化| 林甸县| 漠河县|