Migrating Redis databases
If you are replacing a Heroku Redis add-on or another pre-provisioned Redis service, also review the
Control Plane Redis Template Catalog page. The catalog
template covers a Redis master-replica deployment with Redis Sentinel, optional persistent storage, and optional backups.
It is the better fit when you need Redis Sentinel, public endpoint access, or backup options beyond what the redis and
redis2 repo templates provide.
There are two templates examples in this repo:
redis- basic non-persistent template. It is good for review-apps or staging or where no persistence is requiredredis2- basic persistent template. Good for production where persistence is needed, but cluster is overkill.
Option 1: use SLAVEOF (easier way)
- create a redis workload that will accept data
- execute
SLAVEOF source_host source_port, if needed usemasterauthto provide auth details - wait for replication to pick up all changes (usually quickly), use
INFOorDBSIZEto check progress - stop app completely and ensure nothing is writing to any of redises
- execute
SLAVEOF no oneto disconnect replication - switch
REDIS_URLin the app to point to new server - start the app
Option 2: use Redis-RIOT (harder way, where option 1 is not possible)
General considerations:
-
Heroku uses self-signed TLS certificates, which are not verifiable. It needs special handling by setting The tool that satisfies those criteria is Redis-RIOT
-
We are moving to private Redis that don't have a public URL, so have to do it from a Control Plane GVC container.
The tool that satisfies those criteria is Redis-RIOT
Heroku Redis:
As Redis-RIOT says, master redis should have keyspace-notifications set to KA to be able to do live replication.
To do that:
heroku redis:keyspace-notifications -c KA -a my-app
Connect to heroku Redis CLI:
heroku redis:cli -a my-app
Control Plane Redis:
Connect to Control Plane Redis CLI:
# open cpflow interactive shell
cpflow run bash -a my-app
# install redis CLI if you don't have it in Docker
apt-get update
apt-get install redis -y
# connect to local cloud Redis
redis-cli -u MY_CONTROL_PLANE_REDIS_URL -p 6379
Useful Redis CLI commands:
Quick-check keys qty:
info keyspace
# Keyspace
db0:keys=9496,expires=2941,avg_ttl=77670114535
Create a Control Plane sync workload
name: riot-redis
suspend: true
min/max scale: 1/1
firewall: all firewalls off
image: fieldengineering/riot-redis
CPU: 1 Core
RAM: 1 GB
command args:
--info
-u
rediss://...your_heroku_redis_url...
--tls-verify=NONE
replicate
-h
...your_control_plane_redis_host...
--mode
live
Sync process
- open 1st terminal window with heroku redis CLI, check keys qty
- open 2nd terminal window with controlplane redis CLI, check keys qty
- start sync container
- open logs with
cpflow logs -a my-app -w riot-redis - re-check keys sync qty again
- stop sync container
Result:
Setting commit interval to default value (1)
Setting commit interval to default value (1)
Job: [SimpleJob: [name=snapshot-replication]] launched with the following parameters: [{}]
Executing step: [snapshot-replication]
Scanning 0% ╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0/8891 (0:00:00 / ?)Job: [SimpleJob: [name=scan-reader]] launched with the following parameters: [{}]
Executing step: [scan-reader]
Scanning 61% ━━━━━━━━━━━━━━━━╸━━━━━━━━━━ 5460/8891 (0:00:07 / 0:00:04) 780.0/sStep: [scan-reader] executed in 7s918ms
Closing with items still in queue
Job: [SimpleJob: [name=scan-reader]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 7s925ms
Scanning 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9482/9482 (0:00:11 / 0:00:00) 862.0/s
Step: [snapshot-replication] executed in 13s333ms
Executing step: [verification]
Verifying 0% ╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0/8942 (0:00:00 / ?)Job: [SimpleJob: [name=RedisItemReader]] launched with the following parameters: [{}]
Executing step: [RedisItemReader]
Verifying 2% ╺━━━━━━━━━━━━━━━━━ 220/8942 (0:00:00 / 0:00:19) ?/s >0 T0 ≠Step: [RedisItemReader] executed in 7s521ms
Closing with items still in queue
Job: [SimpleJob: [name=RedisItemReader]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 7s522ms
Verification completed - all OK
Step: [verification] executed in 7s776ms
Job: [SimpleJob: [name=snapshot-replication]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 21s320ms
Total sync time ~1min