220

I currently have a live redis server running on a cloud instance and I want to migrate this redis server to a new cloud instance and use that instance as my new redis server. If it were MySQL, I would export the DB from the old server and import it into the new server. How should I do this with redis?

P.S.: I'm not looking to set-up replication. I want to completely migrate the redis server to a new instance.

Shiki
  • 16,688
  • 7
  • 32
  • 33
ErJab
  • 6,056
  • 10
  • 42
  • 54
  • 7
    Years later... After dealing with various redis related things, I'd suggest going with [Tom Clarkson's approach](http://stackoverflow.com/questions/6004915/how-do-i-move-a-redis-database-from-one-server-to-another/6005929#6005929) of setting up a slave instance, letting it sync with master and then promoting the slave to master. This will cause a much shorter downtime compared to the answer I accepted, especially if you're dealing with several GBs of redis data. If you can throw in a redis sentinel into this mix, you can do an almost zero downtime migration. – ErJab Jun 29 '15 at 05:01
  • I have a remote Redis server and want to copy its data to my locally running Redis server...using dump.rdb might be tricky because I would have to move that data over the network.. – Alexander Mills Dec 15 '15 at 23:20

13 Answers13

321

First, create a dump on server A.

A$ redis-cli
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis/"
127.0.0.1:6379> SAVE
OK

This ensures dump.rdb is completely up-to-date, and shows us where it is stored (/var/lib/redis/dump.rdb in this case). dump.rdb is also periodically written to disk automatically.

Next, copy it to server B:

A$ scp /var/lib/redis/dump.rdb myuser@B:/tmp/dump.rdb

Stop the Redis server on B, copy dump.rdb (ensuring permissions are the same as before), then start.

B$ sudo service redis-server stop
B$ sudo cp /tmp/dump.rdb /var/lib/redis/dump.rdb
B$ sudo chown redis: /var/lib/redis/dump.rdb
B$ sudo service redis-server start

The version of Redis on B must be greater or equal than that of A, or you may hit compatibility issues.

Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192
113

Save a snapshot of the database into a dump.rdb by either running BGSAVE or SAVE from the command line. This will create a file named dump.rdb in the same folder as your redis server. See a list of all server commands.

Copy this dump.rdb to the other redis server you want to migrate to. When redis starts up, it looks for this file to initialize the database from.

Ben Scheirman
  • 40,531
  • 21
  • 102
  • 137
Anurag
  • 140,337
  • 36
  • 221
  • 257
  • 19
    This leaves me guessing at a couple of things: Where does the SAVE command put its dump? Where does Redis look for a "dump.rdb" file to load a start up? My redis config has dbfilename set to /var/db/redis/redis_state.rdb ... is this the filename I use in place of "dump.rdb"? – Mojo Mar 23 '12 at 18:29
  • The SAVE command puts its dump into the same file. You should backup it :-) – Houen May 08 '12 at 16:47
  • 23
    Also be aware that you cannot do this swap while your server is running, as calling SHUTDOWN on the running server will save its memory contents to its dump file, thus overwriting the copy you just placed there. First shutdown the server. Then overwrite the dump file. Then start the server again. – Houen May 08 '12 at 16:50
  • @Mojo I have the exact same questions. – dranxo Jan 22 '13 at 00:04
  • 9
    If you use AOF logging (in redis.conf, `appendonly = yes`), set it to `no` before starting the Redis server--otherwise it will not load the new data set. Once the data set is loaded into memory, turn it back on, both in memory (`config set appendonly yes`) and in the config file. – Matthew Ratzloff Mar 08 '13 at 23:42
  • 5
    On Ubuntu, the Redis conf file is stored in `/etc/redis/redis.conf`, and you can search through it to find where your `.rdb` files are: `cat /etc/redis/redis.conf | grep "rdb"`. In my case it's `/var/lib/redis` – Herman Schaaf Apr 29 '13 at 13:05
  • +1 for Matthew Ratzloff. You need to disable `appendonly = yes` first. – Ankit Jain Nov 11 '13 at 14:10
  • The file may also be in: /var/lib/redis/6379/ – RonnyKnoxville Dec 02 '14 at 10:41
  • 6
    `redis-cli config get dir` would give you the directory in which `.rdb` is stored. – Kishor Pawar Apr 04 '16 at 06:56
36

If you have the connectivity between servers it is better to set up replication (which is trivial, unlike with SQL) with the new instance as a slave node - then you can switch the new node to master with a single command and do the move with zero downtime.

Tom Clarkson
  • 16,074
  • 2
  • 43
  • 51
  • 1
    I do have connectivity. So I can use the slaveof configuration in the new server and set it to the old server's IP address. But how do I know when the data transfer is complete between the master and the slave? And after that, how do I promote the slave to master? – ErJab May 15 '11 at 01:41
  • I think the INFO command will tell you when it is ready. However, that doesn't matter too much - since it is replication rather than a onetime copy, you can leave both nodes in place for as long as you want before switching off the old node. SLAVEOF NONE is the command to promote the new node to master. – Tom Clarkson May 15 '11 at 02:07
  • 14
    Sounds like a great solution — would be nice with some command examples! – knutole Feb 28 '14 at 14:20
25

It is also possible to migrate data using the SLAVEOF command:

SLAVEOF old_instance_name old_instance_port

Check that you have receive the keys with KEYS *. You could test the new instance by any other way too, and when you are done just turn replication of:

SLAVEOF NO ONE

Since Redis 5.0 is recommended to use REPLICAOF as SLAVEOF is deprecated - see manual

estani
  • 24,254
  • 2
  • 93
  • 76
14

Nowadays you can also use MIGRATE, available since 2.6.

I had to use this since I only wanted to move the data in one database and not all of them. The two Redis instances live on two different machines.

If you can't connect directly to Redis-2 from Redis-1, use ssh port binding:

 ssh user@redis-2.foo.com -L 1234:127.0.0.1:6379

A small script to loop all the keys using KEYS and MIGRATE each key. This is Perl, but hopefully you get the idea:

 foreach ( $redis_from->keys('*') ) {

    $redis_from->migrate(
        $destination{host},    # localhost in my example
        $destination{port},    # 1234
        $_,                    # The key
        $destination{db},
        $destination{timeout} 
    );
 }

See http://redis.io/commands/migrate for more info.

Øyvind Skaar
  • 2,278
  • 15
  • 15
7

Key elements of a zero-downtime migration is:

In short:

  1. setup a target redis (empty) as slave of a source redis (with your data)
  2. wait for replication finish
  3. permit writes to a target redis (which is currently slave)
  4. switch your apps to a target redis
  5. wait for finish datastream from master to slave
  6. turn a target redis from master to slave

Additionally redis have options which allows to disable a source redis to accept writes right after detaching a target:

  • min-slaves-to-write
  • min-slaves-max-lag

This topic covered by

Very good explanation from RedisLabs team https://redislabs.com/blog/real-time-synchronization-tool-for-redis-migration (use web.archive.org)

And even their interactive tool for migrate: https://github.com/RedisLabs/redis-migrate

x'ES
  • 554
  • 5
  • 15
4

To check where the dump.rdb has to be placed when importing redis data,

start client

$ redis-cli

and

then

redis 127.0.0.1:6379> CONFIG GET *
 1) "dir"
 2) "/Users/Admin"

Here /Users/Admin is the location of dump.rdb that is read from server and therefore this is the file that has to be replaced.

A.L
  • 10,259
  • 10
  • 67
  • 98
Vinay Vemula
  • 3,855
  • 1
  • 21
  • 24
2
source_host=xxx
source_port=6379
source_db=10
source_auth=xxx

target_host=yyyyy
target_port=6379
target_db=12
target_auth=yyyyy


redis-cli -a $source_auth -h $source_host -p $source_port -n $source_db keys \* | while read key; do
    echo "redis-cli -h $source_host -p $source_port -a $source_auth -n $source_db MIGRATE $target_host $target_port "" $target_db 5000 COPY AUTH $target_auth KEYS $key"
    redis-cli -h $source_host -p $source_port -a $source_auth -n $source_db MIGRATE $target_host $target_port "" $target_db 5000 COPY AUTH $target_auth KEYS $key 
done

I's pretty good with my case, tested it.

Sang Nguyen
  • 113
  • 8
1

you can also use rdd

it can dump & restore a running redis server and allow filter/match/rename dumps keys

r043v
  • 1,859
  • 1
  • 15
  • 25
1

I also want to do the same thing: migrate a db from a standalone redis instance to a another redis instances(redis sentinel).

Because the data is not critical(session data), i will give https://github.com/yaauie/redis-copy a try.

tangxinfa
  • 1,410
  • 13
  • 12
1

The simple way I found to export / Backup Redis data (create dump file ) is to start up a server via command line with slaveof flag and create live replica as follow (assuming the source Redis is 1.2.3.4 on port 6379):

/usr/bin/redis-server --port 6399 --dbfilename backup_of_master.rdb --slaveof 1.2.3.4 6379
Maoz Zadok
  • 4,871
  • 3
  • 33
  • 43
0

I just published a command line interface utility to npm and github that allows you to copy keys that match a given pattern (even *) from one Redis database to another.

You can find the utility here:

https://www.npmjs.com/package/redis-utils-cli

Gabriel McAdams
  • 56,921
  • 12
  • 61
  • 77
-3

redis-dump finally worked for me. Its documentation provides an example how to dump a Redis database and insert the data into another one.

JustAC0der
  • 2,871
  • 3
  • 32
  • 35