@@ -177,20 +177,48 @@ the server.
177177 ... pipe.set(' foo1' , ' bar1' ).get(' foo1' ).execute()
178178 [True , b ' bar1' ]
179179
180- Please note: - RedisCluster pipelines currently only support key-based
181- commands. - The pipeline gets its ‘read_from_replicas’ value from the
182- cluster’s parameter. Thus, if read from replications is enabled in the
183- cluster instance, the pipeline will also direct read commands to
184- replicas. - The ‘transaction’ option is NOT supported in cluster-mode.
185- In non-cluster mode, the ‘transaction’ option is available when
186- executing pipelines. This wraps the pipeline commands with MULTI/EXEC
187- commands, and effectively turns the pipeline commands into a single
188- transaction block. This means that all commands are executed
189- sequentially without any interruptions from other clients. However, in
190- cluster-mode this is not possible, because commands are partitioned
191- according to their respective destination nodes. This means that we can
192- not turn the pipeline commands into one transaction block, because in
193- most cases they are split up into several smaller pipelines.
180+ Please note:
181+
182+ - RedisCluster pipelines currently only support key-based commands.
183+ - The pipeline gets its ‘read_from_replicas’ value from the
184+ cluster’s parameter. Thus, if read from replications is enabled in
185+ the cluster instance, the pipeline will also direct read commands to
186+ replicas.
187+
188+
189+ Transactions in clusters
190+ ~~~~~~~~~~~~~~~~~~~~~~~~
191+
192+ Transactions are supported in cluster-mode with one caveat: all keys of
193+ all commands issued on a transaction pipeline must reside on the
194+ same slot. This is similar to the limitation of multikey commands in
195+ cluster. The reason behind this is that the Redis engine does not offer
196+ a mechanism to block or exchange key data across nodes on the fly. A
197+ client may add some logic to abstract engine limitations when running
198+ on a cluster, such as the pipeline behavior explained on the previous
199+ block, but there is no simple way that a client can enforce atomicity
200+ across nodes on a distributed system.
201+
202+ The compromise of limiting the transaction pipeline to same-slot keys
203+ is exactly that: a compromise. While this behavior is differnet from
204+ non-transactional cluster pipelines, it simplifies migration of clients
205+ from standalone to cluster under some circumstances. Note that application
206+ code that issues multi/exec commands on a standalone client without
207+ embedding them within a pipeline would eventually get ‘AttributeError’s.
208+ With this approach, if the application uses ‘client.pipeline(transaction=True)’,
209+ then switching the client with a cluster-aware instance would simplify
210+ code changes (to some extent). This may be true for application code that
211+ makes use of hash keys, since its transactions may are already be
212+ mapping all commands to the same slot.
213+
214+ An alternative is some kind of two-step commit solution, where a slot
215+ validation is run before the actual commands are run. This could work
216+ with controlled node maintenance but does not cover single node failures.
217+
218+ Cluster transaction support (pipeline/multi/exec) was originally developed by
219+ Scopely and contributed to redis-py under the MIT License.
220+
221+
194222
195223Publish / Subscribe
196224-------------------
0 commit comments