Skip to content
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
cfb0ed8
Added support for cluster mode
barshaul Aug 11, 2021
942b35f
Merge branch 'andymccurdy:master' into cluster-mode
barshaul Aug 17, 2021
09a373d
Changed crc to use implementation from python stdlib binascii.
barshaul Aug 22, 2021
dff75fa
Merge from andymccurdy/redis-py
barshaul Aug 22, 2021
19362e0
Merged branch 'andymccurdy-master' into cluster-mode
barshaul Aug 22, 2021
21e6221
1. Added an optional argument of function pointer 'on_redis_connectio…
barshaul Aug 24, 2021
f7c5be2
Added support for 'from_url' method
barshaul Aug 24, 2021
b26f910
Fetch upstream and separate commands into smaller categories
barshaul Aug 29, 2021
52259ca
Merge branch 'andymccurdy-master' into cluster-mode
barshaul Aug 29, 2021
9af8114
Change f-string to str.format
barshaul Aug 29, 2021
d83e80d
fixings flake8 errors
barshaul Aug 29, 2021
a8aea73
1) Redis-py/master commands.py merged.
barshaul Aug 29, 2021
4da4edb
1) Redis-py/master commands.py merged.
barshaul Aug 29, 2021
c5b7cb8
Created a docker test environment for Redis Cluster with 2 primaries …
barshaul Aug 30, 2021
97ddf1c
1. Added tests for RedisCluster object.
barshaul Sep 1, 2021
be76bc2
Merged from upstream
barshaul Sep 5, 2021
eb7c576
Merge branch 'andymccurdy-master1' into cluster-mode
barshaul Sep 5, 2021
450d9ff
Added support in pub-sub
barshaul Sep 12, 2021
69d4a99
Migrated the cluster tests into the existing target (so 'make test' w…
barshaul Sep 12, 2021
42c413a
Added ClusterPubSub tests
barshaul Sep 13, 2021
cc0b088
Added tests for RedisCluster and NodesManager
barshaul Sep 13, 2021
ccd1667
Enabled existing tests for cluster mode: multiprocessing, connection …
barshaul Sep 14, 2021
72f4e99
Changes in the docker envs: Added contatiner name to each docker, cha…
barshaul Sep 14, 2021
3d51bbf
Code refactoring and cleaning
barshaul Sep 14, 2021
b79d2d8
Merge branch 'andymccurdy:master' into cluster-mode
barshaul Sep 27, 2021
8f86d12
Merge branch 'andymccurdy:master' into cluster-mode
barshaul Sep 30, 2021
166501d
Fixed 'COMMAND' response value to a dictionary
barshaul Sep 29, 2021
a1f437e
Added CommandsParser to cache all commands info and retrieve keys fro…
barshaul Sep 29, 2021
3d5df9b
Fixed CommandsParser relevant bugs
barshaul Sep 30, 2021
52e1896
Fixed CommandsParser relevant bugs
barshaul Sep 30, 2021
1ffc28e
Pipeline DISCARD support (#1565)
chayim Sep 1, 2021
6b4adf9
Changed the CommandsParser logic: if command is flagged as moveable, …
barshaul Oct 3, 2021
e68d88e
Changed the CommandsParser logic: if command is flagged as moveable, …
barshaul Oct 3, 2021
9725b19
Merge branch 'andymccurdy:master' into cluster-mode
barshaul Oct 3, 2021
d13584d
Added locks for thread safety
barshaul Oct 4, 2021
40df203
Removed skip_full_coverage_check and added require_full_coverage whic…
barshaul Oct 4, 2021
85fe672
Added partial documentation for Cluster Mode support in the README file
barshaul Oct 4, 2021
3917bc0
Fixed a small bug
barshaul Oct 4, 2021
38fe8cc
Added support for passing 'redis_connect_func' argument in RedisClust…
barshaul Oct 5, 2021
16e532e
1. Files/variables with 'slave' were renamed to 'replica'
barshaul Oct 10, 2021
0ba1008
Add support for multi-key and cluster management commands in cluster-…
asheryerm Oct 18, 2021
e6c5138
Add support for pipeline in cluster-mode
asheryerm Oct 18, 2021
d1604f1
Merge pull request #5 from asheryerm/cluster-mode
asheryerm Oct 18, 2021
44b00bf
Code cleanup
barshaul Oct 17, 2021
05cf9fc
Added & fixed tests for Cluster Commands
barshaul Oct 18, 2021
0accc89
Merging upstream
barshaul Oct 18, 2021
aecd3d4
Merge branch 'redis-master' into cluster-mode
barshaul Oct 18, 2021
1357418
Added RedisCluster documentation to the README file
barshaul Oct 19, 2021
c0a4aa1
Support additional cluster management commands in cluster-mode
asheryerm Oct 20, 2021
9745375
Fix mget_nonatomic
asheryerm Oct 21, 2021
405a688
Merge pull request #8 from asheryerm/cluster-mode
asheryerm Oct 21, 2021
cd502c6
Added support in passing node flags as target nodes: PRIMARIES, REPLI…
barshaul Oct 23, 2021
2feb75b
Merge branch 'cluster-mode' of https://github.com/barshaul/redis-py i…
barshaul Oct 23, 2021
551a475
Added skip_full_coverage_check parameter to support skipping configur…
barshaul Oct 23, 2021
d65f0dc
Changed the LoadBalancer to hold a primary_name to server_idx dict in…
barshaul Oct 24, 2021
255728c
small fix
barshaul Oct 24, 2021
ee3cacc
Added support for cluster mode
barshaul Aug 11, 2021
b24c2c5
Changed crc to use implementation from python stdlib binascii.
barshaul Aug 22, 2021
48b2065
1. Added an optional argument of function pointer 'on_redis_connectio…
barshaul Aug 24, 2021
4779f1b
Added support for 'from_url' method
barshaul Aug 24, 2021
d83c3a0
Change f-string to str.format
barshaul Aug 29, 2021
76c830b
fixings flake8 errors
barshaul Aug 29, 2021
40c6124
1) Redis-py/master commands.py merged.
barshaul Aug 29, 2021
fb8f6d0
1) Redis-py/master commands.py merged.
barshaul Aug 29, 2021
5effb9b
Created a docker test environment for Redis Cluster with 2 primaries …
barshaul Aug 30, 2021
34656ae
1. Added tests for RedisCluster object.
barshaul Sep 1, 2021
730b9b6
Added support in pub-sub
barshaul Sep 12, 2021
4e6e91f
Migrated the cluster tests into the existing target (so 'make test' w…
barshaul Sep 12, 2021
bb273c3
Added ClusterPubSub tests
barshaul Sep 13, 2021
c85df0c
Added tests for RedisCluster and NodesManager
barshaul Sep 13, 2021
0dce1e7
Enabled existing tests for cluster mode: multiprocessing, connection …
barshaul Sep 14, 2021
828accd
Changes in the docker envs: Added contatiner name to each docker, cha…
barshaul Sep 14, 2021
4e7002a
Code refactoring and cleaning
barshaul Sep 14, 2021
424bf04
Fixed 'COMMAND' response value to a dictionary
barshaul Sep 29, 2021
37aa5c0
Added CommandsParser to cache all commands info and retrieve keys fro…
barshaul Sep 29, 2021
5516db7
Fixed CommandsParser relevant bugs
barshaul Sep 30, 2021
e9ba7cb
Pipeline DISCARD support (#1565)
chayim Sep 1, 2021
057bfc6
Changed the CommandsParser logic: if command is flagged as moveable, …
barshaul Oct 3, 2021
0ef9769
Added locks for thread safety
barshaul Oct 4, 2021
74d0a0d
Removed skip_full_coverage_check and added require_full_coverage whic…
barshaul Oct 4, 2021
3cf8bdd
Added partial documentation for Cluster Mode support in the README file
barshaul Oct 4, 2021
23e6b77
Added support for passing 'redis_connect_func' argument in RedisClust…
barshaul Oct 5, 2021
157e286
1. Files/variables with 'slave' were renamed to 'replica'
barshaul Oct 10, 2021
5b6ba93
Add support for multi-key and cluster management commands in cluster-…
asheryerm Oct 18, 2021
e13892b
Add support for pipeline in cluster-mode
asheryerm Oct 18, 2021
6085b3e
Code cleanup
barshaul Oct 17, 2021
97e85c7
Added & fixed tests for Cluster Commands
barshaul Oct 18, 2021
fdcbd30
Added RedisCluster documentation to the README file
barshaul Oct 19, 2021
1ee3dc9
Added support in passing node flags as target nodes: PRIMARIES, REPLI…
barshaul Oct 23, 2021
1fa5bc5
Support additional cluster management commands in cluster-mode
asheryerm Oct 20, 2021
ffeedd7
Fix mget_nonatomic
asheryerm Oct 21, 2021
867562d
Added skip_full_coverage_check parameter to support skipping configur…
barshaul Oct 23, 2021
d0b9d95
Changed the LoadBalancer to hold a primary_name to server_idx dict in…
barshaul Oct 24, 2021
196e82b
small fix
barshaul Oct 24, 2021
b2d2311
Changed ports
barshaul Oct 26, 2021
3f45859
Merging master branch
barshaul Oct 26, 2021
59fce5b
Merging master branch
barshaul Oct 27, 2021
1c2fe3a
Merge branch 'master' of https://github.com/redis/redis-py into clust…
barshaul Oct 27, 2021
fac26e1
Pull branch cluster mode from barshaul-redis-py
barshaul Oct 27, 2021
c622f1d
Removed all single dockers for Redis Cluster nodes and created a sing…
barshaul Oct 27, 2021
30fde21
Small fix
barshaul Oct 28, 2021
50e56d5
Merge branch 'redis:master' into cluster-mode
barshaul Oct 28, 2021
5ff58d9
Added attribution for redis-py-cluster
barshaul Oct 28, 2021
41bb94a
Small flake8 fix
barshaul Oct 28, 2021
5372cb6
Skip pattern PUBSUB test for cluster mode
barshaul Oct 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions ClusterRedisExample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from redis import RedisCluster as Redis
from redis.cluster import ClusterNode

host = 'localhost'
startup_nodes = [ClusterNode(host, 6378), ClusterNode(host, 6379)]

# from_url examples
rc_url = Redis.from_url("redis://localhost:6379/0")
print(rc_url.client_list())
print(rc_url.set('foo', 'bar1'))
print(rc_url.set('zzzsdfsdf', 'bar2'))
print(rc_url.keyslot('bar'))
print(rc_url.set('{000}', 'bar3'))
print(f"get_all_nodes: {rc_url.get_all_nodes()}")
print(rc_url.get('foo'))
print(rc_url.keys())
# rc = Redis(host=host, port=6379)
rc = Redis(startup_nodes=startup_nodes, decode_responses=True)
print(rc.get('{000}'))
print(rc.keys())
print(rc.cluster_save_config(rc.get_all_primaries()))
print(rc.cluster_save_config(rc.get_node(host=host, port=6378)))

# READONLY examples
rc_readonly = Redis(startup_nodes=startup_nodes, read_from_replicas=True)
for i in range(0, 4):
# Assigning the read command to the slot's servers in a Round-Robin manner
print(rc_readonly.get('zzz'))
# set command would be directed only to the slot's primary node
rc_readonly.set('bar', 'foo2')
# reset READONLY flag
print(rc_readonly.readwrite())
# now the get command would be directed only to the slot's primary node
print(rc_readonly.get('bar'))
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ dev: base
test: dev
docker-compose run --rm test /redis-py/docker-entry.sh

test-cluster: dev
docker-compose run --rm test_cluster /redis-py/docker-entry.sh

clean:
docker-compose stop
docker-compose rm -f
34 changes: 33 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,45 @@ services:
ports:
- "26381:26381"

cluster_master_1:
build: docker/cluster/master_1
ports:
- "7000:7000"

cluster_master_2:
build: docker/cluster/master_2
ports:
- "7001:7001"

cluster_slave_1:
build: docker/cluster/slave_1
depends_on:
- "cluster_master_1"
ports:
- "7002:7002"
environment:
CLUSTER_MASTER_HOST: cluster_master_1

cluster_slave_2:
build: docker/cluster/slave_2
depends_on:
- "cluster_master_2"
ports:
- "7003:7003"
environment:
CLUSTER_MASTER_HOST: cluster_master_2

test:
build: .
depends_on:
- "sentinel_3"
- "cluster_slave_2"
environment:
REDIS_MASTER_HOST: master
REDIS_MASTER_PORT: 6379
DB: 9
CLUSTER_MASTER_HOST: cluster_master_1
CLUSTER_MASTER_PORT: 7000
CLUSTER_DB: 0
CI:
CI_BUILD_ID:
CI_BUILD_URL:
Expand Down
12 changes: 11 additions & 1 deletion docker-entry.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,15 @@ if [ "${GITHUB_ACTIONS}" = true ] ; then
fi

# use the wait-for-it util to ensure the server is running before invoking Tox
util/wait-for-it.sh ${REDIS_MASTER} -- tox -- --redis-url=redis://"${REDIS_MASTER}"/9
util/wait-for-it.sh ${REDIS_MASTER} -- tox -- --redis-url=redis://"${REDIS_MASTER}"/${DB}

if [[ -v CLUSTER_MASTER_HOST ]] ; then
# Test Cluster Redis
CLUSTER_MASTER="${CLUSTER_MASTER_HOST}":"${CLUSTER_MASTER_PORT}"
echo "Testing against Cluster-Redis Server: ${CLUSTER_MASTER}"
# We can skip these environments since they were already tested in the strict Redis tests
export TOX_SKIP_ENV='.*?(flake8|covreport|codecov)'
tox -- --redis-url=redis://"${CLUSTER_MASTER}"/${CLUSTER_DB}
fi


9 changes: 9 additions & 0 deletions docker/cluster/master_1/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM redis-py-base:latest

COPY redis.conf /usr/local/etc/redis/redis.conf
COPY nodes.conf /usr/local/etc/redis/nodes.conf

EXPOSE 7000

RUN chmod 666 /usr/local/etc/redis/nodes.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
4 changes: 4 additions & 0 deletions docker/cluster/master_1/nodes.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
18883b616f3f42c441cdb7d1de6106852e766156 cluster_master_1:7000@17000 myself,master - 0 1630232956498 2 connected 0-8191
01eca22229cf3c652b6fca0d09ff694183e0d2e3 cluster_master_2:7001@17001 master - 0 1630232956000 1 connected 8192-16383
52611e796814b78e90ad94be9d769a9f4f668f9a cluster_slave_1:7002@17002 slave 18883b616f3f42c441cdb7d1de6106852e766156 0 1630232954000 1 connected
22221e7y5814b78e90ad94k8lh969a9ff4665h7a cluster_slave_2:7003@17003 slave 01eca22229cf3c652b6fca0d09ff694183e0d2e3 0 1630232954000 1 connected
4 changes: 4 additions & 0 deletions docker/cluster/master_1/redis.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bind cluster_master_1 127.0.0.1
port 7000
cluster-enabled yes
cluster-config-file /usr/local/etc/redis/nodes.conf
9 changes: 9 additions & 0 deletions docker/cluster/master_2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM redis-py-base:latest

COPY redis.conf /usr/local/etc/redis/redis.conf
COPY nodes.conf /usr/local/etc/redis/nodes.conf

EXPOSE 7001

RUN chmod 666 /usr/local/etc/redis/nodes.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
4 changes: 4 additions & 0 deletions docker/cluster/master_2/nodes.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
18883b616f3f42c441cdb7d1de6106852e766156 cluster_master_1:7000@17000 master - 0 1630232956498 2 connected 0-8191
01eca22229cf3c652b6fca0d09ff694183e0d2e3 cluster_master_2:7001@17001 myself,master - 0 1630232956000 1 connected 8192-16383
52611e796814b78e90ad94be9d769a9f4f668f9a cluster_slave_1:7002@17002 slave 18883b616f3f42c441cdb7d1de6106852e766156 0 1630232954000 1 connected
22221e7y5814b78e90ad94k8lh969a9ff4665h7a cluster_slave_2:7003@17003 slave 01eca22229cf3c652b6fca0d09ff694183e0d2e3 0 1630232954000 1 connected
4 changes: 4 additions & 0 deletions docker/cluster/master_2/redis.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bind cluster_master_2 127.0.0.1
port 7001
cluster-enabled yes
cluster-config-file /usr/local/etc/redis/nodes.conf
9 changes: 9 additions & 0 deletions docker/cluster/slave_1/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM redis-py-base:latest

COPY redis.conf /usr/local/etc/redis/redis.conf
COPY nodes.conf /usr/local/etc/redis/nodes.conf

EXPOSE 7002

RUN chmod 666 /usr/local/etc/redis/nodes.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
4 changes: 4 additions & 0 deletions docker/cluster/slave_1/nodes.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
18883b616f3f42c441cdb7d1de6106852e766156 cluster_master_1:7000@17000 master - 0 1630232956498 2 connected 0-8191
01eca22229cf3c652b6fca0d09ff694183e0d2e3 cluster_master_2:7001@17001 master - 0 1630232956000 1 connected 8192-16383
52611e796814b78e90ad94be9d769a9f4f668f9a cluster_slave_1:7002@17002 myself,slave 18883b616f3f42c441cdb7d1de6106852e766156 0 1630232954000 1 connected
22221e7y5814b78e90ad94k8lh969a9ff4665h7a cluster_slave_2:7003@17003 slave 01eca22229cf3c652b6fca0d09ff694183e0d2e3 0 1630232954000 1 connected
4 changes: 4 additions & 0 deletions docker/cluster/slave_1/redis.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bind cluster_slave_1 127.0.0.1
port 7002
cluster-enabled yes
cluster-config-file /usr/local/etc/redis/nodes.conf
9 changes: 9 additions & 0 deletions docker/cluster/slave_2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM redis-py-base:latest

COPY redis.conf /usr/local/etc/redis/redis.conf
COPY nodes.conf /usr/local/etc/redis/nodes.conf

EXPOSE 7003

RUN chmod 666 /usr/local/etc/redis/nodes.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
4 changes: 4 additions & 0 deletions docker/cluster/slave_2/nodes.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
18883b616f3f42c441cdb7d1de6106852e766156 cluster_master_1:7000@17000 master - 0 1630232956498 2 connected 0-8191
01eca22229cf3c652b6fca0d09ff694183e0d2e3 cluster_master_2:7001@17001 master - 0 1630232956000 1 connected 8192-16383
52611e796814b78e90ad94be9d769a9f4f668f9a cluster_slave_1:7002@17002 slave 18883b616f3f42c441cdb7d1de6106852e766156 0 1630232954000 1 connected
22221e7y5814b78e90ad94k8lh969a9ff4665h7a cluster_slave_2:7003@17003 myself,slave 01eca22229cf3c652b6fca0d09ff694183e0d2e3 0 1630232954000 1 connected
4 changes: 4 additions & 0 deletions docker/cluster/slave_2/redis.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bind cluster_slave_2 127.0.0.1
port 7003
cluster-enabled yes
cluster-config-file /usr/local/etc/redis/nodes.conf
2 changes: 2 additions & 0 deletions redis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from redis.client import Redis, StrictRedis
from redis.cluster import RedisCluster
from redis.connection import (
BlockingConnectionPool,
ConnectionPool,
Expand Down Expand Up @@ -49,6 +50,7 @@ def int_or_str(value):
'PubSubError',
'ReadOnlyError',
'Redis',
'RedisCluster',
'RedisError',
'ResponseError',
'SSLConnection',
Expand Down
11 changes: 7 additions & 4 deletions redis/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ def __init__(self, host='localhost', port=6379,
ssl_check_hostname=False,
max_connections=None, single_connection_client=False,
health_check_interval=0, client_name=None, username=None,
retry=None):
retry=None, redis_connect_func=None):
"""
Initialize a new Redis client.
To specify a retry policy, first set `retry_on_timeout` to `True`
Expand Down Expand Up @@ -844,7 +844,8 @@ def __init__(self, host='localhost', port=6379,
'retry': copy.deepcopy(retry),
'max_connections': max_connections,
'health_check_interval': health_check_interval,
'client_name': client_name
'client_name': client_name,
'redis_connect_func': redis_connect_func
}
# based on input, setup appropriate connection args
if unix_socket_path is not None:
Expand Down Expand Up @@ -1138,14 +1139,16 @@ class PubSub:
HEALTH_CHECK_MESSAGE = 'redis-py-health-check'

def __init__(self, connection_pool, shard_hint=None,
ignore_subscribe_messages=False):
ignore_subscribe_messages=False, encoder=None):
self.connection_pool = connection_pool
self.shard_hint = shard_hint
self.ignore_subscribe_messages = ignore_subscribe_messages
self.connection = None
# we need to know the encoding options for this connection in order
# to lookup channel and pattern names for callback handlers.
self.encoder = self.connection_pool.get_encoder()
self.encoder = encoder
if self.encoder is None:
self.encoder = self.connection_pool.get_encoder()
if self.encoder.decode_responses:
self.health_check_response = ['pong', self.HEALTH_CHECK_MESSAGE]
else:
Expand Down
Loading