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

Error: All keys in the pipeline should belong to the same slots allocation group #1602

Open
ArtemHoruzhenko opened this issue Jun 10, 2022 · 4 comments

Comments

@ArtemHoruzhenko
Copy link

There is an error when trying to execute pipeline on IORedis.Cluster instance.
I'm sure that data belongs to a single shard. When I get some particular node using .getNodes and execute pipeline on that particular node (IORedis.Redis instance) it works fine

Environment:

Redis Cloud Cluster with 6 shards

Data example:

set "\xac\xed\x00\x05t\x0a4100000252" bar
set "\xac\xed\x00\x05t\x0a4100000255" bar

These 2 keys should be allocated to the same shard.

<IORedis.Cluster>.pipeline([
  ['type', <Buffer for \xac\xed\x00\x05t\x0a4100000252>],
  ['type', <Buffer for \xac\xed\x00\x05t\x0a4100000255>],
]).exec()

Will throw an error: All keys in the pipeline should belong to the same slots allocation group

But if you pick any node from the target shard and execute the same pipeline on it (<IORedis.Redis>.pipelien(...).exec()) it will work fine (just to prove that keys belongs to the same shard)

Also interesting thing:

<IORedis.Cluster>.pipeline([
  ['memory usage', <Buffer for \xac\xed\x00\x05t\x0a4100000252>, 'samples', '0'],
  ['memory usage', <Buffer for \xac\xed\x00\x05t\x0a4100000255>, 'samples', '0'],
]).exec()

Will fail with the same error when:

<IORedis.Cluster>.pipeline([
  ['type', <Buffer for \xac\xed\x00\x05t\x0a4100000252>],
  ['memory usage', <Buffer for \xac\xed\x00\x05t\x0a4100000252>, 'samples', '0'],
  ['memory usage', <Buffer for \xac\xed\x00\x05t\x0a4100000255>, 'samples', '0'],
]).exec()

will not

@luin
Copy link
Collaborator

luin commented Jun 12, 2022

Hey @arthosofteq 👋,

These 2 keys should be allocated to the same shard.

The 2 keys belong to two different slots, although the two slots may be severed by the same shard at the moment. Ioredis doesn't know that before it reaches to server, so it throws early without sending them to the server to ensure the semantic of a pipeline.

I think it's risky to assume that two slots always belong to the same shard as it could be false after a failover or cluster re-setup. Generally, if you want to use pipeline in cluster, you need to ensure that they are not only severed by the same shard, but also they belong to the same slot.

Hope that makes sense.

Regarding the second issue, I'm not able to reproduce it as 'memory usage' is not a valid command (I assume you mean ['memory', 'usage', ...] but it still doesn't report the same error). Can you provide a reproducible example so I can test on my side?

@undeadcat
Copy link

undeadcat commented Dec 6, 2022

Stumbled onto this error message.

@luin, I'm curious, what do you mean by 'ensure the semantic of a pipeline'?
Is it a choice to not support multi-slot pipelines or an incomplete feature?

A pipeline is not a transaction, some operations may fail. I have not studied the topic too deeply, but initially seems like it might be reasonable for a Redis client library to provide 'best-effort' (up to a number of redirects) handling of multi-slot pipelines and ultimately (if still rebalancing), report that some operations failed.

The standard CLI client handles multi-slot pipelines:

% echo "SET foo 1\r\nSET foo2 1\r\nSET foo3 1\r\nSET foo4 1" | redis-cli -h <cluster-address> -p 6379 -c
-> Redirected to slot [12182] located at 172.28.224.50:6379
OK
-> Redirected to slot [1044] located at 172.28.199.77:6379
OK
OK
-> Redirected to slot [9426] located at 172.28.210.21:6379
OK
% echo "GET foo\r\nGET foo2\r\nGET foo3\r\nGET foo4" | redis-cli -h <cluster-address> -p 6379 -c        
-> Redirected to slot [12182] located at 172.28.224.50:6379
"1"
-> Redirected to slot [1044] located at 172.28.199.77:6379
"1"
"1"
-> Redirected to slot [9426] located at 172.28.210.21:6379
"1"

Jedis seems to handle multi-slot pipelines as well:
https://github.com/redis/jedis
https://gist.github.com/undeadcat/b1b22acc324a1e61a9b0ac96daeca863

@LRagji
Copy link

LRagji commented Mar 22, 2023

Same issue, @luin I have keys which are belonging to different slots/nodes and i am expecting it to work just as @undeadcat cli request.. since the whole intention of pipeline is to send all commands together to cluster, if there are redirects they can be handled by the ioredis for best possible resolution.. else you are forcing consumers in this scenario to co-locate keys on single node which defeats the purpose of cluster....
Another workaround would be to provide a resolver function which can distribute the commands into different sets according to slots and then let consumer call pipeline for each individual set...

@enchorb
Copy link

enchorb commented Oct 13, 2024

Any updates here? enableAutoPipelining only works if scaleReads is set to master

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

5 participants