Redis Cluster¶
If your infrastructure contains a Redis Cluster, coredis provides
a RedisCluster client than can be used with the same API
as Redis but with awareness of routing the operations
to the appropriate node in the cluster.
Request routing¶
For operations that operate on single keys the RedisCluster client
simply routes the command to the appropriate node that is serving the slot that contains the key.
There are other categories of operations that cannot simply be used with redis cluster
by just routing it to the appropriate node by a single key (such as commands that don’t contain keys, or
contain multiple keys). coredis uses a few routing strategies detailed below, to handle some of these
operations so that the methods in RedisCluster can be used in a consistent manner.
Danger
For write operations that interact with multiple slots, this means that even if coredis is
able to distribute the operation through sub requests - the actual atomicity of the request is lost
as a failure on one node will leave the successful nodes in an inconsistent state. If the risk of this
scenario is unacceptable the automatic routing for cross slot commands can be disabled by setting
non_atomic_cross_slot to False.
Commands routed to all nodes in the cluster¶
- Server commands
coredis.RedisCluster.acl_deluser()The result is the first response if all responses are consistent
coredis.RedisCluster.acl_load()The result is the first response if all responses are consistent
coredis.RedisCluster.acl_save()The result is the first response if all responses are consistent
coredis.RedisCluster.acl_setuser()The result is the first response if all responses are consistent
coredis.RedisCluster.config_resetstat()The result is
Trueif all responses areTruecoredis.RedisCluster.config_set()The result is
Trueif all responses areTruecoredis.RedisCluster.memory_purge()The result is
Trueif all responses areTruecoredis.RedisCluster.module_load()The result is
Trueif all responses areTruecoredis.RedisCluster.module_loadex()The result is
Trueif all responses areTruecoredis.RedisCluster.module_unload()The result is
Trueif all responses areTruecoredis.RedisCluster.save()The result is the first response if all responses are consistent
- Cluster commands
coredis.RedisCluster.cluster_saveconfig()The result is
Trueif all responses areTrue
- Connection commands
coredis.RedisCluster.echo()The result is the first response if all responses are consistent
- Pubsub commands
coredis.RedisCluster.pubsub_channels()The result is the union of the results
coredis.RedisCluster.pubsub_numsub()The result is the merged mapping
coredis.RedisCluster.pubsub_shardchannels()The result is the union of the results
coredis.RedisCluster.pubsub_shardnumsub()The result is the merged mapping
- Scripting commands
coredis.RedisCluster.script_flush()The result is
Trueif all responses areTruecoredis.RedisCluster.script_load()The result is the first response if all responses are consistent
Commands routed to all primaries in the cluster¶
- Server commands
coredis.RedisCluster.flushall()The result is the first response if all responses are consistent
coredis.RedisCluster.flushdb()The result is the first response if all responses are consistent
- Scripting commands
coredis.RedisCluster.function_delete()The result is the first response if all responses are consistent
coredis.RedisCluster.function_flush()The result is the first response if all responses are consistent
coredis.RedisCluster.function_kill()The result is the first response that is not an error
coredis.RedisCluster.function_load()The result is the first response if all responses are consistent
coredis.RedisCluster.function_restore()The result is the first response if all responses are consistent
coredis.RedisCluster.script_exists()The result is the logical AND of all responses
coredis.RedisCluster.script_kill()The result is the first response that is not an error
- Generic commands
coredis.RedisCluster.keys()The result is the union of the results
- Connection commands
coredis.RedisCluster.ping()The result is the first response if all responses are consistent
- Search commands
coredis.modules.Search.config_set()The result is the first response if all responses are consistent
coredis.modules.Search.list()The result is the union of the results
- Timeseries commands
coredis.modules.TimeSeries.mget()The result is the merged mapping
coredis.modules.TimeSeries.mrange()The result is the merged mapping
coredis.modules.TimeSeries.mrevrange()The result is the merged mapping
coredis.modules.TimeSeries.queryindex()The result is the union of the results
Commands routed to the nodes serving the keys in the command¶
- Generic commands
coredis.RedisCluster.delete()The result is the sum of results
coredis.RedisCluster.exists()The result is the sum of results
coredis.RedisCluster.touch()The result is the sum of results
coredis.RedisCluster.unlink()The result is the sum of results
- String commands
coredis.RedisCluster.mget()The result is the concatenations of the results
coredis.RedisCluster.mset()The result is
Trueif all responses areTrue
- Json commands
coredis.modules.Json.mget()The result is the concatenations of the results
coredis.modules.Json.mset()The result is
Trueif all responses areTrue
Commands routed to a random node in the cluster¶
- Server commands
coredis.RedisCluster.acl_cat()The result is the response from the node
coredis.RedisCluster.acl_dryrun()The result is the response from the node
coredis.RedisCluster.acl_genpass()The result is the response from the node
coredis.RedisCluster.acl_getuser()The result is the response from the node
coredis.RedisCluster.acl_list()The result is the response from the node
coredis.RedisCluster.acl_users()The result is the response from the node
coredis.RedisCluster.acl_whoami()The result is the response from the node
coredis.RedisCluster.command()The result is the response from the node
coredis.RedisCluster.command_count()The result is the response from the node
coredis.RedisCluster.command_docs()The result is the response from the node
coredis.RedisCluster.command_getkeys()The result is the response from the node
coredis.RedisCluster.command_getkeysandflags()The result is the response from the node
coredis.RedisCluster.command_info()The result is the response from the node
coredis.RedisCluster.command_list()The result is the response from the node
coredis.RedisCluster.info()The result is the response from the node
coredis.RedisCluster.module_list()The result is the response from the node
- Cluster commands
coredis.RedisCluster.cluster_count_failure_reports()The result is the response from the node
coredis.RedisCluster.cluster_info()The result is the response from the node
coredis.RedisCluster.cluster_keyslot()The result is the response from the node
coredis.RedisCluster.cluster_meet()The result is the response from the node
coredis.RedisCluster.cluster_nodes()The result is the response from the node
coredis.RedisCluster.cluster_replicas()The result is the response from the node
coredis.RedisCluster.cluster_shards()The result is the response from the node
coredis.RedisCluster.cluster_slaves()The result is the response from the node
coredis.RedisCluster.cluster_slots()The result is the response from the node
- Scripting commands
coredis.RedisCluster.function_dump()The result is the response from the node
coredis.RedisCluster.function_list()The result is the response from the node
coredis.RedisCluster.function_stats()The result is the response from the node
- Pubsub commands
coredis.RedisCluster.publish()The result is the response from the node
- Generic commands
coredis.RedisCluster.randomkey()The result is the response from the node
- Search commands
coredis.modules.Search.config_get()The result is the response from the node
Commands routed to node(s) based on the slot id(s) in the command arguments¶
- Cluster commands
coredis.RedisCluster.cluster_countkeysinslot()The result is the response from the node
coredis.RedisCluster.cluster_delslots()The result is
Trueif all responses areTruecoredis.RedisCluster.cluster_delslotsrange()The result is
Trueif all responses areTruecoredis.RedisCluster.cluster_getkeysinslot()The result is the response from the node
Replication¶
coredis supports ensuring synchronous replication of writes using the WAIT
command. This is abstracted away with the ensure_replication()
context manager.
The following example will ensure that the SET is replicated to atleast 2 replicas within 100 milliseconds (default
value of timeout_ms),
else raise a ReplicationError:
import asyncio
from coredis import RedisCluster
from coredis.connection import TCPLocation
async def test():
async with RedisCluster(startup_nodes=[TCPLocation("127.0.0.1", 7000)]) as client:
with client.ensure_replication(replicas=2):
await client.set("fubar", 1)
asyncio.run(test())