Search code examples
transactionsredisredis-cluster

Is there any Redis client (Java prefered) which supports transactions on Redis cluster?


I looked online intensively but couldn't find a mature Redis client offering this functionality. Only found this project. Anyone knows of a Redis client offering the above mentioned? Thank you.


Solution

  • Transactions within a Redis Cluster are a different story than transaction with Redis Standalone.

    TL;DR;

    That's more a conceptual problem regarding guarantees and trade-offs than a client issue.

    Explanation

    In Redis Cluster, a particular node is a master for one or more hash-slots, that’s the partitioning scheme to shard data amongst multiple nodes. One hash-slot, calculated from the keys used in the command, lives on one node. Commands with multiple keys are limited to yield to the same hash-slot. Otherwise, they are rejected. Such constellations are called cross-slot.

    Transactions seem to be the solution to execute commands to cross-slot keys but at a certain point, one would leave the scope of one node and would need another node to continue the transaction. This can be if the one key lives on one node and the other key lives on another node. There is still no transaction coordination and that can sometimes be an issue to Redis Cluster issues.

    A high-level API providing transactional support for Redis Cluster faces multiple issues and there are two strategies so far, how to deal with transactions in Redis Cluster:

    Support transactions if all keys are located on one node

    This option allows fully-featured transactions. The client library is required to keep track of the node the transaction is executed and prohibit keys outside the slot range for the time the transaction is in progress. Because the slot can be only determined by using a command containing a key, the client needs to set a transactional flag and on the very first command containing a key the MULTI command needs to be issued, right before the first command within the transaction. The limitation here is clearly the requirement to have all keys located on one node.

    Distributed transactions

    In this case, multiple transactions are started on all nodes that join the distributed transaction. This distributed transaction can include keys from all master nodes. Once the transaction is executed, the client library triggers the execution of the transaction, the library collects all results (to maintain the order of command results) and returns it to the caller.

    This style of transactions is transparent to the client. As soon as a key on a particular node is requested and the node is not yet part of the transaction, aMULTI command is issued to join the node to the transaction. The drawback here is that transactions cannot be conditional anymore (WATCH). The individual transactions have no knowledge whether a key was changed on a different node, and so one transaction could be rolled back while the other transactions would succeed. Sounds a bit like two-phase-commit.

    Conclusion

    Redis Transactions feels like atomic command batching that can be made conditional. It’s important to remember that command execution is deferred because read results return at the moment of transaction execution and not at the time the command is issued.

    For Redis Cluster, clients have not decided on a global strategy. It’s safe to run transactions on a particular Redis Cluster node but you’re limited to the keys served by that node. Both possible strategies have properties that might be useful for certain use-cases but also come with limitations.