使用Lua将Redis数据库的内容转储

这个是之前的延续,我将lua投入到redis-server中,在服务器上进行SCAN并返回键和值的函数进行了整理,以备备忘录。

环境- The environment

$ python -V
Python 3.7.2

$ redis-cli info | grep redis_version
redis_version:5.0.5

代码 (Mandarin Chinese: mǎ)

在处理哈希表或集合时,请根据需要进行相应的读取替换,例如使用HSCAN或ZSCAN。

local cr    = KEYS[1]
local num   = KEYS[2]
local match = KEYS[3]

local cr2, keys = unpack(redis.call("SCAN", cr, "MATCH", match, "COUNT", num))

local values = redis.pcall("MGET", unpack(keys))
return {cr2, keys, values}
#!/usr/bin/env python
import os
import redis
import click

DEFAULT_REDIS_URL = "redis://localhost:6379/3"
DEFAULT_LUA_FILE  = "dump.lua"

def scan_iter(r, lua_script, bulk=2000, match="*"):
    f = r.register_script(lua_script)

    cr = "0"
    while True:
        cr, keys, values = f(keys=[cr, bulk, match])
        if cr == b"0":
            break

        yield from zip(keys, values)


@click.command()
@click.option("--redis-url", envvar="REDIS_URL", default=DEFAULT_REDIS_URL)
@click.option("--lua-file", envvar="LUA_FILE", default=DEFAULT_LUA_FILE, type=click.File("r"))
@click.option("--output", default=os.sys.stdout, type=click.File("w"))
def cmd(redis_url, lua_file, output):
    r = redis.StrictRedis.from_url(redis_url)
    r.ping()

    for k, v in scan_iter(r, lua_file.read()):
        output.write(k.decode("utf-8"))
        output.write("\n")
        output.write("%d" % len(v))
        output.write("\n")


if __name__ == "__main__":
    cmd()

执行

$ pip install redis click

输入样本数据

$ jq -n -r 'range(10000)|"set key\(.) value\(.)"' | redis-cli -n 8

让我们试一试垃圾倾倒

$ ./export.py --redis-url redis://localhost:6379/8

结束。

广告
将在 10 秒后关闭
bannerAds