5

Is there a command to move redis keys from one database to another or is it possible only with lua scripting??

There has been this type of question asked perviously redis move all keys but the answers are not appropriate and convincing for a beginner like me.

3 Answers 3

5

u can use "MOVE" to move one key to another redis database;

the text below is from redis.io

MOVE key db

Move key from the currently selected database (see SELECT) to the specified destination database. When key already exists in the destination database, or it does not exist in the source database, it does nothing. It is possible to use MOVE as a locking primitive because of this.

Return value

Integer reply, specifically:

  • 1 if key was moved.
  • 0 if key was not moved.
Sign up to request clarification or add additional context in comments.

3 Comments

move command moves only a single key, what if i want to move a set of keys?
@aarish i don't have some good advice. i think u can use KEYS and MOVE to do it with an script.
You could do a MULTI/EXEC block so the commands are buffered and executed all at once.
5

I think this will do the job:

redis-cli keys '*' | xargs -I % redis-cli move % 1 > /dev/null 

(1 is the new database number, and redirection to /dev/null is in order to avoid getting millions of '1' lines - since it will move the keys one by one and return 1 each time)

Beware that redis might run out of connections and then will display tons of such errors:

Could not connect to Redis at 127.0.0.1:6379: Cannot assign requested address

So it could be better (and much faster) to just dump the database and then import it into the new one.

1 Comment

If you have millon of keys, this command will block your server for a long time. It's better to use the command SCAN that will give you the keys in a cursor non-blocking more optimal way than the whole long blocking KEY command.
0

If you have a big database with millions of keys, you can use the SCAN command to select all the keys (without blocking like the dangerous KEYS command that even Redis authors do not recommend).

SCAN gives you the keys by "pages" one by one and the idea is to start at page 0 (formally called CURSOR 0) and then continue with the next page/cursor until you hit the end (the stop signal is when you get the CURSOR 0 again).

You may use any popular language for this like Redis or Ruby or Scala. Here a draft using Bash Scripting:

#!/bin/bash -e REDIS_HOST=localhost PAGE_SIZE=10000 KEYS_TO_QUERY="*" SOURCE_DB=0 TARGET_DB=1 TOTAL=0 while [[ "$CURSOR" != "0" ]]; do CURSOR=${CURSOR:-0} >&2 echo $TOTAL:$CURSOR KEYS=$(redis-cli -h $REDIS_HOST -n $SOURCE_DB scan $CURSOR match "$KEYS_TO_QUERY" count $PAGE_SIZE) unset CURSOR for KEY in $KEYS; do if [[ -z $CURSOR ]]; then CURSOR=$KEY else TOTAL=$(($TOTAL + 1)) redis-cli -h $REDIS_HOST -n $SOURCE_DB move $KEY $TARGET_DB fi done done 

IMPORTANT: As usual, please do not copy and paste scripts without understanding what is doing, so here some details:

The while loop is selecting the keys page by page with the SCAN command and with every key then running the MOVE command.

The SCAN command will return the next cursor in the first line and then the rest of the lines will be the found keys. The while loop starts with the variable CURSOR not defined and then defined in the first loop (this is some magic to just stop in the next CURSOR 0 that will signal the end of the scanning)

PAGE_SIZE is the value of how long will be each scan query, lower values will impact very low on the server but will be slow, bigger values will make the server "sweat" but faster ... here the network is impacted, so try to find a sweet spot around 10000 or even 50000 (ironically values of 1 or 2 may stress also the server but due to the network wrapping part of each query)

KEYS_TO_QUERY: It's a pattern on the keys you want to query, like "*balance*" witll select the keys that include balance in the name of the key (don't forget to include the quotes to avoid syntax errors) ... additionally you can do the filtering at script side, just query all the key with "*" and add a bash scripting if conditional, this will be slower but if you cannot find a pattern for your keys selection this will help.

REDIS_HOST: using localhost by default, change it to any server you like (if you are using a custom port other than the default port 6379 you can also include it with something like myredisserver:4739)

SOURCE_DB: the database ID you want the keys move from (by default 0)

TARGET_DB: the database ID you want the keys move to (by default 1)

You can use this script to execute other commands or checks with the keys, just replace the MOVE command call for anything you may need.

NOTE: To move keys from one Redis server to another Redis server (this is not only moving between internal databases) you can use redis-utils-cli from the NPM packages here -> https://www.npmjs.com/package/redis-utils-cli

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.