Get the data out: migrate from KeyDB to KiviDB

Point KiviDB at a KeyDB server that is not an active replica:

MethodWorks from KeyDBNotes
ReplicateYes, from a server with active-replica noTested with KeyDB 6.3.4: full sync and following writes
RDB file (SAVE, BGSAVE)YesKiviDB reads KeyDB's RDB files, and skips KeyDB's own extensions
RedisShake sync_readerYesInto a KiviDB build with Lua; see the note below
RIOT with --structYesCopies with ordinary commands; stream consumer groups are left behind
MIGRATE, RedisShake scan_reader, RIOT without --structNoThese send KeyDB's DUMP payloads, which carry a KeyDB timestamp KiviDB refuses with ERR Bad data format

Replicate

Point KiviDB at a KeyDB server that is not an active replica:

kividb --port 6380 --dir /var/lib/kividb \
  --replicaof keydb.internal 6379 --masterauth "$KEYDB_PASSWORD"

Then follow the Redis cutover runbook: wait until master_link_status:up and the offsets match, stop writes, promote with REPLICAOF NO ONE, switch clients.

An RDB file

keydb-cli -h keydb.internal BGSAVE
keydb-cli -h keydb.internal INFO persistence | grep -E 'rdb_bgsave_in_progress|rdb_last_bgsave_status'
keydb-cli -h keydb.internal CONFIG GET dir

Copy dump.rdb from that directory once the save has finished. KeyDB writes a version 9 RDB with some extra fields of its own (timestamps, subkey expiry); KiviDB loads the data and drops those.

RedisShake

Use sync_reader exactly as in the Redis guide. Into the default KiviDB build it stops with ERR this build of KiviDB has no Lua, because KeyDB's snapshot carries a script RedisShake replays with SCRIPT LOAD. Use the lua or full build, or a KiviDB Cloud database with Lua on, as the target.

Don't use scan_reader with KeyDB: it copies with DUMP and RESTORE, and KiviDB refuses KeyDB's DUMP payloads.

RIOT

RIOT's default mode also uses DUMP. Add --struct so it reads and writes each type with ordinary commands (HGETALL/HSET, ZRANGE/ZADD and so on):

riot replicate redis://:$KEYDB_PASSWORD@keydb.internal:6379 \
  redis://kividb.internal:6380 --target-pass "$KIVIDB_PASSWORD" \
  --struct --compare NONE

Add --mode LIVE to keep following writes. Live mode listens to keyspace notifications, so turn them on first: keydb-cli -h keydb.internal CONFIG SET notify-keyspace-events KEA.

--struct copies a stream's entries but not its consumer groups. Recreate the groups on KiviDB with XGROUP CREATE <stream> <group> <last-delivered-id>, or copy streams by replication or from an RDB file.

Active replica and multi-master

With active-replica yes, KeyDB sends every write to its replicas wrapped in its own RREPLAY command. KiviDB doesn't know RREPLAY: the full sync works, but every later write is refused (ERR unknown command 'RREPLAY' in KiviDB's log) and the replica silently stops following. So, either:

  • copy with RIOT --struct --mode LIVE, which reads like a client; or
  • stop writing to all but one KeyDB server, set active-replica no and replica-read-only yes on the others, and replicate from the one that takes writes.

For multi-master, copy from a server whose INFO keyspace shows the complete dataset, or copy from each master in turn into the same KiviDB.