Have some question about HMGET performance.
Can you explain how number of fields in hash affect reading performance?
Example 1. 20000 requests. HMGET with 4 fields. Commands in pipeline. Hash contains 760 fields
On test machine it takes about 1500ms.
Example 2. 20000 requests. HMGET with 4 fields. Commands in pipeline. Hash contains 30 fields
On test machine it takes about 300ms.
2
Answers
I did similar test to @LeoMurillo did.
Then I checked hash-max-ziplist-entries. It is set to 1500. So in my case Test1HMGET and Test2HMGET have encoding:ziplist, and Test3HMGET encoding:hashtable.
So I think it is all about compression. When a hashset is compressed, getting fields from the end of a set is so much slower.
It should be O(1) in both cases – independent of the number of fields in the hash. So 5x the time for 20x the number of keys sounds excessive.
I tried to replicate and got very consistent performance. Here what I did:
Created three hashes, with 10, 1000, 100000 fields each:
Then run
redis-benchmark
to test HMGET:As shown, regardless of the hash length, it consistently got ~8800 rps.
Other commands, like HGETALL, do show a decline.
There must be something else on your test driving the difference you observe, perhaps payload difference if you are using different fields.
Update: As pointed out by the OP, there is a performance difference once you get close to
hash-max-ziplist-entries
. See Antirez article, and this post. Your average read performance decay, due to compression. It is a CPU / memory trade-off.On my machine, I had
max-ziplist-entries
= 512. Performance is 2.3x slower towards the end of the key-space. Once we go over the compression optimization threshold (514 fields), it is constant across the key-space, but memory usage went up 6.6x.