Skip to content

Instantly share code, notes, and snippets.

@Nicolab
Forked from alexandremcosta/migrate_redis.ex
Created September 14, 2022 07:52
Show Gist options
  • Save Nicolab/b46f3bf60613d11720e00e87de81fcec to your computer and use it in GitHub Desktop.
Save Nicolab/b46f3bf60613d11720e00e87de81fcec to your computer and use it in GitHub Desktop.
Elixir Redis Migration Script (dump/restore)
defmodule MigrateRedis do
require Logger
@from [host: "127.0.0.1", port: 6379]
@to [host: "127.0.0.1", port: 6379]
def migrate(from \\ @from, to \\ @to) do
{:ok, from} = Redix.start_link(from)
{:ok, to} = Redix.start_link(to)
cursor = 0
size = Redix.command!(from, ["DBSIZE"])
progress = {cursor, size}
from
|> Redix.command!(["SCAN", cursor])
|> loop_dump_restore(progress, from, to)
end
# Last loop
defp loop_dump_restore(["0", keys], _progress, from, to), do: dump_restore(keys, from, to)
# All but last loops
defp loop_dump_restore([cursor, keys], {iteration, size}, from, to) do
# Log every ~100 keys, since each scan handle ~10 keys
if rem(iteration, 10) == 0, do: Logger.info("[MigrateRedis] Progress: #{iteration}/#{size}")
dump_restore(keys, from, to)
from
|> Redix.command!(["SCAN", cursor])
|> loop_dump_restore({iteration + length(keys), size}, from, to)
end
defp dump_restore(keys, from, to) when is_list(keys) do
Enum.each(keys, &dump_restore(&1, from, to))
end
defp dump_restore(key, from, to) do
Logger.info("Dump #{key}")
data = Redix.command!(from, ["DUMP", key])
pttl = Redix.command!(from, ["PTTL", key])
pttl = if pttl < 0, do: 0, else: pttl
Redix.command!(to, ["DEL", key])
Redix.command!(to, ["RESTORE", key, pttl, data])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment