如何在Redis中获取所有键及其对应的值

104

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

几分钟的搜索没有得到任何结果。

P.S. 非常感谢您的答案,但我正在寻找一种本地解决方案。 我可以自己编写一个函数来迭代KEYS *的所有输出。


18
经过4年的无解,似乎答案可能是“不”。 - firelynx
1
请查看类似问题的答案 - x-yuri
17个回答

64

这样做没有本地化的方法。

Redis命令文档中没有本地命令可以获取多个键的键和值。

最本地的方法是使用lua脚本通过使用SCRIPT LOAD命令或EVAL命令加载到你的Redis中。

Bash Haxx解决方案

一个解决方法是使用一些Bash技巧,例如:

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

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

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


2
它只适用于字符串值,请参见此答案 - x-yuri

50

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

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

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


谢谢!这是最直接的方法。 - Pasindu Tennage
假设您已经安装了jq,您可以通过将其管道化到redis-cli GET $key | jq .来获取JSON值的漂亮打印。 - Raphaël

24

我稍微优化了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'

这个 Bash 命令应该在与 Redis 实例相同的服务器上运行吗? - Gabriel Manzini
你可以修改脚本以连接远程实例。请参阅https://dev59.com/81kR5IYBdhLWcg3w4hDN#40678950 - Juuso Ohtonen

14

如果您有大量的键,就不应该在 Redis 生产实例上使用 KEYS 命令,因为它可能会阻塞 Redis 事件循环数秒钟。

我建议先生成一个 dump 文件(使用 bgsave 命令),然后使用以下 Python 包来解析文件并提取数据:

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

您可以得到 JSON 格式的输出,或者在 Python 中自定义您需要的输出格式。


2
+1 这个很重要,有些人可能没有意识到!如果你以一致的方式存储密钥,那么就可以在不需要keys命令的情况下检索它们。 - Abdo
这应该是被接受的答案!我注意到 bgsave 不会存储只包含数字的键名;此外,你也可以使用 strings 命令来解析 Redis 的 dump.rdb 文件。 - αғsнιη

5
您可以使用MGET一次性获取多个key的值。

示例:

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

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


4

我遇到了同样的问题,然后看到了你的帖子。

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

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

要获取所有字段和值,client.HGETALLL可以解决问题。它返回一个数组,其中包含所有字段及其对应的值。

更多信息请参见此处:https://redis.io/commands/hgetall


3

使用此脚本适用于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

2
以下是由“Juuso Ohtonen”提供的脚本的一个小变体。
我添加了一个密码变量和计数器,以便您可以检查备份的进度。同时,我用双括号[[]]替换了简单的括号[],以避免在macos上出现错误。
1.获取键的总数
$ sudo redis-cli
INFO keyspace
AUTH yourpassword
INFO keyspace

2. Edit the script

#!/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

1
使用redis-cli命令,您可以按照以下方式导出键和值:
#!/bin/bash

# Get all keys and their values using redis-cli
redis-cli --raw KEYS "*" | while read key; do
  value=$(redis-cli --raw GET "$key")
  echo "$key: $value" >> "redis_dump.txt"
done

每个键和值都将作为新行添加到redis_dump.txt中。

1
我已经使用 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);
        }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接