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
[NEW] Functions should be able declare additional keys #10951
Comments
It also bothered me at some point, but doing that could violate cluster routing since the client won't see these keys. @MeirShpilraien @yossigo WDYT? |
@oranagra One easy (but maybe not very memory efficient) way to do that without any additional functions is to use |
@madolson I agree with the problem you raise and I believe its even deeper then what you just mentioned. I believe that there are use-cases that today are not even solvable on a cluster and not just because the function should abstract the keys names. For example, consider the use-case where we have hashes representing persons and for each person we have a field with the amount of kids the person have. We want to maintain a counter that will give us the total number of kids. For a single shard, it is easy to implement, you create a function to change the kids field and maintain an outside counter that keeps the total number of kids. For a cluster, I do not see a way to do it, what will be the name of the counter key? How do you maintain it on each shard? How to handle resharding? I believe that such a use-case is a valid use-case for functions and we do not have a solution for that on cluster (unless there is some easy solution that I missed?). |
I also like this solution - "allow the function to easily generate other key names that fit the same hash slot of the declared input key" However I would like to ask if using the BaseKey is the correct method? IMO allow adding internal keys in the function metadata is structured and we can think of supporting some identifier like "$slot" in order to make sure the key will be mapped to the specific slot the function operates in. |
Note that the function may want to update one counter for many different keys it works on, so if we go the curly brackets way, it should be
With functions philosophy, users don't delete keys, they invoke functions to delete logical objects, so that shouldn't be a problem. |
This is strictly an anti-pattern for Redis cluster, and we need to think deep and hard if we really want to work to resolve it. Right now Redis only provides linearizable (for it's definition of durability) on a slot, and you are suggesting we should have some form of linearizable across slots (or some other weaker guarantee). This requires cross shard coordination in the form of distributed transactions or conflict resolvable data types. This is an interesting problem, but I think it's distinct from the problem being discussed here. |
I agree it's a slightly different topic than (sorry for hogging your issue). Regarding the issue you raised, and the solution you suggested, I think it's problematic to run an auxiliary function before starting the actual function. |
Redis Cluster puts the responsibility on the client to store each key on the correct shard. Redis could have been responsible for forwarding/proxying the commands to the correct node, but it isn't. It has been suggested though... If we want to compare the code in a function to the logic in a client, we can allow functions to make calls to any node in the cluster, e.g. the |
@zuiderkwast It'll be a lot more complex than just allowing a client to forward a command to another node, since we still have cross shard linearizability issues. Let's say you have a script that atomically updates two bank account numbers. If those scripts are executed on two separate nodes, they still need to appear as if they happened in some order, we can't have the commands between the two transactions intermingled. |
@madolson Two bank accounts on different shards: We don't support atomic operations across slots, whether or not functions are used. Functions can only do things that regular clients can do. Are we trying to give them more power than that? |
going though this again i'd like to summarize and suggest what i think should be done. these names should support two forms of macros:
i.e. the This way we support both the use case were someone wanna maintain a specific auxiliary key for each of the main keys. we'll also need to add some APIs that will let the function code expand the I wanna argue that users can already probably achieve some of that (the specific auxiliary key for each of the main keys) by manually naming these keys correctly with curly braces, and the main disadvantage they have compared to what we'll offer is that they'll need to manually use |
@zuiderkwast I think that is what people use functions for, they expect it to be atomic. @oranagra I agree with most of the proposal, but I don't think we should solve the $slot problem the way that was identified, by generating a compatible key per slot. I think long term we need some "slot" independent data, and we can provide access to that slot data. I've wanted to modify the hash tag semantic in the past, perhaps with a v2, that allows specifying the slot on the client side. |
@madolson by slot independent data you mean some per-slot data storage (i.e. the function will be able to store some info in slot 0 and some info in slot 1)? or do you mean to save some global (out of keyspace) data in redis (which we'll need to figure out how to reshard)? |
I want to support something like |
I also independently want the |
ok, i can live with that.. it does make things a little bit more complex (more steps), and adds backwards compatibility issues, but arguably makes things clearer.
then they can do something like
i still think that the declarative key binding could be like:
|
discussed in core-team meeting. |
The problem/use-case that the feature addresses
One pattern that functions are suppose to allow is to "abstract" away the underlying details of a command implementation. One such way that might be accomplished is to access multiple keys to perform an operation. However, Functions require all keys to be declared, which might change.
Description of the feature
A function should be able to declare a function that selects which keys will be touched, similar to how functions registration works.
Alternatives you've considered
Require end uses to specify all the keys. This couples the underlying implementation with the keys accessed.
The text was updated successfully, but these errors were encountered: