How hard would it be to group/multiplex a MGET across the cluster slots?
Was not even thinking about it when I started to explore, but normally MGET is not supported on a cluster. But I know at least a few situations where it's now support in clients like Lettuce(?) I think.
Thinking quickly without knowing the innards!! Breaks up a single MGET into an MGET per cluster shard, based on grouping the keys by shard they end up in? Doesn't sound too nasty, but again ideas/thoughts from those who know this better would be good!!
In theory: entirely doable - however, while it works fine in the success case, it massively complicates things in the error scenarios, with things like timeouts, node errors, shard movement, etc - not to mention multi/exec; so: some thought as to how to handle those scenarios would be necessary. Honestly, I wonder whether "any errors at all, just give the hell up" is pragmatic
On Wed, 23 Dec 2020, 06:33 Michael Shiels, [email protected] wrote:
Was not even thinking about it when I started to explore, but normally MGET is not supported on a cluster. But I know at least a few situations where it's now support in clients like Lettuce(?) I think.
Thinking quickly without knowing the innards!! Breaks up a single MGET into an MGET per cluster shard, based on grouping the keys by shard they end up in? Doesn't sound too nasty, but again ideas/thoughts from those who know this better would be good!!
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/StackExchange/StackExchange.Redis/issues/1650, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAEHMDE2YMIMYKLQZFMZ43SWGFKVANCNFSM4VGS4R2A .
Seems pragmatic enough to me :) BTW - I wasn't aware this isn't implemented though at all . currently in IDatabase we have -
///
It doesn't mention anything about not being implemented in case of a cluster. Should I look elsewhere for documentation about this ? I'm afraid I might be using other stuff as well that may not work with a cluster.
Every redis command has the cross-slot limitation on cluster; that's out of my hands - it is a server feature, and you need to read about "hash tags" in the redis cluster documentation to work around it. MGET is unusual and perhaps unique in that there is actually something useful and relevant we can do at the client when multiple slots are involved!
On Wed, 23 Dec 2020, 07:54 pianoman4873, [email protected] wrote:
Seems pragmatic enough to me :) BTW - I wasn't aware this isn't implemented though at all . currently in IDatabase we have -
///
/// Returns the values of all specified keys. For every key that does not hold a string value or does not exist, the special value nil is returned. /// /// The keys of the strings. /// The flags to use for this operation. /// The values of the strings with nil for keys do not exist. /// https://redis.io/commands/mget RedisValue[] StringGet(RedisKey[] keys, CommandFlags flags = CommandFlags.None);
It doesn't mention anything about not being implemented in case of a cluster. Should I look elsewhere for documentation about this ? I'm afraid I might be using other stuff as well that may not work with a cluster.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/StackExchange/StackExchange.Redis/issues/1650#issuecomment-749993755, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAEHMDLLWPVS6T2MU7C7HTSWGO3JANCNFSM4VGS4R2A .
Thanks, I'll keep that in mind :) Funny that https://redis.io/commands/mget doesn't say anything about it either.
Again, it doesn't say it on any individual command because it applies to every command (that accepts multiple keys).
On Wed, 23 Dec 2020, 12:24 pianoman4873, [email protected] wrote:
Thanks, I'll keep that in mind :) Funny that https://redis.io/commands/mget doesn't say anything about it either.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/StackExchange/StackExchange.Redis/issues/1650#issuecomment-750254375, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAEHMHA36ZOTJCIUATPVUTSWHOOLANCNFSM4VGS4R2A .
See "implemented subset" here: https://redis.io/topics/cluster-spec#implemented-subset
On Wed, 23 Dec 2020, 12:36 Marc Gravell, [email protected] wrote:
Again, it doesn't say it on any individual command because it applies to every command (that accepts multiple keys).
On Wed, 23 Dec 2020, 12:24 pianoman4873, [email protected] wrote:
Thanks, I'll keep that in mind :) Funny that https://redis.io/commands/mget doesn't say anything about it either.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/StackExchange/StackExchange.Redis/issues/1650#issuecomment-750254375, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAEHMHA36ZOTJCIUATPVUTSWHOOLANCNFSM4VGS4R2A .
Got you - thanks !
In the case of an MGET I would think 'best attempt' is probably still better than 'nothing' Right? MSET is a bit trickier but also semi-useful, beyond that it gets harder and harder I think. So it looks like I be spelunking the code to see how this all fits together, thanks again for the comments.
Since I am just getting going with this stuff - a few quick questions on if this could be done/simulated/manipulated above StackExchange.Redis - do our own breaking up up of our list - target specific servers based on the shards etc? If that would work we may just try that for now. MGET just seems like something I don't want to lose,.
There is a HashSlot method on the multiplexer that returns the slot for a key. Basically, group by slot, issue requests per group, and recombine the results from all the groups.
On Fri, 1 Jan 2021, 05:49 Michael Shiels, [email protected] wrote:
Since I am just getting going with this stuff - a few quick questions on if this could be done/simulated/manipulated above StackExchange.Redis - do our own breaking up up of our list - target specific servers based on the shards etc? If that would work we may just try that for now. MGET just seems like something I don't want to lose,.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/StackExchange/StackExchange.Redis/issues/1650#issuecomment-753264980, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAEHMBBSXWBHKEQ2BNAGJ3SXVO7RANCNFSM4VGS4R2A .
Oh darn, lost what I had typed, oh well - so yes I had seen that key to hash which then allows you to tell what machiens service that shard. So the question is what interface would still allow mget even in the face of it being a cluster, wher we are breaking things apart ourselves. I have not 100% explored the interface yet but am going as fast as I can in terms of exploration. We are doing a wrapper layer to let us implement 2 tier and other stuff eventually. Using ideas/concepts from CachemAnager/CachingFramework wrappers for StackExchange.Redis. And the nasty part is a COM wrapper for our older code (vs doing a hiredis-cluster port) which seems to work well even under some heavy loads. Hats off it's so far the slickest interface in terms of low connections/high thread support that I found.
The tricky thing is: we have no guarantees at that point in terms of atomicity or point-in-time consistency.
What I am tempted to do is add a new CommandFlags option along the lines of AllowCrossSlot (name TBD) that does this split internally (but grouping by target server, not by slot, so : fewer ops) - and re-combine inside the library. The point being: I wouldn't want to make the existing API do this without making it opt-in. We could make the MGET operation mention this in the exception message for cross-slot scenarios.
Ok makes sense, in our case it's very basic caching so would be fine probably . But ya that could add a new layer of power to the library for sure. I didn't even think it was sanely doable till I ran across 'lettuce' I think that implemented it recently. That got my brain churning. I am assuming from what I have digested so far MGET will still be more efficient (we are only using 100 batches I think) than doing that many Async GETs even, which was what got me thinking it has to be doable in some really slick/sneaky way that would make it usable for more than one thing possibly. Thanks again!! So basically the GetString(keys[]) function would benefit only if requested, which is perfect, if you know it's safe/doable, you can enable it otherwise I assume it would fail on a cluster?
hi all, any update on this?