Debugging Redis Keyspace Misses
Simply put, a keyspace "MISS" means some piece of data you tried to retrieve from Redis was not there. This usually means that one of the following things happened:
- The key expired
- They key was renamed
- The key was deleted
- The key was evicted due to memory pressure
- The entire database was flushed
- The key was never actually inserted
- The data was lost due to a crash, failover, etc.
- The data is in a different DB than the one you currently selected
Please read "What happened to my data" for related information.
For cases 1, 2, 3 and 4 (key expired, renamed, deleted or evicted)
The first thing you should do is look at diagnostic metrics for your cache to see if there is a correlation between when the key went missing and a spike in expired or evicted keys. I have seen many cases where there is a large spike in expired or evicted keys at the point in time when keys seem to have gone missing.
See the Appendix for information on using Keyspace Notifications or MONITOR to debug these types of issues.
For case 5 (DB was flushed)
See here for details of how to see if this happened.
For case 6 (key was never inserted)
In this case, the key was never actually inserted into Redis even though you thought it was. For example, this can happen due to a bug in the client application or due to a network connection getting dropped while the application is trying to write to Redis.
In order to debug this, you will need to debug the client application to figure out which keys are resulting in a MISS and then try to figure out which part of the application is issuing these operations. You will likely need to add additional logging to your application.
For case 7 (data loss)
This doesn't happen very often, so check all the other possible causes first. When we are talking about data loss, we are talking about most or all of your keys disappearing, not a few keys disappeared. As mentioned previously, please read "What happened to my data" for related information.
Using a Premium tier cache instance with persistence is a way to protect yourself against this. You can reach out to customer support if you have additional questions.
For case 8 (incorrect DB selected)
If you have DB 0 selected when you set the key/value into Redis, but have a different DB (like db 1, 2, etc.), then the system won't find the key you are looking for because each DB is its own logical data set. Use the Select Command to switch to other DBs and then look for the key in each DB.
If you need to debug on an individual key basis, then the best option is to enable Keyspace Notifications and watch for events to fire for the key(s) in question. You can find sample code here.
Note that there is a performance impact for turning on notifications.
Another option for figuring out exactly what is happening on the server side is to use the MONITOR Command, which allows a client watch the stream of commands that are being executed. However, you should be aware that this can have a heavy performance impact because Redis will now send all operations back to the client that issued the MONITOR command.
If you are trying to debug a miss with MONITOR logs, then you will have to capture the logs for sufficient time to know what was done to the key in question over time. For instance, you will need to be able to see when the associated SET operation was done on the key, then look for changes (like DELETE, RENAME, EXPIRE, etc). If you don't find any entries in the MONITOR output, then this means that it was never set in the first place or it means that you started MONITOR after the key was already inserted.
As an example, a customer asked why the MISS count went up by just creating a StackExchange.Redis ConnectionMultiplexer and calling GetDatabase() on it. Using MONITOR on my cache, it was pretty easy to see that StackExchange.Redis issues GET requests for a key
"__Booksleeve_TieBreak", which I knew didn't exist in my cache. Apparently StackExchange.Redis uses this key for some type of state management.