<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          基于redis的keys、scan刪除ttl為-1的key

          共 5436字,需瀏覽 11分鐘

           ·

          2022-07-26 15:58

          前言:由于redis服務(wù)器最大使用內(nèi)存為450MB,redis存儲的部分key沒有設(shè)置過期時間,內(nèi)存淘汰策略為:noeviction 以上原因?qū)е聄edis服務(wù)無法加載到新的key,迫使部分業(yè)務(wù)受阻。


          一、keys命令介紹

          redis KEYS 命令基本語法如下:

          redis 127.0.0.1:6379> KEYS PATTERN

          返回值

          符合給定模式的 key 列表 (Array)。

          #獲取 redis 中所有的 key 可用使用 *。
          redis 127.0.0.1:6379> KEYS *
          1"runoob3"
          2"runoob1"
          3"runoob2"

          由于 Redis 是單線程在處理用戶的命令,而 Keys 命令會一次性遍歷所有 Key,于是在 命令執(zhí)行過程中,無法執(zhí)行其他命令。這就導(dǎo)致如果 Redis 中的 key 比較多,那么 Keys 命令執(zhí)行時間就會比較長,從而阻塞 Redis。

          #查找以 runoob 為開頭的 key:
          redis 127.0.0.1:6379> KEYS runoob*
          1"runoob3"
          2"runoob1"
          3"runoob2"

          Keys 的缺點:

          • 沒有l(wèi)imit,我們只能一次性獲取所有符合條件的key,如果結(jié)果有上百萬條,那么等待你的就是“無窮無盡”的字符串輸出。

          • keys命令是遍歷算法,時間復(fù)雜度是O(N)。如我們剛才所說,這個命令非常容易導(dǎo)致Redis服務(wù)卡頓。因此,我們要盡量避免在生產(chǎn)環(huán)境使用該命令。


          二、scan命令介紹

          Redis Scan 命令用于迭代數(shù)據(jù)庫中的數(shù)據(jù)庫鍵。


          SCAN 命令是一個基于游標的迭代器,每次被調(diào)用之后, 都會向用戶返回一個新的游標, 用戶在下次迭代時需要使用這個新游標作為 SCAN 命令的游標參數(shù), 以此來延續(xù)之前的迭代過程。


          SCAN 返回一個包含兩個元素的數(shù)組, 第一個元素是用于進行下一次迭代的新游標, 而第二個元素則是一個數(shù)組, 這個數(shù)組中包含了所有被迭代的元素。如果新游標返回 0 表示迭代已結(jié)束。

          redis Scan 命令基本語法如下:

          SCAN cursor [MATCH pattern] [COUNT count]
          參數(shù):
          cursor - 游標。
          pattern - 匹配的模式。
          count - 指定從數(shù)據(jù)集里返回多少元素,默認值為 10 。

          返回值:數(shù)組列表。

          Scan命令就是對這個一維數(shù)組進行遍歷。每次返回的游標值也都是這個數(shù)組的索引。Count 參數(shù)表示遍歷多少個數(shù)組的元素,將這些元素下掛接的符合條件的結(jié)果都返回。因為每個元素下掛接的鏈表大小不同,所以每次返回的結(jié)果數(shù)量也就不同。

          # 使用 0 作為游標,開始新的迭代
          redis 127.0.0.1:6379scan 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"

          #使用的是第一次迭代時返回的游標 17 開始新的迭代
          redis 127.0.0.1:6379scan 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"

          Scan 的特點:

          1. 復(fù)雜度雖然也是 O(n),但是它是通過游標分步進行的,不會阻塞線程;

          2. 提供 limit 參數(shù),可以控制每次返回結(jié)果的最大條數(shù),limit 只是一個 hint,返回的結(jié)果可多可少;

          3. 同 keys 一樣,它也提供模式匹配功能;

          4. 服務(wù)器不需要為游標保存狀態(tài),游標的唯一狀態(tài)就是 scan 返回給客戶端的游標整數(shù);

          5. 返回的結(jié)果可能會有重復(fù),需要客戶端去重復(fù),這點非常重要;

          6. 遍歷的過程中如果有數(shù)據(jù)修改,改動后的數(shù)據(jù)能不能遍歷到是不確定的;

          7. 單次返回的結(jié)果是空的并不意味著遍歷結(jié)束,而要看返回的游標值是否為零


          count參數(shù)詳解:

          • 當count參數(shù)指定為100時,然而redis中key有幾百萬時,這個時候返回時間會很長,

          • count參數(shù)調(diào)大后,減少了交互次數(shù),返回的時間就會減少。

          • Count 參數(shù)越大,Redis 阻塞時間也會越長,需要取舍。

          • 極限一點,Count 參數(shù)和總 Key 數(shù)一致時,Scan 命令就和 Keys 效果一樣了。


          Count 大小和 Scan 總耗時的關(guān)系如下圖:


          結(jié)論:

          1. 可以發(fā)現(xiàn) Count 越大,總耗時就越短,不過越后面提升就越不明顯了。

          2. 所以推薦的 Count 大小為 1W 左右。

          3. 如果不考慮 Redis 的阻塞,其實 Keys 比 Scan 會快很多,畢竟一次性處理,省去了多余的交互。


          三、keys命令刪除

          #!/usr/bin/python3
          import redis

          r = redis.Redis(host='172.18.158.92', port=6379, db=0,decode_responses=True)
          var = 0
          var1 = 0
          list_keys = r.keys("system_WXMINI/WX_MINI_NO_Userinfo/unionid*")

          for key in list_keys:
              num = r.ttl(key)
              if num == -1:
                  r.delete(key)
                  var = var + 1
              else:
                  var1 = var1 + 1

          print("end")
          print("刪除key的數(shù)量",var)
          print("未刪除的數(shù)量",var1)


          四、scan命令刪除

          [root@iZwz9conqz5shxfx2gmnfkZ scripts]# cat clean_key_v5.py 
          #!/usr/bin/python3
          import redis

          def RedisScan(vague_key,host="127.0.0.1",port=6379,password=None,db=0):
              redis_cache = redis.Redis(host=host, port=port, db=db, password=password, decode_responses=True)
              begin_pos,counts,var,delete_key = 0,0,0,0

              while True:
                  begin_pos,list_keys = redis_cache.scan(begin_pos,vague_key,10000)
                  counts += len(list_keys)
                  for key in list_keys:
                      num = redis_cache.ttl(key)
                      if num == -1:
                          redis_cache.delete(key)
                          delete_key = delete_key + 1
                      else:
                          var = var + 1
                  if begin_pos == 0:
                      break

              print("no delete key is ", var)
              print("delete key is ", delete_key)
              print("total key is ", counts)

          #調(diào)用
          RedisScan("system_url_id*","172.18.158.92",6379,"*****")
          五、redis 相關(guān)調(diào)整
          CONFIG SET maxmemory-policy volatile-lru

          config set maxmemory 8589934592
          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  伦理片一区二区 | 大鸡吧在线视频 | 无码在线国产 | 亚洲最大的成人网址 | 中文字幕北条麻妃在线 |