How to get all keys with their values in redis
Asked Answered
B

18

109

I know that in order to get all the list of all keys in Redis, I have to use KEYS *, but is there a way to output all keys together with their values?

Few minutes of searching did not yield any result.

P.S. thank you very much for answers, but I am looking for a native solution. I can write a function that iterates through all the output of KEYS * by myself.

Balinese answered 14/10, 2013 at 6:48 Comment(2)
It does seem that after 4 years of no solution, the answer might be "no"Ineducation
Check out an answer from a similar question.Chainplate
I
65

There is no native way of doing this.

The Redis command documentation contains no native commands for getting the key and value of multiple keys.

The most native way of doing this would be to load a lua script into your redis using the SCRIPT LOAD command or the EVAL command.

Bash Haxx solution

A workaround would be to use some bash magic, like this:

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

This will output the data from all the keys which begin with YOURKEY

Note that the keys command is a blocking operation and should be used with care.

Ineducation answered 6/2, 2015 at 15:37 Comment(1)
It only works for string values, see this answer.Chainplate
W
51

Yes, you can do print all keys using below bash script,

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

where, 6379 is a port on which redis is running.

Womanizer answered 18/4, 2018 at 14:55 Comment(2)
Thanks! This is the most straight forward approachMama
Assuming you got jq installed, you can get a pretty print for json values by piping it redis-cli GET $key | jq ..Avion
P
25

I refined the bash solution a bit, so that the more efficient scan is used instead of keys, and printing out array and hash values is supported. My solution also prints out the key name.

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

Note: you can formulate a one-liner of this script by removing the first line of redis_print.sh and commanding: cat redis_print.sh | tr '\n' ';' | awk '$1=$1'

Pedagogics answered 27/8, 2019 at 12:18 Comment(2)
This bash command should be running on the same server as the redis instance?Jd
You could modify the script to connect a remote instance. See https://mcmap.net/q/108454/-how-to-connect-to-remote-redis-serverPedagogics
M
14

KEYS command should not be used on Redis production instances if you have a lot of keys, since it may block the Redis event loop for several seconds.

I would generate a dump (bgsave), and then use the following Python package to parse it and extract the data:

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

You can have json output, or customize your own output in Python.

Merissameristem answered 14/10, 2013 at 11:23 Comment(2)
+1 One may not realize how important this is! If you're storing the keys in a consistent manner, you should be able to retrieve them without needing the keys command.Savaii
this should be the accepted answer! I noticed that bgsave doesn't store the keys which contains only digits as its keyName; Also to parse the redis dump.rdb files you can use strings command too.Oidium
L
5

You can use MGET to get the values of multiple keys in a single go.

Example:

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

For listing out all keys & values you'll probably have to use bash or something similar, but MGET can help in listing all the values when you know which keys to look for beforehand.

Leptorrhine answered 6/2, 2020 at 0:59 Comment(0)
H
4

I had the same problem, and I felt on your post.

I think the easiest way to solve this issue is by using redis Hashtable.

It allows you to save a Hash, with different fields and values associated with every field.

To get all the fiels and values client.HGETALLL does the trick. It returns an array of

all the fields followed by their values.

More informations here https://redis.io/commands/hgetall

Heidy answered 29/8, 2018 at 17:10 Comment(0)
L
3

Use this script for 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
Loera answered 19/4, 2020 at 12:15 Comment(0)
S
2

Below is just a little variant of the script provided by @"Juuso Ohtonen".

I have add a password variable and counter so you can can check the progression of your backup. Also I replaced simple brackets [] by double brackets [[]] to prevent an error I had on macos.

1. Get the total number of keys

$ 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. Execute the script

bash redis_print.sh > redis.bak

4. Check progression

tail redis.bak
Sleekit answered 18/9, 2020 at 15:22 Comment(0)
D
1

I have written a small code for this particular requirement using hiredis , please find the code with a working example at http://rachitjain1.blogspot.in/2013/10/how-to-get-all-keyvalue-in-redis-db.html

Here is the code that I have written,

#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);
        }
}
Dialectical answered 28/10, 2013 at 9:9 Comment(0)
L
1

Tried the given example, but over VPN and with 400k+ keys it was too slow for me. Also it did not give me the key objects.

I wrote a small Python called tool redis-mass-get to combine KEYS and MGET requests against Redis:

# 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:*

It supports JSON, CSV and TXT output to file or stdout for usage in pipes. More info can be found at: Reading multiple key/values from Redis.

Lamoureux answered 17/8, 2020 at 10:57 Comment(0)
S
1

This shell script retrieves all Redis keys with their corresponding values using the SCAN command.

It uses a while loop to iterate through batches of keys retrieved from Redis, and a for loop to iterate through the keys in each batch. For each key, it retrieves its value using the GET command, and prints the key-value pairs in a formatted manner to the console.

The script continues to retrieve and process batches of keys until all keys have been retrieved

    #!/bin/sh
    
    # Start Redis CLI and retrieve all keys using SCAN command
    redis_keys=$(redis-cli --raw SCAN 0)
    
    # Loop through keys and retrieve values
    while [ "$redis_keys" != "0" ]; do
      # Extract the cursor and keys from SCAN command response
      cursor=$(echo "$redis_keys" | head -n 1)
      keys=$(echo "$redis_keys" | tail -n +2)
    
      # Loop through the keys and retrieve their values
      for key in $keys; do
        value=$(redis-cli --raw GET "$key")
        echo "Key: $key | Value: $value"
      done
    
      # Retrieve the next batch of keys using the new cursor
      redis_keys=$(redis-cli --raw SCAN "$cursor")
    done
Stribling answered 21/4, 2023 at 15:51 Comment(0)
D
1

With redis-cli you can export keys and values as following:

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

Every key and value will be added as a new line in redis_dump.txt.

Dorthydortmund answered 3/9, 2023 at 14:2 Comment(0)
B
0

scan 0 MATCH * COUNT 1000 // it gets all the keys if return is "0" as first element then count is less than 1000 if more then it will return the pointer as first element and >scan pointer_val MATCH * COUNT 1000 to get the next set of keys it continues till the first value is "0".

Bathometer answered 19/12, 2018 at 4:56 Comment(1)
This doesn't suggest why to use scan vs. keys (which wasn't the question to begin with); and doesn't explain how to get the values for those keys.Mcnew
N
0

This simple script worked for me (I store in my REDIS key-value sets)

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

You simply execute it:

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

The final output is a .csv file (comma delimiter) of the pairs I needed.

Nubbin answered 8/12, 2021 at 12:44 Comment(0)
L
0

I have updated the script with some more keys and here goes

#!/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"
    elif [ $type = "smembers" ]
    then
        printf "$key => $(redis-cli smembers $key)\n"
    elif [ $type = "zset" ]
    then
        printf "$key => $(redis-cli zrange $key 0 -1)\n"
    elif [ $type = "set" ]
    then
        printf "$key => $(redis-cli smembers $key)\n"
    else
        printf "$key => $(redis-cli get $key)\n"

    fi
done
Lauretta answered 6/3, 2022 at 6:19 Comment(0)
D
0

Check out solution for Alpine linux container

  • Create file redis

    #!/bin/bash
    apk --update add redis
    host="$1"
    port="$2"
    
    redis-cli -h "${host}" -p "${port}" --scan --pattern 'key_prefix_*' | while read key;
    do
       value=$(redis-cli -h "${host}" -p "${port}" get "${key}")
       echo "${key} : ${value}"
    done
    
  • Run: chmod 755 redis

  • Run: /bin/sh redis {Your Redis Host} {Your Redis Port}

Disseisin answered 23/11, 2022 at 8:51 Comment(0)
C
0

Same output as firelync one-liner, but easier to type and only invokes redis twice:

echo 'keys YOURKEY*' | redis-cli | xargs  redis-cli mget

Only suitable for a hand full of values, and ommits the name of the key

Coordination answered 28/12, 2023 at 12:38 Comment(0)
P
-2

check out my tool, rdd

rdd -v

will output you all keys with data

Playhouse answered 14/10, 2013 at 14:45 Comment(4)
+1, Also with -m option, we can print only keys which matches given pattern.Filbert
this did not work? need to install something additional? (my redis is running on RHEL 7.3)Spindlelegs
redis-cli lib is the only dependency please be more explicit in your bug report .. maybe your keys got binary names ? filter request to try not use the full set, to isolate faultly keysPlayhouse
You may want to mention it is your own project.Well

© 2022 - 2024 — McMap. All rights reserved.