Skip to content

Instantly share code, notes, and snippets.

@felipecwb
Last active January 15, 2021 05:22
Show Gist options
  • Save felipecwb/437224fd7f29f1d36267509a34e17765 to your computer and use it in GitHub Desktop.
Save felipecwb/437224fd7f29f1d36267509a34e17765 to your computer and use it in GitHub Desktop.
Redis Migration script
#!/bin/bash
REDIS_CLI_PREFIX="redis-cli"
DEFAULT_PORT=6379
DEFAULT_DB=0
log () { echo "[$(date +%Y-%m-%dT%H:%M:%S:%:z)] $@" >&2; }
usage () {
echo -e ">>> RedisMigration:
Run redis migration from source server to destination.
Usage: $0 SOURCE DESTINATION
$0 host[:port][:db] host[:port][:db]
$0 0.0.0.0 127.0.0.1
$0 0.0.0.0:$DEFAULT_PORT 127.0.0.1:$DEFAULT_PORT
$0 0.0.0.0:$DEFAULT_PORT:$DEFAULT_DB 127.0.0.1:$DEFAULT_PORT:$DEFAULT_DB
Options:
-h, --help\tPrint usage
@author Felipe Francisco <[email protected]>
@credits https://elliotchance.medium.com/migrating-data-between-redis-servers-without-downtime-429e4c8048e6
"
exit 1
}
create_redis_cli () {
host="$(echo $1 | cut -d: -f1)"
port="$(echo $1 | cut -d: -f2)"
db="$( echo $1 | cut -d: -f3)"
if [ -z "$port" ] || [ "$port" = "$host" ]; then
port=$DEFAULT_PORT
fi
if [ -z "$db" ] || [ "$db" = "$host" ]; then
db=$DEFAULT_DB
fi
if [ -z "$host" ]; then
log ERROR "Host cannot be empty"
exit 2
fi
echo "$REDIS_CLI_PREFIX -h $host -p $port -n $db"
}
redis_ping () {
log INFO "ping redis server: \$($@ ping)"
$@ ping
return_exit=$?
if [ "$return_exit" != 0 ]; then
log ERROR "\$($@ ping) Exited with $return_exit"
exit 3
fi
log DEBUG "\$($@ ping): connected!"
}
### Main:
# HELP check
if [ -z "$1" ] || [ -z "$2" ] \
|| [ "$1" = "-h" ] || [ "$1" = "--help" ];
then
usage
fi
OLD_REDIS_CLI="$(create_redis_cli $1)"
NEW_REDIS_CLI="$(create_redis_cli $2)"
redis_ping $OLD_REDIS_CLI
redis_ping $NEW_REDIS_CLI
log "Redis Migration: START..."
DUMP_FILE="/tmp/redis_${1//:/-}.dump"
for KEY in $($OLD_REDIS_CLI --scan); do
$OLD_REDIS_CLI --raw DUMP "$KEY" | head -c-1 > $DUMP_FILE
TTL=$($OLD_REDIS_CLI --raw TTL "$KEY")
case $TTL in
-2)
$NEW_REDIS_CLI DEL "$KEY"
;;
-1)
$NEW_REDIS_CLI DEL "$KEY"
cat $DUMP_FILE | $NEW_REDIS_CLI -x RESTORE "$KEY" 0
;;
*)
$NEW_REDIS_CLI DEL "$KEY"
cat $DUMP_FILE | $NEW_REDIS_CLI -x RESTORE "$KEY" "$TTL"
;;
esac
log "$KEY (TTL = $TTL)"
done
log "Redis Migration: DONE!"
exit 0
@felipecwb
Copy link
Author

to run over databases at once:

#!/bin/bash

for n in $(seq 0 10); do
    ./migrate-redis.sh $1:$n $2:$n &
done

./script first-redis:6379 second-redis:6379

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment