Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README code snippets formatted to highlight properly #1888

Merged
merged 1 commit into from Jan 25, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
169 changes: 85 additions & 84 deletions README.md
Expand Up @@ -968,25 +968,25 @@ instance can be created:
- Using 'host' and 'port' arguments:

``` pycon
>>> from redis.cluster import RedisCluster as Redis
>>> rc = Redis(host='localhost', port=6379)
>>> print(rc.get_nodes())
>>> from redis.cluster import RedisCluster as Redis
>>> rc = Redis(host='localhost', port=6379)
>>> print(rc.get_nodes())
[[host=127.0.0.1,port=6379,name=127.0.0.1:6379,server_type=primary,redis_connection=Redis<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=0>>>], [host=127.0.0.1,port=6378,name=127.0.0.1:6378,server_type=primary,redis_connection=Redis<ConnectionPool<Connection<host=127.0.0.1,port=6378,db=0>>>], [host=127.0.0.1,port=6377,name=127.0.0.1:6377,server_type=replica,redis_connection=Redis<ConnectionPool<Connection<host=127.0.0.1,port=6377,db=0>>>]]
```
- Using the Redis URL specification:

``` pycon
>>> from redis.cluster import RedisCluster as Redis
>>> rc = Redis.from_url("redis://localhost:6379/0")
>>> from redis.cluster import RedisCluster as Redis
>>> rc = Redis.from_url("redis://localhost:6379/0")
```

- Directly, via the ClusterNode class:

``` pycon
>>> from redis.cluster import RedisCluster as Redis
>>> from redis.cluster import ClusterNode
>>> nodes = [ClusterNode('localhost', 6379), ClusterNode('localhost', 6378)]
>>> rc = Redis(startup_nodes=nodes)
>>> from redis.cluster import RedisCluster as Redis
>>> from redis.cluster import ClusterNode
>>> nodes = [ClusterNode('localhost', 6379), ClusterNode('localhost', 6378)]
>>> rc = Redis(startup_nodes=nodes)
```

When a RedisCluster instance is being created it first attempts to establish a
Expand Down Expand Up @@ -1016,18 +1016,18 @@ The 'target_nodes' parameter is explained in the following section,
'Specifying Target Nodes'.

``` pycon
>>> # target-nodes: the node that holds 'foo1's key slot
>>> rc.set('foo1', 'bar1')
>>> # target-nodes: the node that holds 'foo2's key slot
>>> rc.set('foo2', 'bar2')
>>> # target-nodes: the node that holds 'foo1's key slot
>>> print(rc.get('foo1'))
b'bar'
>>> # target-node: default-node
>>> print(rc.keys())
[b'foo1']
>>> # target-node: default-node
>>> rc.ping()
>>> # target-nodes: the node that holds 'foo1's key slot
>>> rc.set('foo1', 'bar1')
>>> # target-nodes: the node that holds 'foo2's key slot
>>> rc.set('foo2', 'bar2')
>>> # target-nodes: the node that holds 'foo1's key slot
>>> print(rc.get('foo1'))
b'bar'
>>> # target-node: default-node
>>> print(rc.keys())
[b'foo1']
>>> # target-node: default-node
>>> rc.ping()
```

**Specifying Target Nodes:**
Expand All @@ -1043,18 +1043,18 @@ the client will be able to resolve the nodes flag again with the new topology
and attempt to retry executing the command.

``` pycon
>>> from redis.cluster import RedisCluster as Redis
>>> # run cluster-meet command on all of the cluster's nodes
>>> rc.cluster_meet('127.0.0.1', 6379, target_nodes=Redis.ALL_NODES)
>>> # ping all replicas
>>> rc.ping(target_nodes=Redis.REPLICAS)
>>> # ping a random node
>>> rc.ping(target_nodes=Redis.RANDOM)
>>> # get the keys from all cluster nodes
>>> rc.keys(target_nodes=Redis.ALL_NODES)
[b'foo1', b'foo2']
>>> # execute bgsave in all primaries
>>> rc.bgsave(Redis.PRIMARIES)
>>> from redis.cluster import RedisCluster as Redis
>>> # run cluster-meet command on all of the cluster's nodes
>>> rc.cluster_meet('127.0.0.1', 6379, target_nodes=Redis.ALL_NODES)
>>> # ping all replicas
>>> rc.ping(target_nodes=Redis.REPLICAS)
>>> # ping a random node
>>> rc.ping(target_nodes=Redis.RANDOM)
>>> # get the keys from all cluster nodes
>>> rc.keys(target_nodes=Redis.ALL_NODES)
[b'foo1', b'foo2']
>>> # execute bgsave in all primaries
>>> rc.bgsave(Redis.PRIMARIES)
```

You could also pass ClusterNodes directly if you want to execute a command on a
Expand All @@ -1064,28 +1064,28 @@ will not be made, since the passed target node/s may no longer be valid, and
the relevant cluster or connection error will be returned.

``` pycon
>>> node = rc.get_node('localhost', 6379)
>>> # Get the keys only for that specific node
>>> rc.keys(target_nodes=node)
>>> # get Redis info from a subset of primaries
>>> subset_primaries = [node for node in rc.get_primaries() if node.port > 6378]
>>> rc.info(target_nodes=subset_primaries)
>>> node = rc.get_node('localhost', 6379)
>>> # Get the keys only for that specific node
>>> rc.keys(target_nodes=node)
>>> # get Redis info from a subset of primaries
>>> subset_primaries = [node for node in rc.get_primaries() if node.port > 6378]
>>> rc.info(target_nodes=subset_primaries)
```

In addition, the RedisCluster instance can query the Redis instance of a
specific node and execute commands on that node directly. The Redis client,
however, does not handle cluster failures and retries.

``` pycon
>>> cluster_node = rc.get_node(host='localhost', port=6379)
>>> print(cluster_node)
[host=127.0.0.1,port=6379,name=127.0.0.1:6379,server_type=primary,redis_connection=Redis<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=0>>>]
>>> r = cluster_node.redis_connection
>>> r.client_list()
[{'id': '276', 'addr': '127.0.0.1:64108', 'fd': '16', 'name': '', 'age': '0', 'idle': '0', 'flags': 'N', 'db': '0', 'sub': '0', 'psub': '0', 'multi': '-1', 'qbuf': '26', 'qbuf-free': '32742', 'argv-mem': '10', 'obl': '0', 'oll': '0', 'omem': '0', 'tot-mem': '54298', 'events': 'r', 'cmd': 'client', 'user': 'default'}]
>>> # Get the keys only for that specific node
>>> r.keys()
[b'foo1']
>>> cluster_node = rc.get_node(host='localhost', port=6379)
>>> print(cluster_node)
[host=127.0.0.1,port=6379,name=127.0.0.1:6379,server_type=primary,redis_connection=Redis<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=0>>>]
>>> r = cluster_node.redis_connection
>>> r.client_list()
[{'id': '276', 'addr': '127.0.0.1:64108', 'fd': '16', 'name': '', 'age': '0', 'idle': '0', 'flags': 'N', 'db': '0', 'sub': '0', 'psub': '0', 'multi': '-1', 'qbuf': '26', 'qbuf-free': '32742', 'argv-mem': '10', 'obl': '0', 'oll': '0', 'omem': '0', 'tot-mem': '54298', 'events': 'r', 'cmd': 'client', 'user': 'default'}]
>>> # Get the keys only for that specific node
>>> r.keys()
[b'foo1']
```

**Multi-key commands:**
Expand All @@ -1105,14 +1105,14 @@ operations batch the keys according to their hash value, and then each batch is
sent separately to the slot's owner.

``` pycon
# Atomic operations can be used when all keys are mapped to the same slot
>>> rc.mset({'{foo}1': 'bar1', '{foo}2': 'bar2'})
>>> rc.mget('{foo}1', '{foo}2')
[b'bar1', b'bar2']
# Non-atomic multi-key operations splits the keys into different slots
>>> rc.mset_nonatomic({'foo': 'value1', 'bar': 'value2', 'zzz': 'value3')
>>> rc.mget_nonatomic('foo', 'bar', 'zzz')
[b'value1', b'value2', b'value3']
# Atomic operations can be used when all keys are mapped to the same slot
>>> rc.mset({'{foo}1': 'bar1', '{foo}2': 'bar2'})
>>> rc.mget('{foo}1', '{foo}2')
[b'bar1', b'bar2']
# Non-atomic multi-key operations splits the keys into different slots
>>> rc.mset_nonatomic({'foo': 'value1', 'bar': 'value2', 'zzz': 'value3')
>>> rc.mget_nonatomic('foo', 'bar', 'zzz')
[b'value1', b'value2', b'value3']
```

**Cluster PubSub:**
Expand All @@ -1135,11 +1135,11 @@ See [redis-py-cluster documentation](https://redis-py-cluster.readthedocs.io/en/
for more.

``` pycon
>>> p1 = rc.pubsub()
# p1 connection will be set to the node that holds 'foo' keyslot
>>> p1.subscribe('foo')
# p2 connection will be set to node 'localhost:6379'
>>> p2 = rc.pubsub(rc.get_node('localhost', 6379))
>>> p1 = rc.pubsub()
# p1 connection will be set to the node that holds 'foo' keyslot
>>> p1.subscribe('foo')
# p2 connection will be set to node 'localhost:6379'
>>> p2 = rc.pubsub(rc.get_node('localhost', 6379))
```

**Read Only Mode**
Expand All @@ -1157,20 +1157,20 @@ target_nodes='replicas', and read-write access can be restored by calling the
readwrite() method.

``` pycon
>>> from cluster import RedisCluster as Redis
# Use 'debug' log level to print the node that the command is executed on
>>> rc_readonly = Redis(startup_nodes=startup_nodes,
read_from_replicas=True)
>>> rc_readonly.set('{foo}1', 'bar1')
>>> for i in range(0, 4):
# Assigns read command to the slot's hosts in a Round-Robin manner
>>> rc_readonly.get('{foo}1')
# set command would be directed only to the slot's primary node
>>> rc_readonly.set('{foo}2', 'bar2')
# reset READONLY flag
>>> rc_readonly.readwrite(target_nodes='replicas')
# now the get command would be directed only to the slot's primary node
>>> rc_readonly.get('{foo}1')
>>> from cluster import RedisCluster as Redis
# Use 'debug' log level to print the node that the command is executed on
>>> rc_readonly = Redis(startup_nodes=startup_nodes,
... read_from_replicas=True)
>>> rc_readonly.set('{foo}1', 'bar1')
>>> for i in range(0, 4):
... # Assigns read command to the slot's hosts in a Round-Robin manner
... rc_readonly.get('{foo}1')
# set command would be directed only to the slot's primary node
>>> rc_readonly.set('{foo}2', 'bar2')
# reset READONLY flag
>>> rc_readonly.readwrite(target_nodes='replicas')
# now the get command would be directed only to the slot's primary node
>>> rc_readonly.get('{foo}1')
```

**Cluster Pipeline**
Expand All @@ -1187,16 +1187,17 @@ by significantly reducing the the number of network round trips between the
client and the server.

``` pycon
>>> with rc.pipeline() as pipe:
>>> pipe.set('foo', 'value1')
>>> pipe.set('bar', 'value2')
>>> pipe.get('foo')
>>> pipe.get('bar')
>>> print(pipe.execute())
[True, True, b'value1', b'value2']
>>> pipe.set('foo1', 'bar1').get('foo1').execute()
[True, b'bar1']
>>> with rc.pipeline() as pipe:
... pipe.set('foo', 'value1')
... pipe.set('bar', 'value2')
... pipe.get('foo')
... pipe.get('bar')
... print(pipe.execute())
[True, True, b'value1', b'value2']
... pipe.set('foo1', 'bar1').get('foo1').execute()
[True, b'bar1']
```

Please note:
- RedisCluster pipelines currently only support key-based commands.
- The pipeline gets its 'read_from_replicas' value from the cluster's parameter.
Expand Down