This document describes options to migrate data from an older a9s Redis version to a newer one, for example how to migrate data from a Redis 5.x service instance to a Redis 6.x service instance.
Migrate Redis 5.x to 6.x
The main strategy to migrate the whole dataset from one Redis service instance to another will use the Redis MIGRATE feature.
- Downtime during the migration. It will depend on the amount of data inside your Redis service instance and network connection throughput between both Redis service instances.
- If a Redis service instance uses a logical database, in order to migrate the whole Redis database, it is
necessary to migrate the Redis logical database one after another. A piece of information about logical databases:
Out of the box, a Redis instance supports 16 logical databases. These databases are effectively siloed off from one another, and when you run a command in one database, it doesn't affect any of the data stored in other databases in your Redis instance.
When to Migrate
It is highly recommended to isolate the Redis service instance before making the migration. This avoids data inconsistency in case the Redis service instance is receiving new data and making the migration at the same time.
Also the Redis MIGRATE feature says:
The command is atomic and blocks the two instances for the time required to transfer the key, at any given time the key will appear to exist in a given instance or in the other instance, unless a timeout error occurs.
Hence, during the migration, there will be a system downtime, therefore it is suggested to make the migration in a wise timeline, likely in the moment in the week, the day, and period with less impact for the client of this specific Redis service instance. The application developer must decide wisely.
Based on internal and isolated tests, migrating 1GB takes about 50 seconds on average. However, it will depend on each environment and its particularities. Be aware that it might take some time, so it is necessary to plan wisely.
- Install redis-cli.
Create New a9s Redis 6.x Instance
Create a new and empty a9s Redis 6.x service instance that will be the target for the data migration from an existing Redis 5.x service instance.
- Do not insert any data inside of the machine before the migration and checking are done.
- Create a service instance with the same capabilities or greater.
The goal is to give access to the application developer to the Redis service instance. And for this, it is necessary to make a SSH tunnels to the Redis 5.x service instance.
In the end, we want to achieve the following scenario below.
(port 6379) (port 6379)
/----> * Redis 5.x * ----- Redis MIGRATE -----> * Redis 6.x *
* CF Application * (via SSH Tunnel) [infrastructure network]
/ [Developer network]
* Developer Machine * (local port 6379)
It is possible to access any of the a9s Data Services locally. That means you can connect with a local client to the service for any purpose such as debugging. Cloud Foundry (CF) provides a smart way to create SSH forward tunnels via a pushed application. For more information about this feature see the Accessing Apps with SSH section of the CF documentation.
First of all you must have an application bound to the service. How to do this see Bind an application to a Service Instance.
cf ssh support must be enabled in the platform. Ask your platform operator if you are not sure.
Follow the section Create a Tunnel to The Service to create the reverse tunnel.
(Optional) Save RDB File (Redis Dump File)
Note: It is an advisable safe step, to avoid losing data for whatever reason. It is desirable to keep it stored safely until the confirmation of the database consistency after the migration.
It is possible to download the RDB file for a specific service instance using redis-cli:
redis-cli -h <a9s-redis-5.x-host> -p 6379 -a <password> --rdb /tmp/dump.rdb
Alternatively, you can download the latest backup from a9s Service Dashboard.
Isolate The Node Before The Migration
Avoid client connections and hence stop writing data into the Redis service instance during the migration.
You may achieve it by unbinding all applications from your Redis service instance.
Perform the Migration
redis-cli to retrieve the keys and migrate between the Redis service instance. Replace all
placeholder values in the command below and execute it afterward.
redis-cli -h <a9s-redis-5.x-host> -p <a9s-redis-5.x-port> -a <a9s-redis-5.x-password> -n <a9s-redis-5.x-logical-database-number> --raw KEYS '*' \
| xargs redis-cli -h <a9s-redis-5.x-host> -p <a9s-redis-5.x-port> -a <a9s-redis-5.x-password> MIGRATE \
<a9s-redis-6.x-host> <a9s-redis-6.x-port> "" <a9s-redis-5.x-logical-database-number> <timeout> \
COPY AUTH <a9s-redis-6.x-password> KEYS > /tmp/migration-output-checker.txt
- This command must be executed in the application developer machine once he/she only will have access to the Redis service instance via the reverse tunnel.
- The first command (
redis-cli --raw KEYS '*') lists all keys.
- The second command (
xargs redis-cli MIGRATE <destination-host> <destination-port> "" 0 5000 COPY AUTH <pass> KEYS) uses the output of the first command to MIGRATE the data of the source host to the destination host.
COPYargument must be present in the command in order to not delete the key from the source host.
- If you are using the logical database and you have more than one, this command must be executed as many times
as the amount of the logical databases. It is necessary to change the
|The domain or ip of the host that contains data to be migrated||Yes|
|The port of the host that contains data to be migrated||Yes|
|The password of the host that contains data to be migrated||---||Yes|
|The Redis database logical number. Default: 0||0||Yes|
|The domain or ip of the host that the data will be migrate.||---||Yes|
|The port of the host that the data will be migrate.||Yes|
|The password of the host that the data will be migrate.||---||Yes|
|The timeout of each Redis MIGRATION operation||Yes|
How To Find The Redis 6.x Information
- Ensure, you already have Redis 6.x UP and running.
- First, create a service key.
cf create-service-key <cf-redis-6.x-service-instance> key
- Retrieve the Redis 6.x host domain (
cf service-key <cf-redis-6.x-service-instance> key | grep '"host"'
- Retrieve the Redis 6.x port (
cf service-key <cf-redis-6.x-service-instance> key | grep '"port"'
- Retrieve the Redis 6.x password (
cf service-key <cf-redis-6.x-service-instance> key | grep '"password"'
Check The Database Consistency
Check the output of MIGRATE requests at
migration-output-checker.txt content is the output result of each MIGRATE
request made to the Redis instance. It must contain only "OK".
Check the content:
cat /tmp/migration-output-checker.txt | grep --invert-match "OK"
The output of this command must be empty otherwise it means the output was different of the expected and so meaning something wrong happened during migration.
Errors example and some troubleshooting:
- The key does not exists in the source Redis service instance.
Double check if the first part of the command (
redis-cli --raw KEYS '*') is correct.
The output of this command must have all keys present in the Redis instance.
- Likely it is a problem in the communication between the two Redis instances.
IOERR error or timeout connecting to the client
Double check if the Redis 5 service instance has access to the Redis 6 service instance.
- Authentication does not work.
ERR Target instance replied with error: ERR invalid password
Double check if the password is correct.
Compare Data Between the Redis Service Instances
Note: By chance, Redis 5 has not been isolated and kept receiving new data during the migration the following checking will not work.
- Perform the
info keyspaceredis-cli command under each host.
redis-cli -h <a9s-redis-5.x-host> -p <a9s-redis-5.x-port> -a <a9s-redis-5.x-password> info keyspace
redis-cli -h <a9s-redis-6.x-host> -p <a9s-redis-6.x-port> -a <a9s-redis-6.x-password> info keyspace
expires must be equals .
- Perform the
info memoryredis-cli command under each host.
redis-cli -h <a9s-redis-5.x-host> -p <a9s-redis-5.x-port> -a <a9s-redis-5.x-password> info memory | grep "used_memory:\|used_memory_human"
redis-cli -h <a9s-redis-6.x-host> -p <a9s-redis-6.x-port> -a <a9s-redis-6.x-password> info memory | grep "used_memory:\|used_memory_human"
The values must be similar with only a few kilobytes of difference.
Compare Keys Between the Redis Service Instances
This step will compare all keys between both Redis instances.
- Get all source Redis service instance keys and sort them.
redis-cli -h <a9s-redis-5.x-host> -p <a9s-redis-5.x-port> -a <a9s-redis-5.x-password> --raw keys '*' > /tmp/redis5.txt
sort --parallel=2 -uo /tmp/redis5-sorted.txt /tmp/redis5.txt
- Get all destination Redis service instance keys and sort them.
redis-cli -h <a9s-redis-6.x-host> -p <a9s-redis-6.x-port> -a <a9s-redis-6.x-password> --raw keys '*' > /tmp/redis6.txt
sort --parallel=2 -uo /tmp/redis6-sorted.txt /tmp/redis6.txt
- Compare both Redis service instances keys
diff /tmp/redis5-sorted.txt /tmp/redis6-sorted.txt
The output must not have differences.