【问题标题】:How to get all keys with their values in redis如何在redis中获取所有键及其值
【发布时间】:2013-10-21 16:47:00
【问题描述】:

我知道要获取Redis中所有键的所有列表,我必须使用KEYS *,但是有没有办法将所有键及其值一起输出?

几分钟的搜索没有产生任何结果。

附:非常感谢您的回答,但我正在寻找本机解决方案。我可以自己写一个函数来遍历KEYS *的所有输出。

【问题讨论】:

  • 似乎在 4 年没有解决方案之后,答案可能是“不”
  • 查看类似问题的answer

标签: redis


【解决方案1】:

没有本地方法可以做到这一点。

Redis command documentation 不包含用于获取多个键的键和值的本机命令。

执行此操作的最原生方式是使用SCRIPT LOAD 命令或EVAL 命令将lua script 加载到您的redis 中。

Bash Haxx 解决方案

解决方法是使用一些 bash 魔法,如下所示:

echo 'keys YOURKEY*' | redis-cli | sed 's/^/get /' | redis-cli 

这将输出所有以 YOURKEY 开头的键的数据

请注意,keys 命令是一个阻塞操作,应谨慎使用。

【讨论】:

  • 它只适用于字符串值,见answer
【解决方案2】:

是的,您可以使用以下 bash 脚本打印所有键,

for key in $(redis-cli -p 6379 keys \*);
  do echo "Key : '$key'" 
     redis-cli -p 6379 GET $key;
done

其中,6379 是运行 redis 的端口。

【讨论】:

  • 谢谢!这是最直接的方法
【解决方案3】:

我稍微改进了 bash 解决方案,以便使用更有效的 scan 代替 keys,并打印出数组和哈希支持值。我的解决方案还会打印出密钥名称。

redis_print.sh

#!/bin/bash

# Default to '*' key pattern, meaning all redis keys in the namespace
REDIS_KEY_PATTERN="${REDIS_KEY_PATTERN:-*}"
for key in $(redis-cli --scan --pattern "$REDIS_KEY_PATTERN")
do
    type=$(redis-cli type $key)
    if [ $type = "list" ]
    then
        printf "$key => \n$(redis-cli lrange $key 0 -1 | sed 's/^/  /')\n"
    elif [ $type = "hash" ]
    then
        printf "$key => \n$(redis-cli hgetall $key | sed 's/^/  /')\n"
    else
        printf "$key => $(redis-cli get $key)\n"
    fi
done

注意:您可以通过删除 redis_print.sh 的第一行并命令:cat redis_print.sh | tr '\n' ';' | awk '$1=$1'

来制定此脚本的单行代码

【讨论】:

【解决方案4】:

如果您有很多键,则不应在 Redis 生产实例上使用 KEYS 命令,因为它可能会阻塞 Redis 事件循环几秒钟。

我会生成一个转储(bgsave),然后使用以下 Python 包对其进行解析并提取数据:

https://github.com/sripathikrishnan/redis-rdb-tools

你可以有 json 输出,或者在 Python 中自定义你自己的输出。

【讨论】:

  • +1 人们可能没有意识到这有多重要!如果您以一致的方式存储密钥,您应该能够在不需要 keys 命令的情况下检索它们。
【解决方案5】:

您可以使用MGET 一次获取多个键的值。

例子:

redis> SET key1 "Hello"
"OK"
redis> SET key2 "World"
"OK"
redis> MGET key1 key2 nonexisting
1) "Hello"
2) "World"
3) (nil)

要列出所有键和值,您可能必须使用 bash 或类似的东西,但如果您事先知道要查找哪些键,MGET 可以帮助列出所有值。

【讨论】:

    【解决方案6】:

    我遇到了同样的问题,我在你的帖子中感受到了。

    我认为解决这个问题最简单的方法是使用 redis Hashtable。

    它允许您保存一个哈希,其中包含与每个字段关联的不同字段和值。

    要获取所有字段和值client.HGETALLL 就可以了。它返回一个数组

    所有字段后跟它们的值。

    更多信息在这里https://redis.io/commands/hgetall

    【讨论】:

      【解决方案7】:

      将此脚本用于 redis >=5:

      #!/bin/bash
      redis-cli keys "*" > keys.txt
      cat keys.txt | awk '{ printf "type %s\n", $1 }' | redis-cli > types.txt
      paste -d'|' keys.txt types.txt | awk -F\| '
         $2 == "string"               { printf "echo \"KEY %s %s\"\nget %s\n", $1, $2, $1 }
         $2 == "list" || $2 == "set"  { printf "echo \"KEY %s %s\"\nsort %s by nosort\n", $1, $2, $1 }
         $2 == "hash"                 { printf "echo \"KEY %s %s\"\nhgetall %s\n", $1, $2, $1 }
         $2 == "zset"                 { printf "echo \"KEY %s %s\"\nzrange %s 0 -1 withscores\n", $1, $2,$1 }
      ' | redis-cli
      rm keys.txt
      rm types.txt
      

      【讨论】:

        【解决方案8】:

        我使用hiredis 为这个特殊要求编写了一个小代码,请在http://rachitjain1.blogspot.in/2013/10/how-to-get-all-keyvalue-in-redis-db.html 找到带有工作示例的代码

        这是我写的代码,

        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include "hiredis.h"
        
        int main(void)
        {
                unsigned int i,j=0;char **str1;
                redisContext *c; char *t;
                redisReply *reply, *rep;
        
                struct timeval timeout = { 1, 500000 }; // 1.5 seconds
                c = redisConnectWithTimeout((char*)"127.0.0.2", 6903, timeout);
                if (c->err) {
                        printf("Connection error: %s\n", c->errstr);
                        exit(1);
                }
        
                reply = redisCommand(c,"keys *");
                printf("KEY\t\tVALUE\n");
                printf("------------------------\n");
                while ( reply->element[j]->str != NULL)
                {
                        rep = redisCommand(c,"GET  %s", reply->element[j]->str);
                        if (strstr(rep->str,"ERR Operation against a key holding"))
                        {
                                printf("%s\t\t%s\n",  reply->element[j]->str,rep->str);
                                break;
                        }
                        printf("%s\t\t%s\n",  reply->element[j]->str,rep->str);
                        j++;
                        freeReplyObject(rep);
                }
        }
        

        【讨论】:

          【解决方案9】:

          尝试了给定的示例,但是通过 VPN 和 400k+ 密钥对我来说太慢了。它也没有给我关键对象。

          我编写了一个名为redis-mass-get 的小型 Python 工具来组合针对 Redis 的 KEYSMGET 请求:

          # installation:
          pip install redis-mass-get
          
          # pipeline example CSV:
          redis-mass-get -f csv -och redis://my.redis.url product:* | less
          
          # write to json-file example with progress indicator:
          redis-mass-get -d results.json -jd redis://my.redis.url product:*
          

          它支持 JSON、CSV 和 TXT 输出到文件或stdout 以在管道中使用。更多信息请访问:Reading multiple key/values from Redis

          【讨论】:

            【解决方案10】:

            以下只是@“Juuso Ohtonen”提供的脚本的一个小变种。

            我添加了一个密码变量计数器,以便您可以检查备份的进度。我还用 双括号 [[]] 替换了简单的括号 [],以防止我在 macos 上遇到错误。

            1。获取key的总数

            $ sudo redis-cli
            INFO keyspace
            AUTH yourpassword
            INFO keyspace
            

            2。编辑脚本

            #!/bin/bash
            
            # Default to '*' key pattern, meaning all redis keys in the namespace
            REDIS_KEY_PATTERN="${REDIS_KEY_PATTERN:-*}"
            PASS="yourpassword"
            i=1
            for key in $(redis-cli -a "$PASS" --scan --pattern "$REDIS_KEY_PATTERN")
            do
                echo $i.
                ((i=i+1))
                type=$(redis-cli -a "$PASS" type $key)
                if [[ $type = "list" ]]
                then
                    printf "$key => \n$(redis-cli -a "$PASS" lrange $key 0 -1 | sed 's/^/  /')\n"
                elif [[ $type = "hash" ]]
                then
                    printf "$key => \n$(redis-cli -a "$PASS" hgetall $key | sed 's/^/  /')\n"
                else
                    printf "$key => $(redis-cli -a "$PASS" get $key)\n"
                fi
                echo
            done
            

            3。执行脚本

            bash redis_print.sh > redis.bak
            

            4。检查进度

            tail redis.bak
            

            【讨论】:

              【解决方案11】:

              这个简单的脚本对我有用(我存储在我的 REDIS 键值集中)

              #!/bin/bash
              
              for key in $(redis-cli -p <port> -n <db num> keys \*);
                do
                  OUTPUT=$(redis-cli -p <port> -n <db num> GET $key)
                  echo "$key", "${OUTPUT}" >> redis_pairs.csv
              done
              

              你只需执行它:

              $ chmod +x script.sh
              $ ./script.sh
              

              最终输出是我需要的对的 .csv 文件(逗号分隔符)。

              【讨论】:

                【解决方案12】:

                scan 0 MATCH * COUNT 1000 // 它得到所有的键 如果返回为“0”作为第一个元素,则计数小于 1000 如果更多,则它将指针作为第一个元素返回并 >scan pointer_val MATCH * COUNT 1000 要获取下一组键,它会一直持续到第一个值为“0”。

                【讨论】:

                • 这并没有说明为什么要使用扫描与键(这不是一开始的问题);并且没有解释如何获取这些键的值。
                【解决方案13】:

                看看我的工具,rdd

                rdd -v
                

                将为您输出所有带有数据的键

                【讨论】:

                • +1,同样使用-m 选项,我们可以只打印与给定模式匹配的键。
                • 这不起作用?需要安装额外的东西吗? (我的 redis 在 RHEL 7.3 上运行)
                • redis-cli lib 是唯一的依赖项,请在您的错误报告中更加明确。也许您的密钥有二进制名称?过滤请求以尝试不使用完整集,以隔离错误键
                • 你可能想说这是你自己的项目。
                猜你喜欢
                • 2016-08-20
                • 2017-08-13
                • 2018-04-04
                • 2014-03-10
                • 2015-06-21
                • 1970-01-01
                • 2017-04-03
                • 1970-01-01
                • 2015-08-24
                相关资源
                最近更新 更多