StackExchange / StackExchange.Redis

General purpose redis client
https://stackexchange.github.io/StackExchange.Redis/
Other
5.86k stars 1.5k forks source link

Blocking Transaction #2590

Closed MattGhafouri closed 8 months ago

MattGhafouri commented 8 months ago

In my Kafka consumer, I'm processing around 100,000 transactions per second. Within the consumer, I've implemented a transaction to ensure atomicity for two operations: var tran = _multiplexer.GetDatabase(DEFAULT_DATABASE).CreateTransaction();
tran.KeyDeleteAsync(key); tran.HashSetAsync(key, entries); var success = await tran.ExecuteAsync();

The keys used in these transactions are unique for each transaction, and the likelihood of concurrent requests sharing the same key is extremely low. However, I'm concerned about the possibility of blocking other concurrent requests if one transaction takes an extended time to execute.

Will such a long transaction block all other concurrent requests, or will it only affect the key associated with that transaction? I've reviewed various documents, but I couldn't find a definitive answer to this scenario.

I attempted to replicate the situation, but extending the duration of a transaction proved to be challenging because incorporating a Lua script to introduce delays within the transaction was not feasible.

mgravell commented 8 months ago

The redis core (on the server) is single threaded, so: there is no such thing as concurrent operations. Every redis call is blocking, in terms of other connections (and other commands on the same connection). Nothing the library does will impact this. I do not recommend injecting delays inside any command (for example, via Lua) for this reason!

MattGhafouri commented 8 months ago

Thank you for your response. By concurrent requests, I mean having one Redis server and multiple clients reading and writing data while also receiving and caching data.

To clarify my question, if we have different application instances reading and writing to Redis with different keys, and if one of the consumer instances encounters a delay, such as being blocked due to a locked key or the transaction taking longer than usual for any reason, could this potentially affect other Redis clients with different keys across all application instances?

slorello89 commented 8 months ago

Long running commands have the potential to block Redis (and therefore other clients interacting with Redis). However a transaction with a single DEL and HSET is unlikely to do that - worth noting that the time complexity of HSET is linear in the number of fields you pass to it - so if you pass many thousands of fields per HSET you might run into some long running transactions.

MattGhafouri commented 8 months ago

Thanks for taking the time to provide me with the information I needed.

mgravell commented 8 months ago

as an addition: SE.Redis maps the concept of "transactions" to "multi/exec" in redis; in the absence of constraints (which are hard to describe briefly) this is really just "run these commands from start to end without interruptions from other connections", but otherwise the behavior is identical: if something is unusually slow, it will block other connections and commands on the current connection (which is true inside or outside of multi/exec)