【问题标题】:Redis move all keys from one database to anotherRedis 将所有密钥从一个数据库移动到另一个数据库
【发布时间】:2020-04-13 17:31:26
【问题描述】:

是否有将 redis 键从一个数据库移动到另一个数据库的命令,还是只能使用 lua 脚本?

以前redis move all keys 有人问过这种类型的问题,但对于像我这样的初学者来说,答案并不合适和令人信服。

【问题讨论】:

    标签: redis


    【解决方案1】:

    你可以使用“MOVE”将一个键移动到另一个redis数据库;

    以下文字来自redis.io

    MOVE 键数据库

    将键从当前选定的数据库(参见 SELECT)移动到指定的目标数据库。当 key 已经存在于目标数据库中,或者它不存在于源数据库中时,它什么也不做。因此,可以将 MOVE 用作锁定原语。

    返回值

    整数回复,具体来说:

    • 如果键被移动,则为 1。
    • 如果键没有移动,则为 0。

    【讨论】:

    • move 命令只移动一个键,如果我想移动一组键怎么办?
    • @aarish 我没有什么好的建议。我认为你可以使用 KEYSMOVE 来使用脚本来完成。
    • 你可以做一个 MULTI/EXEC 块,这样命令就会被缓冲并一次执行。
    【解决方案2】:

    我认为这可以完成工作:

    redis-cli keys '*' | xargs -I % redis-cli move % 1 > /dev/null
    

    (1 是新的数据库编号,重定向到 /dev/null 是为了避免获得数百万行 '1' - 因为它会一一移动键并每次返回 1)

    请注意,redis 可能会用完连接,然后会显示大量此类错误:

    无法在 127.0.0.1:6379 连接到 Redis:无法分配请求的地址

    因此,直接转储数据库然后将其导入新数据库可能会更好(而且速度更快)。

    【讨论】:

    • 如果您有数百万个密钥,此命令将长时间阻塞您的服务器。最好使用 SCAN 命令,它会比整个长阻塞 KEY 命令以光标非阻塞更优化的方式为您提供键。
    【解决方案3】:

    如果您有一个包含数百万键的大型数据库,您可以使用 SCAN 命令选择所有键(不会像 dangerous KEYS 命令那样阻塞,即使是 Redis 作者也不会推荐)。

    SCAN 逐页为您提供键,其想法是从第 0 页(正式称为 CURSOR 0)开始,然后继续下一页/光标,直到您到达结尾(停止信号是当您再次获得 CURSOR 0 时)。

    您可以为此使用任何流行的语言,例如 Redis、Ruby 或 Scala。这是使用 Bash 脚本的草稿:

    #!/bin/bash -e
    
    REDIS_HOST=localhost
    PAGE_SIZE=10000
    KEYS_TO_QUERY="*"
    SOURCE_DB=0
    TARGET_DB=1
    
    TOTAL=0
    while [[ "$CURSOR" != "0" ]]; do
      CURSOR=${CURSOR:-0}
      >&2 echo $TOTAL:$CURSOR
      KEYS=$(redis-cli -h $REDIS_HOST -n $SOURCE_DB scan $CURSOR match "$KEYS_TO_QUERY" count $PAGE_SIZE)
      unset CURSOR
      for KEY in $KEYS; do
        if [[ -z $CURSOR ]]; then
          CURSOR=$KEY
        else
         TOTAL=$(($TOTAL + 1))
         redis-cli -h $REDIS_HOST -n $SOURCE_DB move $KEY $TARGET_DB
        fi
      done
    done
    

    重要提示:像往常一样,请不要在不了解正在做什么的情况下复制和粘贴脚本,所以这里有一些细节:

    while 循环使用SCAN 命令逐页选择键,然后对每个键运行MOVE 命令。

    SCAN 命令将在第一行返回下一个光标,然后其余行将是找到的键。 while 循环以未定义变量 CURSOR 开始,然后在第一个循环中定义(这是一种魔法,可以在下一个 CURSOR 0 处停止,表示扫描结束)

    PAGE_SIZE 是每次扫描查询的时长值,较低的值对服务器的影响非常小,但速度会很慢,较大的值会使服务器“出汗”但速度更快......这里的网络是受到影响,因此请尝试在 10000 甚至 50000 左右找到最佳位置(具有讽刺意味的是,值 1 或 2 也可能对服务器造成压力,但由于每个查询的网络包装部分)

    KEYS_TO_QUERY:这是您要查询的键上的模式,例如 "*balance*" 将选择键名中包含 balance 的键(不要忘记包含引号以避免语法错误) ...另外你可以在脚本端进行过滤,只需使用"*"查询所有键并添加一个bash脚本if条件,这会更慢但是如果你找不到你的键选择模式,这将帮助。

    REDIS_HOST:默认使用 localhost,将其更改为您喜欢的任何服务器(如果您使用的是默认端口 6379 以外的自定义端口,您也可以将其包含在 myredisserver:4739 之类的东西中)

    SOURCE_DB:您希望键移动的数据库 ID(默认为 0)

    TARGET_DB:您希望密钥移动到的数据库 ID(默认为 1)

    您可以使用此脚本执行其他命令或使用键进行检查,只需将MOVE 命令调用替换为您可能需要的任何内容。

    注意:要将密钥从一个 Redis 服务器移动到另一个 Redis 服务器(这不仅是在内部数据库之间移动),您可以在此处使用 NPM 包中的 redis-utils-cli -> @987654321 @

    【讨论】:

      猜你喜欢
      • 2014-11-04
      • 2012-11-27
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-11
      相关资源
      最近更新 更多