大量刪除指定Key,推薦使用Redis UNLINK命令結合Linux的cat、xargs命令。批量模糊刪除具有相同首碼或尾碼的Key,推薦使用Redis的SCAN和UNLINK命令。
注意事項
建議刪除前先備份資料,並在業務低峰期執行刪除操作。
下文樣本需通過ECS或本地的redis-cli、Python用戶端執行相關操作,不支援在DMS中執行。
大量刪除指定Key
執行命令前,您需要把待刪除的Key列表寫入至檔案。
通過cat命令從指定檔案中讀取每一行作為Redis的Key,然後使用 redis-cli 串連到 Redis 伺服器,並使用UNLINK命令刪除這些Key。命令文法如下。
# 使用 UNLINK (Redis 4.0+) 非同步刪除,避免阻塞。如果版本低於 Redis 4.0,請將 UNLINK 替換成 DEL
cat <file> | xargs redis-cli -h <host> -p <port> -a <password> UNLINKLinux的xargs命令可以將參數列表分段傳遞給其他命令,以避免參數列表過長的問題,可以單獨使用,也可以使用管道符、重定位器等與其他命令配合使用。
參數說明:
file:記錄了待刪除Key的檔案路徑。例如key.txt。
host:Redis的執行個體串連地址,更多資訊請參見查看串連地址。
port:Redis的連接埠號碼,預設6379。
password:Redis執行個體密碼,更多資訊請參見執行個體的登入方式。
樣本:
cat key.txt | xargs redis-cli -h r-bp127cu5tb*****.redis.rds.aliyuncs.com -a Test**** UNLINK大量刪除模糊比對Key
方法 | 適用情境 |
(推薦)通過SCAN和UNLINK命令模糊刪除 | 在生產環境中安全地清理大量資料。此方法不會阻塞伺服器,能確保線上服務的穩定性 。 |
通過Pipeline模式高輸送量模糊刪除 | 在需要極致刪除效率的情境下,通過一次性批量提交大量命令來最大化輸送量並減少網路延遲。 |
通過KEYS和DEL命令模糊刪除 | 開發、測試環境或在業務完全停止時清理少量資料情境。因KEYS命令會阻塞伺服器,在生產環境使用風險極高。 |
(推薦)通過SCAN和UNLINK命令模糊刪除
通過迴圈逐步遍曆並刪除合格Key。Python程式碼範例:
import redis
import sys
def main(argv):
if len(argv) < 4:
print("Usage: python scan_and_del.py host port password match")
sys.exit(-1)
host = argv[1]
port = argv[2]
password = argv[3]
match = argv[4]
print("host: %s, port: %s, password: %s, match: %s\n" % (host, port, password, match))
redis_cli = redis.StrictRedis(host=host, port=port, password=password)
cursor = 0
rnd = 1
while rnd == 1 or cursor != 0:
result = redis_cli.scan(cursor=cursor, match=match, count=1000)
ret_cursor = result[0]
ret_keys = result[1]
num_keys = len(ret_keys)
print("del %d keys in round %d, cursor: %d" % (num_keys, rnd, ret_cursor))
if 0 != num_keys:
ret_unlink = redis_cli.unlink(*ret_keys)
print("ret_unlink: %d, ret_keys: %s" % (ret_unlink, ret_keys))
cursor = ret_cursor
rnd += 1
print("")
if __name__ == '__main__':
main(sys.argv)調用上述範例程式碼scan_and_unlink.py,調用時指定Redis執行個體的串連資訊和Key的匹配模式,即可實現模糊比對刪除。
python scan_and_unlink.py <host> <port> <password> "<key>" 參數說明:
host:Redis的執行個體串連地址,更多資訊請參見查看串連地址。
port:Redis執行個體的連接埠號碼,預設6379。
password:Redis執行個體密碼,更多資訊請參見執行個體的登入方式。
key:某個資料庫中符合指定要求的Key,例如
"test*"標識以test為首碼的Key,如test1、test2、test3等。關於萬用字元匹配的更多說明:
w?rld:匹配以w開頭,以rl結尾,且長度為5個字元的字串,例如world,warld和wxrld等。
w*rld:匹配以w開頭,以rl結尾的任一字元串,例如wrld和woooorld。
w[ae]rld:匹配warld和werld,但是不匹配world等。
w[^e]rld:匹配world和warld等,但是不匹配werld。
w[a-b]rld:匹配warld和wbrld。
通過Pipeline模式高輸送量模糊刪除
通過迴圈逐步遍曆合格Key,然後將這些Key通過 UNLINK 命令打包在 Pipeline 中一次性發送,從而顯著減少網路往返時間(RTT)。Python程式碼範例:
import redis
import sys
def main(argv):
if len(argv) < 4:
print("Usage: python scan_and_del_pipeline.py host port password match")
sys.exit(-1)
host = argv[1]
port = int(argv[2]) # Convert port to integer
password = argv[3]
match = argv[4]
print(f"host: {host}, port: {port}, password: {'*' * len(password)}, match: {match}\n")
# 每次累積1000個key後,通過Pipeline提交一次DEL命令,可根據業務需求調整
pipeline_batch_size = 1000
redis_cli = redis.StrictRedis(host=host, port=port, password=password, decode_responses=True)
cursor = 0
total_deleted_count = 0
keys_to_delete = []
print("Starting key scan...")
# 使用 'while True' 迴圈,在 cursor 為 0 時退出
while True:
# 1. 掃描一批key
cursor, keys = redis_cli.scan(cursor=cursor, match=match, count=1000)
if keys:
# 2. 將掃描到的key收集到待刪除列表中
keys_to_delete.extend(keys)
# 3. 當待刪除列表達到批處理大小,或者掃描已完成時,執行刪除
if len(keys_to_delete) >= pipeline_batch_size or cursor == 0:
if keys_to_delete:
print(f"Accumulated {len(keys_to_delete)} keys. Preparing to delete via Pipeline...")
# --- Pipeline -----------
pipe = redis_cli.pipeline(transaction=False, shard_hint=None)
pipe.delete(*keys_to_delete)
result = pipe.execute()
# -------------------------
deleted_in_batch = result[0]
total_deleted_count += deleted_in_batch
print(f" -> Pipeline executed. Deleted {deleted_in_batch} keys in this batch.")
# 清空待刪除列表,為下一批做準備
keys_to_delete = []
# 4. 如果掃描完成,則退出迴圈
if cursor == 0:
break
print(f"\nScan finished. Total keys deleted: {total_deleted_count}")
if __name__ == '__main__':
main(sys.argv)
調用上述範例程式碼scan_and_unlink_pipe.py,調用時指定Redis執行個體的串連資訊和Key的匹配模式,即可實現模糊比對刪除。
python scan_and_unlink_pipe.py <host> <port> <password> "<key>" 參數說明:
host:Redis的執行個體串連地址,更多資訊請參見查看串連地址。
port:Redis執行個體的連接埠號碼,預設6379。
password:Redis執行個體密碼,更多資訊請參見執行個體的登入方式。
key:某個資料庫中符合指定要求的Key,例如
"test*"標識以test為首碼的Key,如test1、test2、test3等。關於萬用字元匹配的更多說明:
w?rld:匹配以w開頭,以rl結尾,且長度為5個字元的字串,例如world,warld和wxrld等。
w*rld:匹配以w開頭,以rl結尾的任一字元串,例如wrld和woooorld。
w[ae]rld:匹配warld和werld,但是不匹配world等。
w[^e]rld:匹配world和warld等,但是不匹配werld。
w[a-b]rld:匹配warld和wbrld。
通過KEYS和DEL命令模糊刪除
使用KEYS命令可能會導致CPU使用率高,請在業務低峰期操作。
資料庫中資料較多,使用KEYS命令會影響資料庫的效能,建議在資料較少時使用。
通過KEYS命令,使用萬用字元模糊比對所有合格Key,再通過DEL命令刪除這些Key。
redis-cli -h <host> -p <port> -a <password> KEYS "<key>" | xargs redis-cli -h <host> -p <port> -a <password> DEL參數說明:
host:Redis的執行個體串連地址,更多資訊請參見查看串連地址。
port:Redis執行個體的連接埠號碼,預設6379。
password:Redis執行個體密碼,更多資訊請參見執行個體的登入方式。
key:某個資料庫中符合指定要求的Key,例如
"test*"標識以test為首碼的Key,如test1、test2、test3等。關於萬用字元匹配的更多說明:
w?rld:匹配以w開頭,以rl結尾,且長度為5個字元的字串,例如world,warld和wxrld等。
w*rld:匹配以w開頭,以rl結尾的任一字元串,例如wrld和woooorld。
w[ae]rld:匹配warld和werld,但是不匹配world等。
w[^e]rld:匹配world和warld等,但是不匹配werld。
w[a-b]rld:匹配warld和wbrld。
樣本:
redis-cli -h r-bp127cu5tb*****.redis.rds.aliyuncs.com -a Test**** KEYS "keys*" | xargs redis-cli -h r-bp127cu5tb*****.redis.rds.aliyuncs.com -a Test**** DEL驗證Key是否成功刪除
使用 SCAN 再次掃描,確認沒有匹配的 Key 返回。
# 統計匹配的 Key 數量,預期為 0
redis-cli -h <host> -p <port> -a <password> --scan --pattern 'test:*' | wc -l