Skip to content

Redisearch + Cluster seems unsupported #2365

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

Closed
rpkak opened this issue Sep 1, 2022 · 2 comments
Closed

Redisearch + Cluster seems unsupported #2365

rpkak opened this issue Sep 1, 2022 · 2 comments

Comments

@rpkak
Copy link

rpkak commented Sep 1, 2022

Version: 4.3.4

Platform: Python 3.10.6 on Archlinux with 5.19.5-arch1-1 kernel

Description:

Dockerfile
FROM redis/redis-stack-server:latest

RUN mkdir "/configs" \
        \
	&& echo "port 7000" >> "/configs/7000"  \
	&& echo "cluster-enabled yes" >> "/configs/7000"  \
	&& echo "cluster-config-file /configs/7000nodes.conf" >> "/configs/7000"  \
	&& echo "cluster-node-timeout 5000" >> "/configs/7000"  \
	&& echo "appendonly yes" >> "/configs/7000"  \
	&& echo "protected-mode no" >> "/configs/7000"  \
	\
	&& echo "port 7001" >> "/configs/7001"  \
	&& echo "cluster-enabled yes" >> "/configs/7001"  \
	&& echo "cluster-config-file /configs/7001nodes.conf" >> "/configs/7001"  \
	&& echo "cluster-node-timeout 5000" >> "/configs/7001"  \
	&& echo "appendonly yes" >> "/configs/7001"  \
	&& echo "protected-mode no" >> "/configs/7001"  \
	\
	&& echo "port 7002" >> "/configs/7002"  \
	&& echo "cluster-enabled yes" >> "/configs/7002"  \
	&& echo "cluster-config-file /configs/7002nodes.conf" >> "/configs/7002"  \
	&& echo "cluster-node-timeout 5000" >> "/configs/7002"  \
	&& echo "appendonly yes" >> "/configs/7002"  \
	&& echo "protected-mode no" >> "/configs/7002"  \
	\
	&& echo "port 7003" >> "/configs/7003"  \
	&& echo "cluster-enabled yes" >> "/configs/7003"  \
	&& echo "cluster-config-file /configs/7003nodes.conf" >> "/configs/7003"  \
	&& echo "cluster-node-timeout 5000" >> "/configs/7003"  \
	&& echo "appendonly yes" >> "/configs/7003"  \
	&& echo "protected-mode no" >> "/configs/7003"  \
	\
	&& echo "port 7004" >> "/configs/7004"  \
	&& echo "cluster-enabled yes" >> "/configs/7004"  \
	&& echo "cluster-config-file /configs/7004nodes.conf" >> "/configs/7004"  \
	&& echo "cluster-node-timeout 5000" >> "/configs/7004"  \
	&& echo "appendonly yes" >> "/configs/7004"  \
	&& echo "protected-mode no" >> "/configs/7004"  \
	\
	&& echo "port 7005" >> "/configs/7005"  \
	&& echo "cluster-enabled yes" >> "/configs/7005"  \
	&& echo "cluster-config-file /configs/7005nodes.conf" >> "/configs/7005"  \
	&& echo "cluster-node-timeout 5000" >> "/configs/7005"  \
	&& echo "appendonly yes" >> "/configs/7005"  \
	&& echo "protected-mode no" >> "/configs/7005"  \
	\
	&& echo "#!/usr/bin/env bash" >> "/entrypoint"  \
	&& echo "redis-server /configs/7000 --loadmodule /opt/redis-stack/lib/redisearch.so &" >> "/entrypoint"  \
	&& echo 'R7000=$!' >> "/entrypoint"  \
	&& echo "redis-server /configs/7001 --loadmodule /opt/redis-stack/lib/redisearch.so &" >> "/entrypoint"  \
	&& echo 'R7001=$!' >> "/entrypoint"  \
	&& echo "redis-server /configs/7002 --loadmodule /opt/redis-stack/lib/redisearch.so &" >> "/entrypoint"  \
	&& echo 'R7002=$!' >> "/entrypoint"  \
	&& echo "redis-server /configs/7003 --loadmodule /opt/redis-stack/lib/redisearch.so &" >> "/entrypoint"  \
	&& echo 'R7003=$!' >> "/entrypoint"  \
	&& echo "redis-server /configs/7004 --loadmodule /opt/redis-stack/lib/redisearch.so &" >> "/entrypoint"  \
	&& echo 'R7004=$!' >> "/entrypoint"  \
	&& echo "redis-server /configs/7005 --loadmodule /opt/redis-stack/lib/redisearch.so &" >> "/entrypoint"  \
	&& echo 'R7005=$!' >> "/entrypoint"  \
	&& echo "_term() {" >> "/entrypoint" \
	&& echo "  echo 'Stopping redisearch cluster'" >> "/entrypoint" \
	&& echo '  kill -TERM "$R7000"' >> "/entrypoint" \
	&& echo '  kill -TERM "$R7001"' >> "/entrypoint" \
	&& echo '  kill -TERM "$R7002"' >> "/entrypoint" \
	&& echo '  kill -TERM "$R7003"' >> "/entrypoint" \
	&& echo '  kill -TERM "$R7004"' >> "/entrypoint" \
	&& echo '  kill -TERM "$R7005"' >> "/entrypoint" \
	&& echo "}" >> "/entrypoint" \
	&& echo "sleep 1" >> "/entrypoint"  \
	&& echo "redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1 --cluster-yes" >> "/entrypoint"  \
	&& echo "trap '_term' TERM" >> "/entrypoint" \
	&& echo "trap '_term' INT" >> "/entrypoint" \
	&& echo "wait -n" >> "/entrypoint" \
	&& echo 'exit $?' >> "/entrypoint" \
	\
	&& chmod 755 "/entrypoint"

EXPOSE 7000
EXPOSE 7001
EXPOSE 7002
EXPOSE 7003
EXPOSE 7004
EXPOSE 7005

CMD [ "/entrypoint" ]

For the redis cluster I use a docker image build from the Dockerfile and start it with:

docker run -p 7000-7005:7000-7005 [imagename]

Setup:

from redis.cluster import RedisCluster, ClusterNode
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.field import TextField

r = RedisCluster(startup_nodes=[
    ClusterNode('localhost', '7000'),
    ClusterNode('localhost', '7001'),
    ClusterNode('localhost', '7002'),
    ClusterNode('localhost', '7003'),
    ClusterNode('localhost', '7004'),
    ClusterNode('localhost', '7005')
])

When I try to create a index the response is b'OK', but you can see that there was an error. Here my IPython logs:

In [2]: r.ft('foo').create_index([TextField('bar')])
MovedError
Traceback (most recent call last):
  File "path/venv/lib/python3.10/site-packages/redis/cluster.py", line 1074, in _execute_command
    response = redis_node.parse_response(connection, command, **kwargs)
  File "path/venv/lib/python3.10/site-packages/redis/client.py", line 1254, in parse_response
    response = connection.read_response()
  File "path/venv/lib/python3.10/site-packages/redis/connection.py", line 839, in read_response
    raise response
redis.exceptions.MovedError: 12182 127.0.0.1:7002
Out[2]: b'OK'

When I run r.ft('foo').create_index([TextField('bar')]) again I get:

...

ResponseError: Index already exists

So probably the first try worked as expected, but only prints an error.

By looking into the code I think that these two lines of RedisCluster._determine_nodes are causeing the issue because they always use the default node and not the node of slot of the index name:

redis-py/redis/cluster.py

Lines 836 to 837 in e6cd4fd

elif command in self.__class__.SEARCH_COMMANDS[0]:
return [self.nodes_manager.default_node]

When I removed these lines the error was gone, but I think the lines have to be there for a reason.

I while looking into the code I also saw, that Search.pipeline always (for clusters and single servers) returns a redis.commands.search.Pipeline object, which does not inharit ClusterPipeline.

Because of this r.ft('foo').pipeline() fails. Because Search.sugadd uses this function, r.ft('foo').sugadd('bar') fails as well.

@uglide
Copy link
Contributor

uglide commented Feb 8, 2023

Related to #2470

Copy link
Contributor

This issue is marked stale. It will be closed in 30 days if it is not updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants