Skip to content

Instantly share code, notes, and snippets.

@daragh
Last active December 22, 2019 15:45
Show Gist options
  • Save daragh/e00d1c8c3a407a6b48d133d2a1e376f7 to your computer and use it in GitHub Desktop.
Save daragh/e00d1c8c3a407a6b48d133d2a1e376f7 to your computer and use it in GitHub Desktop.
Copy keys & values from one Redis instance to another
#!/usr/bin/env python3
import sys
import asyncio
import argparse
from redis import StrictRedis
class Async:
def __init__(self, wrapped):
self._wrapped = wrapped
def __getattr__(self, attr):
value = getattr(self._wrapped, attr)
if callable(value):
async def func(*args, **kwargs):
return value(*args, **kwargs)
return func
else:
return value
async def main():
(source, destination) = parse_args()
async def dump_restore(key):
ttl = max(0, source.ttl(key))
value = source.dump(key)
destination.restore(key, ttl=ttl, value=value, replace=True)
counter = 0
size = source.dbsize()
save_cursor_position = "\033[s"
sys.stderr.write(save_cursor_position)
scan_task = asyncio.create_task(Async(source).scan(cursor=0))
while True:
(cursor, keys) = await scan_task
scan_task = asyncio.create_task(Async(source).scan(cursor=cursor))
for task in [asyncio.create_task(dump_restore(key)) for key in keys]:
await task
counter += 1
write_progress(size, counter)
if cursor == 0: break
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("source", type=StrictRedis.from_url)
parser.add_argument("destination", type=StrictRedis.from_url)
parsed = parser.parse_args()
return (parsed.source, parsed.destination)
def write_progress(size, counter):
restore_cursor_position = "\033[u"
percent = (100.0 * counter) / size
sys.stderr.write(
f"{restore_cursor_position}"
f"{counter} / {size} "
f"({percent:.2f}%) "
"\n"
)
sys.stderr.flush()
if __name__ == "__main__": asyncio.run(main(), debug=True)
from setuptools import setup
setup(
name='Redis Dump Restore',
version='0.1.0',
scripts=['redis-dump-restore'],
install_requires=['redis>=3.3'],
python_requires='>=3.7',
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment