@@ -177,20 +177,48 @@ the server.
177
177
... pipe.set(' foo1' , ' bar1' ).get(' foo1' ).execute()
178
178
[True , b ' bar1' ]
179
179
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
+
194
222
195
223
Publish / Subscribe
196
224
-------------------
0 commit comments