Q: I saw a RedisTimeOutException, What does it mean? What shall I do? Can Redisson Team fix it?

A :

There are three main reasons:

1) All netty threads are busy, leading to delays in both Redis response decoding and sending commands to Redis2) All connections are busy3) Redis server takes too long to respond the request.

First try to set follow values for nettyThreads setting: 32, 64, 128, 256 this allow Redisson to get free netty thread to decode response or send command. Next, try to increase connection pool setting so that Redisson can stand a better chance in getting a free connection. Also, try to increase retryInterval and/or timeout to a reasonable value so that a command can still gracefully fail without having the end user wait forever.

Complex commands such as keys, hmget and big loops in Lua scripts are more likely to see it than other commands. It is important to understand an operation can still timeout despite the absence of it from the Redis slowlog. Slowlogs only record the time a command is been processed by the Redis event loop and not anything before or after. Network issue may also cause this exception when a response is still in-flight.

Q: I saw a com.fasterxml.jackson.databind.JsonMappingException during deserialization process, can you fix it?

A : As the exception name suggests, this is an exception related to the usage of Jackson mapper, and it is not something can be fixed by Redisson. As the nature of Jackson mapper, by default, not all classes can be deserialised without specialised configuration, especially those ones with no default constructor. You may need to register a Mixin class and/or other techniques to guide Jackson in these situations.

Since this exception is only related to Jackson, as an alternative, you can swap to use another none-Jackson based codec to avoid it altogether, however be advised that as everything in life, there are pros and cons in everything.

Q: There were too many quotes appeared in the redis-cli console output, how do I fix it?

  1. 127.0.0.1:6379> get abc
  2. "\"123\""
  3. 127.0.0.1:6379>

A : In order to “fix” the problem, we need to understand where they are coming from. You see, I had the word “fix” wrapped around a pair of double quotes too. I used double quotes to indicate that this was intended to mean something quite opposite. Don’t worry, I am not here to teach you grammar, but rather to highlight the importance of quotes and the impact they had on the context they surround.

You may or may not have noticed, redis-cli used double quotes to indicate the output is a string type. So the first quote and the last quote are not really part of the content of the result.

The second(inner) pair of quotes, however, are indeed part of the answer. Redisson uses JSON as its default encoding/decoding format. As per JSON specification dictates: any string typed value has to be wrapped around a pair of double quotes. Now you can see both pairs quotes were in fact required under different jurisdictions.

Under certain use cases, if you only ever going to need string typed keys and values. You can changed the default codecs to StringCodec and it will stop adding the second pair of quotes to any string values.

Q: When do I need to shut down a Redisson instance, at the end of each request or the end of the life of a thread?

A : Redisson instance requires manual shutdown only if you want to stop using all of its features. It is a common pattern that Redisson starts and stops along with the application. Since it is completely thread safe, you may treat a Redisson instance as a singleton. The shutdown sequence will disconnect all the active connections held in each connection pool, and it will clean up certain types of Redisson objects require a manual destroy action upon disposal, it will then stop the event loops. Please be advised, the entire shutdown process is not instant.

Q: In MapCache/SetCache/SpringCache/JCache, I have set an expiry time to an entry, why is it still in Redis when it should be disappeared?

A : The first and foremost thing you need to understand is entry expiry feature is not supported by Redis. This is one of Redisson’s own creation. Which means it requires Redisson to work. You can’t expect a correct behaviour using other clients such as redis-cli or even jedis.

Redisson employs both active approach and passive approach, just like Redis server, to ensure an element is evicted when its time is due. There is are scheduled eviction tasks that runs periodically to remove the expired elements from the collection, Redisson also checks the expiry information when an element is accessed: if it has expired, it will be removed and a null value will be returned.

So if you saw the stale value in redis-cli, please do not panic, it will be removed when the scheduled task catches up or when you next request it through Redisson.

Q: How can I perform Pipelining/Transaction through Redisson?

A : The fact is pipelining and transaction are dealt with virtually in the same way by the RBatch object in Redisson. This is the design decision we took based on the analysis of the characteristics of both techniques. From the client side point of view, through both techniques, you are expected to issue a series of commands consecutively, and more importantly you will only expect to see the results after the last command is executed.

There are only subtle differences between the two techniques lies within the RBatch API. There is an atomic() method you should use before issuing batch commands if you want to execute a series of commands in a single transaction. There is no other usage difference.

And yes, if this answers your other question, transactional commands are always dispatched in a single pipeline.

Q: Is Redisson thread safe? Can I share an instance of it between different threads?

A : The Redisson instance itself and all the objects it provides are thread safe. APIs exposed by those objects are just operation handles. None of the these objects keep any states that would break the thread safety local to the instance. Most of those objects that do not “contain” any data local to the JVM with exception to LocalCached instances for obvious reasons. And here is a piece of pro advice: You can even share a RObject to multiple machines by publish it over a RTopic.

Q: Can I use different encoder/decoders for different tasks?

A : Absolutely. A different codec to the default one can be supplied when creating a RObject instance. So that you can have RObjects with different codecs symbiotically living together. For map objects, you can have different codecs for keys and values by extending the Codec interface with your preferred implementation. Additionally, within your own implementation, you can create composite codecs by daisy-chaining a series of codecs together for different purposes: You can first marshal the data into XML format, then compress it before applying encryption. Once a RObject is configured with this composite codec, it will perform all the above processes automatically and transparently. One thing you have to be aware is when there is an un-handled exception thrown by the decoder, it may cause the command to timeout, despite the fact this command may already been executed by the server.