偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Redis如何刪除數(shù)量過(guò)萬(wàn)以上Key而不影響業(yè)務(wù)

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù) Redis
有時(shí)候因?yàn)?Redis Key 沒(méi)有設(shè)置過(guò)期時(shí)間或者因?yàn)闃I(yè)務(wù)需求或者Redis內(nèi)存不足或者修改Redis Key值等需求,并且這些Key是有規(guī)律的,可以通過(guò)正則表達(dá)式來(lái)匹配。

需求

有時(shí)候因?yàn)?Redis Key 沒(méi)有設(shè)置過(guò)期時(shí)間或者因?yàn)闃I(yè)務(wù)需求或者Redis內(nèi)存不足或者修改Redis Key值等需求,并且這些Key是有規(guī)律的,可以通過(guò)正則表達(dá)式來(lái)匹配。

解決方法一

一般通過(guò)網(wǎng)上搜索,會(huì)告訴你使用下面方法,Redis 提供了一個(gè)簡(jiǎn)單暴力的指令 keys用來(lái)列出所有滿足特定正則字符串規(guī)則的 key。

  1. $ redis-cli --raw keys "testkey-*" | xargs redis-cli del 

通過(guò) Redis keys 來(lái)匹配你需要?jiǎng)h除的key,再使用 xargs 把結(jié)果傳給 redis-cli del ,這樣看似完美,實(shí)則有很大風(fēng)險(xiǎn)。

上面命令使用非常簡(jiǎn)單,提供一個(gè)簡(jiǎn)單的正則字符串即可,但是有很明顯的兩個(gè)缺點(diǎn)。

  • 沒(méi)有 offset、limit 參數(shù),一次性吐出所有滿足條件的 key,萬(wàn)一實(shí)例中有幾百 w 個(gè) key 滿足條件,當(dāng)你看到滿屏的字符串刷的沒(méi)有盡頭時(shí),你就知道難受了。
  • keys 算法是遍歷算法,復(fù)雜度是 O(n),如果實(shí)例中有千萬(wàn)級(jí)以上的 key,這個(gè)指令就會(huì)導(dǎo)致 Redis 服務(wù)卡頓,所有讀寫(xiě) Redis 的其它的指令都會(huì)被延后甚至?xí)瑫r(shí)報(bào)錯(cuò),因?yàn)?Redis 6 版本以下都是單線程程序,順序執(zhí)行所有指令,其它指令必須等到當(dāng)前的 keys 指令執(zhí)行完了才可以繼續(xù),這樣就會(huì)導(dǎo)致業(yè)務(wù)不可用,甚至造成redis宕機(jī)的風(fēng)險(xiǎn)。

注意:這種方法不推薦,建議生產(chǎn)環(huán)境屏蔽keys命令。那大家會(huì)問(wèn),有沒(méi)有更好的方法來(lái)解決這個(gè)問(wèn)題?答案是當(dāng)然用,請(qǐng)接著看下文。

解決方法二

Redis從2.8版本開(kāi)始支持 scan 命令,SCAN命令的基本用法如下:

  1. SCAN cursor [MATCH pattern] [COUNT count
  • cursor:游標(biāo),SCAN命令是一個(gè)基于游標(biāo)的迭代器,SCAN命令每次被調(diào)用之后,都會(huì)向用戶返回一個(gè)新的游標(biāo),用戶在下次迭代時(shí)需要使用這個(gè)新游標(biāo)作為SCAN命令的游標(biāo)參數(shù),以此來(lái)延續(xù)之前的迭代過(guò)程,直到服務(wù)器向用戶返回值為0的游標(biāo)時(shí),一次完整的遍歷過(guò)程就結(jié)束了。
  • MATCH:匹配規(guī)則,例如遍歷以 testkey- 開(kāi)頭的所有key可以寫(xiě)成 testkey-*。
  • COUNT:COUNT選項(xiàng)的作用就是讓用戶告知迭代命令,在每次迭代中應(yīng)該從數(shù)據(jù)集里返回多少元素,COUNT只是對(duì)增量式迭代命令的一種提示,并不代表真正返回的數(shù)量,例如你COUNT設(shè)置為2有可能會(huì)返回3個(gè)元素,但返回的元素?cái)?shù)據(jù)會(huì)與COUNT設(shè)置的正相關(guān),COUNT的默認(rèn)值是10。

例子:

  1. $ scan 0 MATCH testkey-* 
  2.  
  3. 1) "34" 
  4. 2)  1) "testkey-2" 
  5.     2) "testkey-49" 
  6.     3) "testkey-20" 
  7.     4) "testkey-19" 
  8.     5) "testkey-93" 
  9.     6) "testkey-8" 
  10.     7) "testkey-34" 
  11.     8) "testkey-76" 
  12.     9) "testkey-13" 
  13.    10) "testkey-18" 
  14.    11) "testkey-10" 
  15.  
  16. $ scan 34 MATCH testkey-* COUNT 1000 
  17.  
  18. 1) "0" 
  19. 2)  1) "ops-coffee-16" 
  20.     2) "ops-coffee-19" 
  21.     3) "ops-coffee-23" 
  22.     4) "ops-coffee-21" 
  23.     5) "ops-coffee-40" 
  24.     6) "ops-coffee-22" 
  25.     7) "ops-coffee-1" 
  26.     8) "ops-coffee-11" 
  27.     9) "ops-coffee-28" 
  28.    10) "ops-coffee-3" 
  29.    11) "ops-coffee-26" 
  30.    12) "ops-coffee-4" 
  31.    13) "ops-coffee-31" 
  32.    ... 

scan 命令返回的是一個(gè)包含兩個(gè)元素的數(shù)組,第一個(gè)數(shù)組元素是用于進(jìn)行下一次迭代的新游標(biāo),而第二個(gè)數(shù)組元素則是一個(gè)數(shù)組,這個(gè)數(shù)組中包含了所有被迭代的元素。

上面這個(gè)例子的意思是掃描所有前綴為testkey-的key。第一次迭代使用0作為游標(biāo),表示開(kāi)始一次新的迭代,同時(shí)使用了MATCH匹配前綴為testkey-的key,返回了游標(biāo)值34以及遍歷到的數(shù)據(jù)。第二次迭代使用的是第一次迭代時(shí)返回的游標(biāo),也即是命令回復(fù)第一個(gè)元素的值34,同時(shí)通過(guò)將COUNT選項(xiàng)的參數(shù)設(shè)置為1000,強(qiáng)制命令為本次迭代掃描更多元素。在第二次調(diào)用SCAN命令時(shí),命令返回了游標(biāo)0,這表示迭代已經(jīng)結(jié)束,整個(gè)數(shù)據(jù)集已經(jīng)被完整遍歷過(guò)了。

Redis scan 命令就是基于游標(biāo)的迭代器,意味著命令每次被調(diào)用都需要使用上一次這個(gè)調(diào)用返回的游標(biāo)作為該次調(diào)用的游標(biāo)參數(shù),以此來(lái)延續(xù)之前的迭代過(guò)程。當(dāng)SCAN命令的游標(biāo)參數(shù)被設(shè)置為0時(shí),服務(wù)器將開(kāi)始一次新的迭代,而當(dāng)redis服務(wù)器向用戶返回值為0的游標(biāo)時(shí),表示迭代已結(jié)束,這是唯一迭代結(jié)束的判定方式,而不能通過(guò)返回結(jié)果集是否為空判斷迭代結(jié)束。

上面的需求,最終可以使用下面命令來(lái)解決:

  1. $ redis-cli --scan --pattern "testkey-*" | xargs -L 1000 redis-cli del 

xargs -L 指令表示xargs一次讀取的行數(shù),也就是每次刪除key的數(shù)量,不要一次行讀取太多數(shù)量key。

scan 與 keys 比較

scan 相比 keys 具備有以下特點(diǎn):

  • 復(fù)雜度雖然也是 O(n),但是它是通過(guò)游標(biāo)分步進(jìn)行的,不會(huì)阻塞線程。
  • 提供 limit 參數(shù),可以控制每次返回結(jié)果的最大條數(shù),limit 只是對(duì)增量式迭代命令的一種提示(hint),返回的結(jié)果可多可少。
  • 同 keys 一樣,它也提供模式匹配功能。
  • 服務(wù)器不需要為游標(biāo)保存狀態(tài),游標(biāo)的唯一狀態(tài)就是 scan 返回給客戶端的游標(biāo)整數(shù)。
  • 返回的結(jié)果可能會(huì)有重復(fù),需要客戶端去重復(fù),這點(diǎn)非常重要。
  • 遍歷的過(guò)程中如果有數(shù)據(jù)修改,改動(dòng)后的數(shù)據(jù)能不能遍歷到是不確定的。
  • 單次返回的結(jié)果是空的并不意味著遍歷結(jié)束,而要看返回的游標(biāo)值是否為零。

小結(jié)

Redis 類似 scan 命令還有很多,比如:

  • scan 指令是一系列指令,除了可以遍歷所有的 key 之外,還可以對(duì)指定的容器集合進(jìn)行遍歷
  • zscan 遍歷 zset 集合元素
  • hscan 遍歷 hash 字典的元素
  • sscan 遍歷 set 集合的元素

注意: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ù)鍵。

參考鏈接

http://jinguoxing.github.io/redis/2018/09/04/redis-scan/

https://juejin.cn/post/6844903869412016142

 

責(zé)任編輯:姜華 來(lái)源: YP小站
相關(guān)推薦

2012-03-02 09:03:57

VDI虛擬桌面網(wǎng)絡(luò)

2009-01-16 08:17:43

北電破產(chǎn)保護(hù)重組

2021-04-26 09:40:46

QPS數(shù)據(jù)庫(kù)Redis

2014-04-14 13:05:41

RedisDBA服務(wù)器

2023-11-06 11:12:08

大數(shù)據(jù)數(shù)據(jù)治理

2016-01-08 13:53:19

網(wǎng)絡(luò)犯罪網(wǎng)絡(luò)詐騙

2022-01-02 08:38:22

Redis數(shù)據(jù)單線程

2022-11-28 14:12:07

物聯(lián)網(wǎng)IOT

2013-04-02 14:14:23

Android廣告不影響用戶體驗(yàn)

2010-09-10 08:32:45

android marApp CatalogApp Store

2018-06-06 16:17:41

視頻剪輯

2021-06-04 10:24:37

人工智能AI深度學(xué)習(xí)

2023-09-06 12:17:19

數(shù)字化轉(zhuǎn)型能源成本

2020-08-11 10:25:38

數(shù)據(jù)成本數(shù)據(jù)大數(shù)據(jù)

2015-04-23 15:30:08

2009-11-25 16:29:08

PHP刪除數(shù)組元素

2022-11-28 11:47:47

物聯(lián)網(wǎng)IOT

2009-03-26 08:22:49

AndroidGoogle移動(dòng)OS

2009-03-26 17:10:58

LinuxAndroidWindows 7

2009-07-07 09:31:04

Twitter
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)