Skip to content

Commit ef5d415

Browse files
author
Jamie Curnow
committed
Added List migrate support
1 parent 3670896 commit ef5d415

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
Redis Migrator will take the keys from one server/db and
44
transfer them to another server/db.
55

6+
## How does it work?
7+
8+
Simply it iterates over the keys in SOURCE and recreates them on DESTINATION.
9+
10+
This will not wipe out any existing data in DESTINATION, with the exception
11+
of Lists which have to be replaced entirely on the DESTINATION. Strings will
12+
obviously be replaced. Hashes will only be updated, any pre-existing hash fields
13+
set on the DESTINATION will remain if they are not replaced by the SOURCE.
14+
15+
Any pre-existing keys on DESTINATION that are not on SOURCE will remain untouched.
16+
17+
## Usage
18+
619
```bash
720
Usage: redis-migrator --source-host SOURCE-HOST --destination-host DESTINATION-HOST
821
[--source-port SOURCE-PORT] [--source-db SOURCE-DB] [--source-user SOURCE-USER]

pkg/migrator/migrate.go

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package migrator
22

33
import (
44
"fmt"
5+
"math"
56
"os"
67
"time"
78

@@ -53,7 +54,9 @@ func DoMigration(sourceClient, destinationClient *redis.Client, keyFilter, keyPr
5354
case "string":
5455
copyString(sourceClient, destinationClient, sourceKey, destinationKey, ttl)
5556
case "hash":
56-
copyHash(sourceClient, destinationClient, sourceKey, destinationKey, ttl)
57+
copyHash(sourceClient, destinationClient, sourceKey, destinationKey)
58+
case "list":
59+
copyList(sourceClient, destinationClient, sourceKey, destinationKey)
5760
default:
5861
logger.Error("Key type not yet sypported: %s", keyType)
5962
os.Exit(1)
@@ -77,7 +80,7 @@ func copyString(sourceClient, destinationClient *redis.Client, sourceKey, destin
7780
}
7881
}
7982

80-
func copyHash(sourceClient, destinationClient *redis.Client, sourceKey, destinationKey string, ttl time.Duration) {
83+
func copyHash(sourceClient, destinationClient *redis.Client, sourceKey, destinationKey string) {
8184
fieldCount, err := sourceClient.HLen(helpers.Ctx, sourceKey).Result()
8285
if err == nil {
8386
// Count the fields in the hash
@@ -110,7 +113,49 @@ func copyHash(sourceClient, destinationClient *redis.Client, sourceKey, destinat
110113
break
111114
}
112115
}
113-
logger.Trace("=====================")
116+
}
117+
} else {
118+
logger.Trace("copyHash Error: %+v", err)
119+
}
120+
}
121+
122+
func copyList(sourceClient, destinationClient *redis.Client, sourceKey, destinationKey string) {
123+
// populate test
124+
/*
125+
for x := int64(0); x < 3333; x++ {
126+
sourceClient.RPush(helpers.Ctx, sourceKey, fmt.Sprintf("example %v", x)).Result()
127+
}
128+
logger.Trace("added lots of examples for '%s'", sourceKey)
129+
*/
130+
131+
itemsPerPage := float64(1000)
132+
itemCount, err := sourceClient.LLen(helpers.Ctx, sourceKey).Result()
133+
if err == nil {
134+
// Count the items in the List
135+
logger.Trace("List '%s' has %d items", sourceKey, itemCount)
136+
137+
if itemCount > 0 {
138+
pages := math.Ceil(float64(itemCount) / itemsPerPage)
139+
// Remove the key from destination, prevents contamination
140+
destinationClient.Del(helpers.Ctx, destinationKey).Result()
141+
142+
// For each page of up to 1000 items:
143+
for i := float64(0); i < pages; i++ {
144+
start := i * itemsPerPage
145+
end := math.Min(start+itemsPerPage, float64(itemCount))
146+
items, lrangeErr := sourceClient.LRange(helpers.Ctx, sourceKey, int64(start), int64(end)).Result()
147+
if lrangeErr == nil {
148+
// Add to destination
149+
// Requires a []interface{} not a []string
150+
itemsInterface := make([]interface{}, len(items))
151+
for i := range items {
152+
itemsInterface[i] = items[i]
153+
}
154+
destinationClient.RPush(helpers.Ctx, destinationKey, itemsInterface...)
155+
} else {
156+
logger.Trace("copyList Error: %+v", lrangeErr)
157+
}
158+
}
114159
}
115160
} else {
116161
logger.Trace("copyHash Error: %+v", err)

0 commit comments

Comments
 (0)