Git Product home page Git Product logo

rump's Introduction

Rump

Go Report Card GoDoc CI

Hot sync two Redis databases using dumps.

Why

There's no easy way to sync data from an AWS ElastiCache or GCP MemoryStore Redis cluster; the standard commands BGSAVE and SLAVEOF are blocked.

Rump is able to live sync Redis databases across cloud providers by only using SCAN, DUMP and RESTORE.

It's used at Sticker Mule to keep staging and development environments in sync with the production AWS/GCP Redis clusters.

Examples

# Sync local Redis DB 1 to DB 2.
$ rump -from redis://127.0.0.1:6379/1 -to redis://127.0.0.1:6379/2

# Sync ElastiCache cluster to local.
$ rump -from redis://production.cache.amazonaws.com:6379/1 -to redis://127.0.0.1:6379/1

# Sync protected ElastiCache via EC2 port forwarding.
$ ssh -L 6969:production.cache.amazonaws.com:6379 -N [email protected] &
$ rump -from redis://127.0.0.1:6969/1 -to redis://127.0.0.1:6379/1

# Dump GCP MemoryStore to file.
$ rump -from redis://10.0.20.2:6379/1 -to /backup/memorystore.rump

# Restore backup to ElastiCache.
$ rump -from /backup/memorystore.rump -to redis://production.cache.amazonaws.com:6379/1

# Sync with verbose mode disabled.
$ rump -from redis://127.0.0.1:6379/1 -to redis://127.0.0.1:6379/2 -silent

# Sync with TTLs.
$ rump -from redis://127.0.0.1:6379/1 -to redis://127.0.0.1:6379/2 -ttl

Features

  • Uses SCAN instead of KEYS to avoid DoS servers.
  • Doesn't use any temp file.
  • Can sync any key type.
  • Can optionally sync TTLs.
  • Uses buffered channels to optimize slow source servers.
  • Uses implicit pipelining to minimize network roundtrips.
  • Supports two-step sync: dump source to file, restore file to database.
  • Supports Redis URIs with auth.
  • Offers the same guarantees of the SCAN command.

Demo

asciicast

Development

# requirements: docker, docker-compose (dc)
dc up # watch/run Rump tests and a Redis container
dc run --rm rump sh # get shell on Rump container
dc run --rm redis sh; redis-cli -h redis # get Redis console

Install

Binaries can be found on the releases page.

curl -SL https://github.com/stickermule/rump/releases/download/1.0.0/rump-1.0.0-linux-amd64 -o rump \
  && chmod +x rump;
./rump

You can run rump in a container following the Dockerfile.example.

Mentions

Maintainers

nixtrace

Collaboration & License

rump's People

Contributors

badshark avatar jdorfman avatar jon1op avatar nixtrace avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rump's Issues

ttl support

Hello,

rump is a great tool however in certain situations having ttl set to 0 does not work okay (session data etc). May I suggest adding a separate flag for ttl with 0 default, so that default behavior does not change. Please see my local change at master...eugenetaranov:ttl, if you find it useful, I'll be happy to make a PR.

Unexpected element type for Strings, got type redis.Error

Hy,
I have an interesting issue by some redis clusters.
We have 3 redis clusters in AWS.
Old, New1, New2
When I do sync from old to new1, then everything goes fine.
When I do sync from old to new 2 I get following error:
redigo: unexpected element type for Strings, got type redis.Error

I can log into new2 with redis-cli, so don't see what could be wrong, compared to new1. new1 and new 2 are identical clusters, same instance size, count, etc..

Thank you

Authentication issue

Report

  • Dump remote Redis with rump and with AUTH to local rump file
$ ./rump -from redis://h:[email protected]:PORT/0 -to ./hero-redis.rump -ttl

rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw

SUCCESS
  • Connect to the destination ElastiCache using redis_uri format and redis-cli
echo $REDIS_URL 
redis://[email protected]:6379

redis-cli -u ${REDIS_URL} INFO SERVER
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Server
redis_version:4.0.10
redis_git_sha1:0
redis_git_dirty:0
redis_build_id:0
redis_mode:standalone
os:Amazon ElastiCache
...
  • [!] Restore data to the the destination ElastiCache
./rump -from ./hero-redis.rump -to redis://[email protected]:6379/0

rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
signal: exit
NOAUTH Authentication required.

Notes

I have seen #26 and I have downloaded rump 1.0.0 from GitHub Release, but still facing the issue

Rump doesn't copy all keys

In a test environment we did a test transfer between two redis cluster, and we found that there was a bigger number of differences between key numbers.
Dest node 1625684
Source node 1673187

How can this happen, or how can we mitigate these issues? How can we debug what cases them?
Thank you

signal: exit redis read: exit ERR Invalid TTL value, must be >= 0

Report

Sync with ttl terminated by 'ERR Invalid TTL value, must be >= 0'
The source AWS ElastiCache redis version is 3.2.10
rump -from redis://redis-002.ruf311.0001.cnw1.cache.amazonaws.com.cn:6379/0 -to redis://127.0.0.1:6379/0 -ttl
signal: exit

redis read: exit
ERR Invalid TTL value, must be >= 0

file write: exit Error

Report

I am hitting an error when running rump in a Kubernetes pod(if that matters). The failure appears to happen here but also reports a TCP i/o timeout.

Can you confirm whether this is a filesystem i/o issue or an issue talking to Redis?

Is it possible to set timeouts higher and prevent this issue?

I see around a 7x increase in CPU usage but still not over 55%.

Node type: cache.m3.medium
Engine: Redis
Engine Version Compatibility: 2.8.24

file write: exit

signal: exit
read tcp 10.X.X.10:57824->10.Z.Z.145:6379: i/o timeout

Please explain -ttl option

Report

Please update the docs for the ttl option. It is given without explanation and the example in the README appears incorrect (it lacks a value, which is apparently required).

  1. What happens to records with a TTL when the ttl option is not given?
  2. What happens when it is given?

Test Coverage

Hello.

First of all, thank you very much for this. Very cool.

I noticed that there's no test coverage and, if it's okay, I'd like to add/increase that? I'm on vacation for the next fortnight, but I can get a PR in before the end of the month?

Anthony.

Include a way to dump the entire redis cluster

Report

Currently rump will only deal with the specified URI database numbers, or, if those are omitted, it will use 0 as both source and destination. Having a way of moving all the source database numbers to the cluster would be nice

EOF output but no keys migrated to destination system

Report

Trying to migrate from one Redis system to a Digital Ocean managed Redis, I get EOF as the only output and no keys in the destination system, I've tried system to system, and I've also tried writing to a backup.rump and source that to a destination and get the same output.

Any suggestions?

rump -from redis://:password@test-redis:6379/0 -to redis://default:[email protected]:25061/0
EOF

Dumping to a file:

rump -from redis://:password@test-redis:6379/0 -to backup.rump
rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwwrrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
signal: exit
done

Trying to restore from the file:

rump -from backup.rump -to rediss://default:[email protected]:25061/0
EOF

Deleted keys are not removed from sync endpoint

Report

I have been using RUMP last few months to Sync a primary redis endpoint with a failover (in the even of DR). Ive noticed that RUMP is actually copying keys across and not deleted keys that have been removed from primary. For example primary endpoint has around 166 thousand keys, while the failover now has 26 million. is there a flag i am missing to do this or is it not a-part of the functionality? Thank you

Question: Is a cluster with replicas supported?

Report

Question: I have a redis cluster created from the bitnami helm chart here: https://github.com/bitnami/charts/tree/master/bitnami/redis-cluster/#installing-the-chart with 3 master nodes and 3 replica nodes. I am trying to copy data from another redis cluster (with no replicas) into this cluster but I keep getting errors like this:

./rump -from redis://redis-telem-cache-stg-ksat-m-1-redis-cluster:6379 -to redis://10.255.8.12:6379 -ttl
r
signal: exit
rr
redis read: exit
MOVED 4042 10.255.8.14:6379

Note: Above 10.255.8.12:6379 is one of the master nodes.

$ kk exec rails-cache-stg-redis-ksat-m-1-redis-cluster-0 -- redis-cli --cluster check 10.255.8.10:6379
Defaulting container name to rails-cache-stg-redis-ksat-m-1-redis-cluster.
Use 'kubectl describe pod/rails-cache-stg-redis-ksat-m-1-redis-cluster-0 -n default-minim-private' to see all of the containers in this pod.
10.255.8.15:6379 (fbdd5a4e...) -> 14029 keys | 5462 slots | 1 slaves.
10.255.8.12:6379 (b3718ac7...) -> 568 keys | 5461 slots | 1 slaves.
10.255.8.14:6379 (8790c578...) -> 487 keys | 5461 slots | 1 slaves.
[OK] 15084 keys in 3 masters.
0.92 keys per slot on average.
>>> Performing Cluster Check (using node 10.255.8.10:6379)
S: 8500263462d98613bc6e1172106ddcd37f5976a6 10.255.8.10:6379
   slots: (0 slots) slave
   replicates b3718ac766349261d819c9923cd915fc43d70352
M: fbdd5a4eebe77b49ec984ec953ec098fe262d320 10.255.8.15:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 4b371b26a9b5b3d0f23d2c965197f0bf3cbc355b 10.255.8.11:6379
   slots: (0 slots) slave
   replicates 8790c57879627039f3d74cc599e61707d33d93d4
M: b3718ac766349261d819c9923cd915fc43d70352 10.255.8.12:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: f01bd775618fd6de9a18160186a48a37b469da03 10.255.8.13:6379
   slots: (0 slots) slave
   replicates fbdd5a4eebe77b49ec984ec953ec098fe262d320
M: 8790c57879627039f3d74cc599e61707d33d93d4 10.255.8.14:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Does rump currently support clusters with replicas? If it does can you recommend a way to diagnose/debug this further?

Thanks.

Include a way to only dump keys matching patterns

Report

I had a situation where I had a Redis full of stuff and I wanted to only transfer the keys matching some-pattern* to another Redis. For now, Rump doesn't support dumping only a pattern; however, both Redis and Radix supports it.

It would be great if Rump supported dumping keys matching a pattern.

Improve performance

Report

First of all thanks for a nice and robust tool!

I thought it could use some performance improvements. Currently scanning and dumping data from bigger data sets takes quite a bit of time and there are a couple reasons for that:

  • When observing the reads and writes they happen almost serially. Making them concurrent would certainly improve the situation. By making the reads concurrent we should also be able to scan ahead (currently when scanning we're idling while fetching the next chunk of data).

  • Another thing is the default COUNT returned when scanning is 10. Increasing it is definitely a low-hanging fruit, but for obvious reasons it cannot be set too high and since it wouldn't make sense to hard-code an arbitrary value I feel that giving the user an option to increase the COUNT manually is the right thing to do.

Add support for Elasticache with In-Transit Encryption

Report

The current version of rump does not work with an Elasticache Redis cache cluster where in-transit encryption (TLS) is enabled. If you try it, you will only get errors about blocked connections.
(More about in-transit encryption: https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html)

Would you be interested in a PR to add support for TLS encrypted connections? I have a private version where this works for my use case. If you are interested in a PR, I could create a more general solution that works with all combinations of encrypted / not encrypted connections and files.

It requires a change to the URL validation, an upgrade of the radix library and some changes to the run package where the connections are managed.

yaml support

I wonder if it would make sense to have support for yaml config's. That way you could do:

$ rump -bookmark local
$ rump -b prod

_config.yml:

bookmark:
  local:
    from: 'redis://127.0.0.1:6379/1'
    to: 'redis://127.0.0.1:6379/2'
  prod:
    from: 'redis://production.cache.amazonaws.com:6379/1'
    to: 'redis://127.0.0.1:6379/1'

Add support to sync only keys matching a certain pattern

I've used this tool it in the past and it works great, but now I have a case in which I need to dump keys that only match a certain pattern instead of dumping all the keys of a DB.

MATCH option of SCAN command can be used to add this support.

The following commit fzunino@67bc2e1 adds this support adding an optional command line argument called match and using * as default value, maintaining the current semantic.

Let me know and I can submit a PR with this commit.

does redis -> elasticache work?

I've just tried to make a run between SRC=a regular redis and DEST=an elasticache server.

  • Rump detects the keys as I see progress on the screen, proportionate to the keys
  • but when I look at the keys in the DEST elasticache I only see
    1) "ElastiCacheMasterReplicationTimestamp"

Is this supported?

The elasticserver info:

# Server
redis_version:2.8.24
redis_git_sha1:0
redis_git_dirty:0
redis_build_id:0
redis_mode:standalone
os:Amazon ElastiCache
arch_bits:64

Doesnt show error if auth is enabled

I just noticed that if dumping TO a cluster with AUTH enabled, and NOT specifying the auth password in the "connection string", rump will not show any error, leading the user to believe that a dump has been performed (when it in fact has not)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.