Shouldn't "LettuceFuture"."awaitOrCancel" exclude BlockingCommands not to cancel?
No. There are various things that impact a timeout and you want to protect your application in the first place. One thing that could be done is considering the timeout of BLPOP
, XREAD
and so on and increase the duration. But then, you still have the aspect that the timeout in each command is evaluated on the Redis server itself. If we would use the same value, then all commands would get timed out as the network latency plays into command completion.
So while the command would have a timeout of e.g. 5 seconds, there are a few milliseconds on top that are spent with sending the command to Redis and the command response, so a sane command timeout would need to consider the network latency.
RedisConnection.bLPop(…)
), then Spring Data Redis will allocate a dedicated connection (see https://github.com/spring-projects/spring-data-redis/blob/2eb7067e8c7e859168a281145cc46ccddb42049f/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java#L340-L382) for the command instead of using the shared one
What still can happen is that with pooling, a dedicated connection may receive a command, it times out from a caller perspective, the connection gets released to the pool while the command is still active on Redis and blocks the connection.
A subsequent allocation that would returh the connection has still that command in progress which blocks the connection and if you run another command, then you likely run into another timeout
I configured redis to use connection pool, spring.redis.lettuce.pool.max-active=10.
I set shareNativeConnection to false and noticed the performance of api's are degraded by 20% and also noticed a select dbIndex command was executed all the time before executing any redis commands.
if (asyncDedicatedConn instanceof StatefulRedisConnection) {
((StatefulRedisConnection<byte[], byte[]>) asyncDedicatedConn).sync().select(dbIndex);
}
why is this select db required ?
I want the connection to be taken from pool without any performance degradation. how should i configure ?
I don't want to use single native connection because we have a service it's heavily dependent on redis and it's tomcat running thread count is 200.
we are using a single redis server only.
SELECT
when the database index is zero. That is an optimization we can make if we can assume that application code does not change the database index when the initial database is used
@mp911de from this lettuce-io/lettuce-core#835
Commands are written immediately to the transport without awaiting completion of a previous command
Is that means lettuce puts all the commands to the trasport channel asynchronously. when a request is sent to transport layer is there any call back registered, so that completion data can be sent to the original thread ? Is this the reason your advising single native thread is enough ?
how this was achieved. In case of executing a redis get command before awaiting completion of this command and it executes the next command requested from a different thread, when the first thread's get command complete's how the data will be returned the first thread.
how this was achieved
Commands are represented as objects. They get written to the I/O and then added into a protocol stack in the order they get written to the transport. As soon as Redis responds, the channel handler takes the response and assigns it to the first element in the protocol stack and removes the command. After that, we go back to the next response and so on.
Each Command object is either a Future
or offer some other means of synchronization. In case for synchronous invocation, the invocation is intercepted by a proxy that calls the await(…)
method on the command and so the calling thread is blocked until a command completes (or times out).
This could be a stupid question, but I didn't manage to find an answer. Is version of lettuce somehow coupled with redis versions? Can I run letuce 5+ with redis 3.2.8 for example? We have java 11 so I would like to upgrade lettuce, but I will not upgrade redis at the moment if I dont' have to
Thank you in advance
In this doc https://lettuce.io/core/release/reference/#advanced-usage it was mentioned. EventLoopGroups are started lazily to allocate Threads on-demand
. which class can i check to see how this works.
In our application we are seeing api latency only for the first 5 minutes. just want to see does on-demand EventLoop thread bootup was the cause. if so, is there way to configure to have minimum number EpollEventLoop threads should be running ?
RedisFuture
s are maintained in a list; when we call closePipeline
Lettuce will just wait for all the RedisFuture
s to be completed. I'm a little confused because in this article (https://developpaper.com/redis-throughput-enhancement-through-pipeline/), it is said that "After Pipelinearization, all requests are merged into one IO", but it seems to me that the implementation of Lettuce will actually trigger multiple IO operation, each for one command in the pipeline, although we only try to get all the result at the end, is that right? thanks!
Future
s, multiple processes can use the same connection and commands are sent in self-contained messages.
setAutoFlush(…)
, flushCommands()
)
flush
calls in pipeline, the syscalls at Redis server side are reduced (because we don't need to wait for the response of a previous command before sending another command), as stated in Redis doc(https://redis.io/topics/pipelining): "When pipelining is used, many commands are usually read with a single read()
system call, and multiple replies are delivered with a single write()
system call...and eventually reaches 10 times the baseline obtained not using pipelining".
get/set
calls concurrently. And we found (with surprise) that even only with a single connection, the QPS of Lettuce is higher than Jedis Pool
write/read
) for Redis server are reduced, and as a result we get a higher QPS. Is that right? thanks!