首頁 > 軟體

redis模糊批次刪除key的方法

2022-12-19 14:01:48

一、命令列刪除

redis-cli -h 172.18.255.99 -p 6379 -n 6 -a 123456 KEYS "websocket127.0.0.1:5*" | xargs redis-cli -h 172.18.255.99 -p 6379 -n 6 -a 123456 DEL
  • -h:redis地址
  • -p:redis埠
  • -n:reids庫
  • -a:redis密碼

Redis 提供了一個簡單暴力的指令 keys 用來列出所有滿足特定正則字串規則的 key。

注:這個指令使用非常簡單,提供一個簡單的正則字串即可,但是有很明顯的兩個缺點。

  • 沒有 offset、limit 引數,一次性吐出所有滿足條件的 key,萬一範例中有幾百 w 個 key 滿足條件,
  • 當你看到滿屏的字串刷的沒有盡頭時,你就知道難受了。
  • keys 演演算法是遍歷演演算法,複雜度是 O(n),如果範例中有千萬級以上的 key,這個指令就會導致 Redis 服務卡頓,
  • 所有讀寫 Redis 的其它的指令都會被延後甚至會超時報錯,
  • 因為 Redis 是單執行緒程式,順序執行所有指令,其它指令必須等到當前的 keys 指令執行完了才可以繼續。

所以建議生產環境遮蔽keys命令

scan 相比 keys 具備有以下特點:

  • 複雜度雖然也是 O(n),但是它是通過遊標分步進行的,不會阻塞執行緒;
  • 提供 limit 引數,可以控制每次返回結果的最大條數,limit 只是對增量式迭代命令的一種提示(hint),返回的結果可多可少;
  • 同 keys 一樣,它也提供模式匹配功能;
  • 伺服器不需要為遊標儲存狀態,遊標的唯一狀態就是 scan 返回給使用者端的遊標整數;
  • 返回的結果可能會有重複,需要使用者端去重複,這點非常重要;
  • 遍歷的過程中如果有資料修改,改動後的資料能不能遍歷到是不確定的;
  • 單次返回的結果是空的並不意味著遍歷結束,而要看返回的遊標值是否為零

KEYS vs SCAN

一樣都會掃過所有的 key,scan 不會阻塞整個 server,而是迭代的收集結果

DEL vs UNLINK

一樣都是刪除 key ,差別在於 unlink 是非阻塞的刪除,會以非同步的方式回收記憶體

所以對於一個大的key數量,我們可以藉助sscan使用下邊的命令可以實現優雅的批次刪除:

redis-cli -h 172.18.255.99 -p 6379 --scan --pattern users:* | xargs redis-cli -h 172.18.255.99 -p 6379 unlink
  • 用 scan 找出要刪的 key
  • 透過 xargs 傳給 unlink 刪掉 key
(error) ERR unknown command 'unlink'

如果出現以上錯誤,說明redis版本不足,使用unlink需要Redis4版本

cluster 刪除資料

redis-cli -c -p 7000 --scan --pattern "age_*" | xargs -L 1 redis-cli -c -p 7000 -n 0 unlink

遍歷redis cluster各分片刪除

for port in {7000..7005}; do
    redis-cli -c -p ${port} -h 192.168.31.181 --scan --pattern "age_*" | xargs -L 1 redis-cli -h 192.168.31.181 -c -p ${port} -n 0 unlink  
done

二、golang程式碼刪除

func DeleteRedisKeys(key string) {
	traceId := libra.GenTraceId(context.Background(), nil)
	ctx := libra.SetTraceId(context.Background(), traceId)
	//模糊查詢所有符合條件的key
	websocketKeys, _ := commons.GetRedisClient().Keys(ctx, key+"*").Result()
	if reflect.TypeOf(websocketKeys).Kind() == reflect.Slice {
		val := reflect.ValueOf(websocketKeys)
		if val.Len() == 0 {
			return
		}
		// 批次刪除key
		for i := 0; i < val.Len(); i++ {
			_, err := commons.GetRedisClient().Del(ctx, val.Index(i).Interface().(string)).Result()
			dlog.Errorf("DeleteKeys addr:=%v,err=%v", addr, err)
		}
	}
}

參考檔案

Redis SCAN的使用:http://jinguoxing.github.io/redis/2018/09/04/redis-scan/

到此這篇關於redis模糊批次清除key的文章就介紹到這了,更多相關redis模糊刪除key內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com