14

Redis can be used either directly as a key-value store, where the value is string. Or, in more sophisticated way, the value can be a data structure, for example hash or list. Assuming we have the second case and under the key "H", there is a hash. Items can be added to the hash and removed. Eventually, the hash can be empty, and it can be re-populated again.

I have found out that if we remove the last item from the data structure, our hash "H", Redis removes it from current keys, for some reason.

Example:

HSET "H" "key1" "value1"
HSET "H" "key2" "value2"
HDEL "H" "key1"
 <-- Here, "H" is in the list of current keys, whereby HLEN returns 1
HDEL "H" "key2"
 <-- Here, for some reason, "H" is not shown among existing keys, 
     not even as an empty hash (HLEN 0)
HSET "H" "key3" "value3"
 <-- Hash is back in the list of keys

My question is: Is it possible to configure Redis so it does still keep showing the value (empty hash, in our example) of the given key ("H", in our example) as an empty non-trivial data structure?

2 Answers 2

21

Short answer: No

Redis 'creates the hash' when first item is inserted and 'removes the hash' when last item is removed. I'm using Redis 2.8 and there is no option to 'let an empty hash be'.

Addendum: Same is true for Redis 6 as well.

Sign up to request clarification or add additional context in comments.

1 Comment

Can you please have a look stackoverflow.com/questions/52712982/…
4

Manu is right. You have no way of doing that.

But if you explain why you would want to do it, then we might help you better. As you know, in Redis you can set an attribute on a Hash even if it doesn't exist previously, so you don't not need to first create the Hash and then set the attributes. With that on mind, there is no need to keep an empty Hash that would just be wasting memory.

What is your use case?

update: after reading your use case, I am improving the answer.

For your problem of "volatile" hashes, you can do something easy. After you run your KEYS (or SCAN) command, you can create a SET containing all the names of the hashes that existed in this iteration. You can call this something like "last_seen_keys". What you want to do now is, after you call KEYS, you create a set that you call "current_keys". Now you just run a diff between the two sets, so you can see which keys were present in the last pass and not in this one. You can set your values in statsd to zero for those keys. After that, you delete the "last_seen_keys" SET and you rename the "current_keys" SET to "last_seen_keys". That should do the trick

4 Comments

What I want is to monitor lengths of various hashes in Redis. I am using statsd, but it does not matter. The point is that each minute, I dump length of all existing Redis structures (hashes) to statsd. The names of hashes are dynamic, that's why I cannot just enumerate them. I need to run "KEYS hash-*" and then iterate over these. However, if the hash disappeared, I have the last non-zero value in statsd, but is should be replaced by zero - obviously, length of empty hash is zero.
There is no command to do that directly, but you can do something. First, stop using KEYS, as it is highly inefficient. Starting from redis 2.8 you can use SCAN, which is much more efficient and specially designed for users who need to deal with dynamic keys.
I just improved my answer to include my proposed solution
Thank you, Ramirez. Although I am aware of inefficiency of KEYS, it's not a big deal when there are only tens of keys, not more. And your solution with last_seen_keys would probably work, but that's exactly the kind of overkill I did not want to do... I could also hack statsd to process the data in the similar fashion, but I want the "cleanest" solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.