Mastering Bidirectional Redis Sync: Strategies, Challenges, and Redissyncer in Action
This article explores the RedisSyncer toolkit for achieving reliable bidirectional Redis synchronization, explains the necessity of cache sync, details the data offset solution and double‑read approach, and provides step‑by‑step deployment instructions with code examples and practical considerations.
RedisSyncer Overview
RedisSyncer is a JD Cloud‑developed open‑source middleware suite for Redis multi‑task synchronization, supporting single‑instance and cluster sync. It includes four components: redissyncer‑server (sync service engine), redissyncer‑cli (client), redissyncer‑compare (data verification tool), and a Docker‑Compose integrated deployment package.
Source code is available at https://github.com/TraceNature/redissyncer-server .
Why Bidirectional Sync?
Ensures dynamic data consistency between two instances when both have existing data and write traffic.
Makes cache data globally readable, preventing cache stampede.
Improves cache hit rate, reducing database load.
Provides full data visibility when a single data center fails.
Challenges of Native Redis Sync
Cannot differentiate the source of cached data.
Lack of instance identifiers leads to data loops during bidirectional sync.
Ring buffer overflow causes data confusion and cleanup difficulty.
Data Offset (Data Reconciliation) Solution
The offset method uses two “offset pools” (set1 and set2) to record keys and sync counts, breaking the write‑loop. The process involves full‑sync, incremental sync with offset‑based discard, and careful ordering of writes to avoid circular replication.
Start full‑sync from redis1 to redis2.
Start incremental sync from redis1 to redis2, discarding keys present in set1.
Start full‑sync from redis2 to redis1, then write to set1 before redis1 to allow offset‑based discard on the return path.
Start incremental sync from redis2 to redis1, using set2 for discard and set1 to avoid looped copies.
Modify the incremental task on redis1→redis2 to discard via set1 first, then write to set2 before syncing.
Double‑Write Pitfalls
Simultaneous writes to the same key in a concurrent environment cannot guarantee order, leading to inconsistent results. Network interruptions cause data loss, and strong consistency makes the system unavailable if a single data center goes down, adding latency and reducing cache effectiveness.
Double‑Read Solution
Each data center deploys a read‑write Redis instance and a read‑only instance. Redissyncer synchronizes write‑side data to the remote read‑only instance. Applications first query the read‑only instance; if the key is missing, they fall back to the read‑write instance, ensuring high availability with minimal operational overhead.
Keys must be globally unique across centers.
Avoid non‑idempotent commands such as INCR or LPUSH.
Network jitter may still cause occasional inconsistencies despite offset handling.
Implementation Details
Deploy Redis instances as usual. Then deploy Redissyncer using Docker:
git clone https://github.com/TraceNature/redissyncer.git
cd redissyncer
docker-compose up -dInstall the client:
wget https://github.com/TraceNature/redissyncer-cli/releases/download/v0.1.0/redissyncer-cli-0.1.0-linux-amd64.tar.gz
tar zxvf redissyncer-cli-0.1.0-linux-amd64.tar.gzConfigure .config.yaml with server address and token:
# redissyncer‑server address and port
syncserver: http://127.0.0.1:8080
# token obtained via redissyncer‑cli login (default admin/123456)
token: 379F5E2BD55A4608B6A7557F0583CFC5Create synchronization tasks (example for az_a1 → az_b2):
{
"sourcePassword": "redistest0102",
"sourceRedisAddress": "10.0.0.110:16375",
"targetRedisAddress": "10.0.0.113:16375",
"targetPassword": "redistest0102",
"taskName": "a1_to_b2",
"targetRedisVersion": 5.0,
"autostart": true,
"afresh": true,
"batchSize": 100
}Start the task with the client:
redissyncer-cli-0.1.0-linux-amd64 -i
redissyncer-cli> task create source synctask/a1_to_b2.jsonRepeat for the opposite direction (az_b1 → az_a2) using a similar JSON file.
To simulate double‑read, clone and build redisdual , then run it to observe read‑only vs. read‑write behavior.
Configuration Example (config.yaml)
# Logging configuration (no changes needed)
zap:
level: 'debug'
format: 'console'
prefix: '[redisdual]'
director: 'log'
link-name: 'latest_log'
show-line: true
encode-level: 'LowercaseColorLevelEncoder'
log-in-console: true
execinterval: 1 # execution interval in ms
loopstep: 30 # max loop steps before reset
localkeyprefix: a
remotekeyprefix: b
redisrw:
db: 0
addr: '114.67.76.82:16375'
password: 'redistest0102'
redisro:
db: 0
addr: '114.67.120.120:16375'
password: 'redistest0102'Key Code Snippets
Bidirectional read logic (redisdual/cmd/start.go):
func dual(rw *redis.Client, ro *redis.Client, key string) {
roResult, err := ro.Get(key).Result()
if err == nil && roResult != "" {
global.RSPLog.Sugar().Infof("Get key %s from redisro result is:%s ", key, roResult)
return
}
rwResult, err := rw.Get(key).Result()
if err != nil || rwResult == "" {
global.RSPLog.Sugar().Infof("key %s no result return!", key)
return
}
global.RSPLog.Sugar().Infof("Get key %s from redisrw result is: %s ", key, rwResult)
}Service start loop (redisdual/cmd/start.go):
for {
if i > loopstep { i = 0 }
key := global.RSPViper.GetString("localkeyprefix") + "_key" + strconv.Itoa(i)
redisRW.Set(key, key+"_"+strconv.FormatInt(time.Now().UnixNano(),10)), 3600*time.Second)
dual(redisRW, redisRO, global.RSPViper.GetString("localkeyprefix")+"_key"+strconv.Itoa(i))
dual(redisRW, redisRO, global.RSPViper.GetString("remotekeyprefix")+"_key"+strconv.Itoa(i))
i++
time.Sleep(time.Duration(global.RSPViper.GetInt("execinterval")) * time.Millisecond)
}Conclusion
Three main mechanisms for Redis bidirectional synchronization are presented: data offset, double‑write, and double‑read. Considering data safety and maintenance cost, the double‑read scheme offers the lowest operational overhead and avoids data confusion during failures.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD Cloud Developers
JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
