Last active
June 27, 2019 13:00
-
-
Save ocpodariu/63756f0fc7787357cfc8271fac88102d to your computer and use it in GitHub Desktop.
Copy Redis database between two Elasticache services
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import sys | |
import logging | |
import ConfigParser | |
import redis | |
def connect_to_redis(host, port, database): | |
rc = redis.Redis(host=host, port=port, db=database) | |
rc.get("test-conn") | |
return rc | |
if __name__ == '__main__': | |
logging.getLogger().setLevel(logging.ERROR) | |
filename = r'dev.conf' | |
for arg in sys.argv: | |
if arg == '-v': | |
logging.getLogger().setLevel(logging.DEBUG) | |
elif arg == '-prod': | |
filename = r'prod.conf' | |
config = ConfigParser.ConfigParser() | |
config.readfp(open(filename)) | |
logging.debug('Connecting to Redis Source at %s:%s[db:%s]...', | |
config.get('redis-source', 'host'), | |
config.get('redis-source', 'port'), | |
config.get('redis-source', 'db')) | |
redis_source = connect_to_redis(config.get('redis-source', 'host'), | |
config.get('redis-source', 'port'), | |
config.get('redis-source', 'db')) | |
logging.debug('Connecting to Redis Destination at %s:%s[db:%s]...', | |
config.get('redis-dest', 'host'), | |
config.get('redis-dest', 'port'), | |
config.get('redis-dest', 'db')) | |
redis_dest = connect_to_redis(config.get('redis-dest', 'host'), | |
config.get('redis-dest', 'port'), | |
config.get('redis-dest', 'db')) | |
keys_left_to_copy = redis_source.dbsize() | |
keys_per_scan = 500 | |
cursor = 0 | |
while keys_left_to_copy > 0: | |
logging.debug('Keys left to copy: %d\tCurrent cursor: %d', | |
keys_left_to_copy, cursor) | |
result = redis_source.scan(cursor, match=None, count=keys_per_scan) | |
cursor = result[0] | |
count = len(result[1]) | |
keys_left_to_copy -= count | |
logging.debug('Copying %d keys', count) | |
for key in result[1]: | |
key_type = redis_source.type(key) | |
if key_type == 'string': | |
redis_dest.set(key, redis_source.get(key)) | |
elif key_type == 'list': | |
redis_dest.lpush(key, redis_source.lrange(key, 0, -1)) | |
elif key_type == 'hash': | |
redis_dest.hmset(key, redis_source.hgetall(key)) | |
elif key_type == 'set': | |
redis_dest.sadd(key, redis_source.smembers(key)) | |
elif key_type == 'zset': | |
members = redis_source.zrange(key, 0, -1, desc=False, withscores=True) | |
redis_dest.zadd(key, *list(sum(members, ()))) | |
key_ttl = redis_source.ttl(key) | |
if key_ttl >= 0: | |
redis_dest.expire(key, key_ttl) | |
logging.debug(50 * '-') | |
# Scanning stops when the returned cursor is 0 | |
if cursor == 0: | |
break | |
logging.debug('Copied %d keys successfully', redis_source.dbsize()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[redis-source] | |
host = redis.x.x.x.cache.amazonaws.com | |
port = 6379 | |
db = 4 | |
[redis-dest] | |
host = redis.z.z.z.cache.amazonaws.com | |
port = 6379 | |
db = 7 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ # Run script with development config ("dev.conf") | |
$ ./elasticache-copy.py -v | |
$ # Run script with production config ("prod.conf") | |
$ ./elasticache-copy.py -v -prod |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment