Documentation v1.0.0

Recovery Resync

This page explains how data from the fallback period flows from local files through memory back to Redis once Redis recovers, and which entries are not written back.

Steps

changeToNormalMode (sync.go:50-92) runs in order:

Step Action On failure
1 Walk every .json file under {DBPath}/{DB} Errors such as a missing directory → the whole flow aborts and isHealth stays false
2 Read and parse each file as Cache, store it in the memory cache under Cache.Key A file that fails to read or parse → error logged, file skipped
3 syncMemoryToRedis: iterate the entire memory cache and pipeline entries to Redis Pipeline execution errors are not checked
4 cleanupLocalFile: delete every .json file and empty subdirectory (keeping {DBPath}/{DB} itself) A failed delete → error logged, continue
5 isHealth = true —

Write-Back Rules

syncMemoryToRedis (sync.go:94-133):

Item Rule
Scope Every non-expired entry in the memory cache, including entries that were in memory before fallback
Redis TTL Timestamp + TTL − now seconds (remaining time)
Remaining TTL ≤ 0 Not written; entries without a TTL (ttl = 0) also land here
Batching One Exec per 100 non-expired entries, plus a final Exec for the remainder
Format JSON of Data (strings have quotes trimmed), same as Set
Concurrency guard isRecovering uses CAS so only one resync runs at a time; a concurrent call returns immediately

Observed Results

Two keys written while Redis was down, then Redis restored:

Key Write Redis after recovery Local file after recovery
ttlkey Set("ttlkey", "t", time.Hour) Present, TTL 59m59s Deleted
forever Set("forever", "f", 0) Absent Deleted

forever is still in the memory cache; the first read in normal mode writes it back to Redis through Read-Repair.

When Data Survives Only in Memory

Step 4 deletes local files whether or not step 3 succeeded. After any of the following, the data lives only in the memory cache and is lost when the process exits:

Case Reason
Pipeline Exec fails (for example Redis drops again during recovery) Errors are unchecked and files are deleted anyway
A resync is already running The second syncMemoryToRedis call returns immediately, but the file cleanup still runs
ttl = 0 entries Not in the batch; only read-repair writes them back

Memory Cache After Recovery

Recovery does not clear the memory cache. Every loaded entry stays in memory until it expires and is removed by the background sweep; in normal mode, Get always hits memory for these keys and never asks Redis.

中文