Skip to content

Instantly share code, notes, and snippets.

@calvinbui
Created April 23, 2020 02:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save calvinbui/b82e9b0dc3fe7ee916ff976a38fa7442 to your computer and use it in GitHub Desktop.
Save calvinbui/b82e9b0dc3fe7ee916ff976a38fa7442 to your computer and use it in GitHub Desktop.
redis migrate
#!/usr/bin/env python3
import argparse
import redis
def connect(conn_dict, tls):
return redis.Redis(
host=conn_dict['host'],
password=conn_dict['password'],
port=conn_dict['port'],
db=conn_dict['db'],
ssl=tls
)
def conn_string_type(string):
conn_format = '<host>:<port>:<db>:<password>'
try:
host, port, database, password = string.split(':')
database = int(database)
except ValueError:
raise argparse.ArgumentTypeError(f'incorrect format, should be: {conn_format}')
return {
'host': host,
'port': port,
'db': database,
'password': password
}
def migrate_redis(source, destination):
src = connect(source, None)
dst = connect(destination, True) # elasticache has encryptionssrc
for key in src.keys('*'):
ttl = src.ttl(key)
# handle TTL command returning -1 (no expire) or -2 (no key)
if ttl < 0:
ttl = 0
print(f"Dumping key: {key.decode('UTF-8')}")
value = src.dump(key)
print(f"Restoring key: {key.decode('UTF-8')}")
try:
# the ttl key is stored in seconds
# but restore expects milliseconds, so * 1000
dst.restore(key, ttl * 1000, value, replace=True)
except redis.exceptions.ResponseError:
print(f"Failed to restore key: {key.decode('UTF-8')}")
def run():
parser = argparse.ArgumentParser()
parser.add_argument('source', type=conn_string_type)
parser.add_argument('destination', type=conn_string_type)
options = parser.parse_args()
migrate_redis(options.source, options.destination)
if __name__ == '__main__':
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment