18

Is it possible to copy all keys from one Redis instance to another remote instance using MIGRATE? I've tried COPY, REPLACE and KEYS without any luck. Each time I get a NOKEY response. If I use any of the MIGRATE commands with a single key it works.

Examples:

MIGRATE my.redis 6379 "*" 0 5000 REPLACE // NOKEY MIGRATE my.redis 6379 "*" 0 5000 COPY // NOKEY MIGRATE my.redis 6379 "" 0 5000 KEYS * // NOKEY MIGRATE my.redis 6379 "" 0 5000 KEYS test // OK 

5 Answers 5

27

This is an improvement on the answer provided by @ezain since I am unable to post comments. The command uses the correct redis syntax for processing batches of keys, but the arguments to xargs result in the command being called once for every key instead of just once with all the keys included (which means it'll take much more time to complete than is necessary). The following will be much faster in all cases:

redis-cli --raw KEYS '*' | xargs redis-cli MIGRATE my.redis 6379 "" 0 5000 KEYS

If the destination is password protected:

  • redis-cli --raw KEYS '*' | xargs redis-cli MIGRATE my.redis 6379 "" 0 5000 AUTH password-here KEYS
Sign up to request clarification or add additional context in comments.

2 Comments

What if the remote destination instance asks for a password?
I've updated the answer to include example for password protected destination.
7

try run in your shell

redis-cli keys '*' | xargs -I '{}' redis-cli migrate my.redis 6379 "" 0 5000 KEYS '{}' 

4 Comments

This works but constrains me to copy data from only the default database 0
redis-cli -n 2 keys '*' | xargs -I '{}' redis-cli -n 2 migrate my.redis 6379 "" 3 5000 KEYS '{}' to copy from default redis db 2 to my.redis db 3
How to specify password/auth for the destination Redis server?
What if the remote destination instance asks for a password?
1

For a big DBs with a lot of keys it's better to use --scan instead of keys, to avoid Redis lock on KEYS command:

redis-cli --scan | xargs redis-cli MIGRATE my.redis 6379 "" 0 5000 KEYS 

Not really related to the question, but in case someone will need it: Redis does not support MIGRATE with a password before 3.0. After 3.0, you can add AUTH parameter to check the permission:

MIGRATE 192.168.0.33 6379 "" 0 5000 AUTH mypassword KEYS user:{info}:age 

1 Comment

This is authenticating on the local instance I suppose? How do you send password for the destination redis host ?
1

If you are running on non-managed¹ redis instances, the most ideal way would probably to run the target instance as a replica temporarly and then disable (after all data is copied) the replication.

see the REPLICAOF command in redis. how to apply it (all commands on the target instance):

initiate the replication: $ replicaof source_hostname_or_ip source_port

after everything is done: $ replicaof no one

If you can't use this command¹ then you can try this script on the digital ocean blog: https://www.digitalocean.com/community/tutorials/how-to-migrate-redis-data-to-a-digitalocean-managed-database#step-3-%E2%80%94-building-the-migration-script

################

¹ - managed services often restrict the usage of this command see here or here.

Comments

-3

I'm not advocating using this, but I tried all of these examples, and many others and did not work. I ended up doing it myself in PHP, so maybe this will help someone else who is stuck.

<?php $redisSource = new Redis(); $redisSource->connect('1.2.3.4', 6379); $redisSource->auth('password'); $redisTarget = new Redis(); $redisTarget->connect('127.0.0.1', 6379); foreach($redisSource->keys('*') as $key) { $redisTarget->set($key, $redisSource->get($key)); } 

2 Comments

This solution doesn't consider keys metadata like TTL
while this solution is not very "liked", it's the only way I have found so far to copy data from a newer version of redis to an older (looking at you, out of date Alpine repo). Otherwise you always get checksum/version errors

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.