How to Fix Redis Keys Serialized With Java
If you work with Java and use Spring, there is a fair chance your keys in Redis look like this
Keys in Redis can only be Strings, but Spring lets you store java objects as well. By default, Spring will convert the java object using JDK serializer. The JDK serializer adds those
The fix is usually a 1-line change - instruct spring to use StringRedisSerializer. But this change only affects new keys. Existing keys will continue to remain in Redis but will be inaccessible to java.
If you already have data in production, you need to do more. One approach is to rename keys and get rid of the binary data.
Rename Java Encoded Keys
We recently released a java script that automatically fixes such keys. See hashedin/redis-rename-java-encoded-keys.
The general approach is:
- Scan keys, and look for keys starting with
\xac\xed\x00\x05- which is the signature for java encoded objects
- Try to deserialize into a java object.
- If successful, and if the object is of type String, then rename the key
- If it is a cluster, rename key will not work. In that case, dump and restore the key under the new name
Running it in Production
- You first need to make the code change to stop using Jdk Serializer
- At this point, reads from redis will fail, because the code is looking for serialized objects
- Now start running the script to correct the data
- To reduce downtime, you can scan the database and buffer all the rename commands. Then make the code change and immediately run the rename commands in one go.
- Improve cluster support. Currently, you have to run against each master node in the cluster