This topic describes how to bulk delete keys from a Tair instance by using different methods based on your scenario.
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
Use this method when you have a predefined list of keys to delete.
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> UNLINKParameters
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 Connect to an instance. |
Example
cat key.txt | xargs redis-cli -h r-bp127cu5tb*****.redis.rds.aliyuncs.com -a Test**** UNLINKVerify 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 -lMethod 2: SCAN + UNLINK (Recommended)
Use this method for production environments. It 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 Connect to an instance. |
key | Key pattern. Example: |
Pattern syntax
Pattern | Matches |
| 5-char strings: |
| Any length: |
|
|
|
|
|
|
Verify the deletion
After the script completes, verify:
redis-cli -h <host> -p <port> -a <password> --scan --pattern '<key>' | wc -l
# Expected output: 0Method 3: Pipeline mode
Use this method when you need maximum throughput. It batches UNLINK commands to reduce network round-trip time (RTT).
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 Connect to an instance. |
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: 0Method 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> DELParameters
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 Connect to an instance. |
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**** DELVerify
redis-cli -h <host> -p <port> -a <password> --scan --pattern '<key>' | wc -l
# Expected output: 0FAQ
Q: Why does SCAN fail to find expected keys?
A: The keys may be in a different database. By default, a Tair instance has 256 databases. Run INFO keyspace to see which databases contain keys and use one of the following method:
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>