Delete keys from a Tair instance in bulk using non-blocking methods such as SCAN + UNLINK or pipeline mode.
Choose a deletion method
|
Scenario |
Method |
Blocking |
Risk |
|
I have a list of specific keys to delete |
No |
Low |
|
|
I need to delete keys matching a pattern in production |
No |
Low |
|
|
I need maximum throughput for batch deletion |
No |
Low |
|
|
I'm in a dev/test environment with few keys |
Yes |
High |
Important notes
-
Back up your data before deleting keys.
-
Perform deletions during off-peak hours to minimize impact.
-
Cannot run in DMS: Use redis-cli or a Python client on an ECS instance or local machine.
Method 1: Delete from a file
Best for a predefined list of keys stored in a text file.
Prerequisites
Write the keys to delete to a text file, one key per line.
Command
# UNLINK is non-blocking (Redis 4.0+). For earlier versions, use DEL.
cat <file> | xargs redis-cli -h <host> -p <port> -a <password> UNLINK
Parameters
|
Parameter |
Description |
|
file |
Path to the file containing keys. Example: |
|
host |
The endpoint of the Tair instance. See View endpoints. |
|
port |
Port number. Default: |
|
password |
The password used to log on to the instance. See Authentication methods for instances. |
Example
cat key.txt | xargs redis-cli -h r-bp127cu5tb*****.redis.rds.aliyuncs.com -a Test**** UNLINK
Verify the deletion
# Verify that keys are deleted. Expected result: 0
redis-cli -h <host> -p <port> -a <password> --scan --pattern '<key pattern in the file>' | wc -l
Method 2: SCAN + UNLINK (Recommended)
Recommended for production. Iteratively scans and deletes keys without blocking the server.
Code
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)
Run
python scan_and_unlink.py <host> <port> <password> "<key>"
Parameters
|
Parameter |
Description |
|
host |
The endpoint of the Tair instance. See View endpoints. |
|
port |
Port number. Default: |
|
password |
The password used to log on to the instance. See Authentication methods for instances. |
|
key |
Key pattern. Example: |
Pattern syntax
|
Pattern |
Matches |
|
|
5-char strings: |
|
|
Any length: |
|
|
|
|
|
|
|
|
|
Verify the deletion
Verify that all matching keys are deleted:
redis-cli -h <host> -p <port> -a <password> --scan --pattern '<key>' | wc -l
# Expected output: 0
Method 3: Pipeline mode
Maximizes throughput by batching UNLINK commands to reduce network round trips.
Code
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")
# After accumulating 1000 keys, submit a DEL command through the pipeline. You can adjust this number as needed.
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...")
# Use a 'while True' loop and exit when the cursor is 0.
while True:
# 1. Scan a batch of keys.
cursor, keys = redis_cli.scan(cursor=cursor, match=match, count=1000)
if keys:
# 2. Collect the scanned keys into a list for deletion.
keys_to_delete.extend(keys)
# 3. When the deletion list reaches the batch size or the scan is complete, execute the deletion.
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.")
# Clear the deletion list to prepare for the next batch.
keys_to_delete = []
# 4. If the scan is complete, exit the loop.
if cursor == 0:
break
print(f"\nScan finished. Total keys deleted: {total_deleted_count}")
if __name__ == '__main__':
main(sys.argv)
Run
python scan_and_unlink_pipe.py <host> <port> <password> "<key>"
Parameters
|
Parameter |
Description |
|
host |
The endpoint of the Tair instance. See View endpoints. |
|
port |
Port number. Default: |
|
password |
The password used to log on to the instance. See Authentication methods for instances. |
|
key |
Key pattern. Example: |
Pattern syntax
|
Pattern |
Matches |
|
|
5-char strings: |
|
|
Any length: |
|
|
|
|
|
|
|
|
|
Verify
redis-cli -h <host> -p <port> -a <password> --scan --pattern '<key>' | wc -l
# Expected output: 0
Method 4: KEYS + DEL (Use with caution)
The KEYS command blocks the server and may cause high CPU usage. Use this method only in development environments or during planned outages.
When to use
-
Development or staging environments
-
Databases with a small number of keys
-
During complete service outages
Command
redis-cli -h <host> -p <port> -a <password> KEYS "<key>" | xargs redis-cli -h <host> -p <port> -a <password> DEL
Parameters
|
Parameter |
Description |
|
host |
The endpoint of the Tair instance. See View endpoints. |
|
port |
Port number. Default: |
|
password |
The password used to log on to the instance. See Authentication methods for instances. |
|
key |
Key pattern. Example: |
Pattern syntax
|
Pattern |
Matches |
|
|
5-char strings: |
|
|
Any length: |
|
|
|
|
|
|
|
|
|
Example
redis-cli -h r-bp127cu5tb*****.redis.rds.aliyuncs.com -a Test**** KEYS "test*" | xargs redis-cli -h r-bp127cu5tb*****.redis.rds.aliyuncs.com -a Test**** DEL
Verify
redis-cli -h <host> -p <port> -a <password> --scan --pattern '<key>' | wc -l
# Expected output: 0
FAQ
Q: Why does SCAN fail to find expected keys?
A: The keys may reside in a different database. A Tair instance has 256 databases by default. Run INFO keyspace to identify which databases contain keys, then use one of the following methods:
-
Use the
-nparameter to specify the database (Recommended):redis-cli -h <host> -p <port> -a <password> -n <db> -
Use the SELECT command to switch to the database:
redis-cli -h <host> -p <port> -a <password> > SELECT <db>