Skip to content

Proposal for ring multikey #4832

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

Merged

Conversation

danielblando
Copy link
Contributor

Signed-off-by: Daniel Deluiggi [email protected]

What this PR does:
Add new proposal for ring multikey

Which issue(s) this PR fixes:

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

@danielblando danielblando marked this pull request as ready for review August 19, 2022 01:42
@danielblando danielblando force-pushed the proposal-ring-multikey branch 2 times, most recently from 1f79ffa to 4f13780 Compare August 19, 2022 01:45
Copy link
Member

@friedrichg friedrichg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks nice as an experiment to solve the hot key problem.
There is a minor format issue

Signed-off-by: Daniel Deluiggi <[email protected]>
@danielblando danielblando force-pushed the proposal-ring-multikey branch from 4f13780 to ddfec3d Compare August 19, 2022 16:32
@danielblando
Copy link
Contributor Author

Thanks @friedrichg for taking the time. I got some ideas from how memberlist works mixing the code with ring using the Mergeable interface.

Agree with you about the experiment. I actually did a second POC changing the ring to support multikey instead of putting the logic mostly on the KV. The idea was adding a new Codec to the ring which would run using multikey. The problem encountered was that we dont have a proper migration path from singlekey to multikey on that approach. We would need to create a multi interface similar to KV to use both rings for a while.

I preferred proposing a simple approach which does not block Cortex to change the ring in the future.

@alanprot
Copy link
Member

I think this approach make sense in order to prevent a more disruptive change that will require a painful migration.

Comment on lines +99 to +112
The proposal is to create an interface called MultiKey. The interface allows KV store to request the codec to split and
join the values is separated keys.

```
type MultiKey interface {
SplitById() map[string]interface{}

JoinIds(map[string]interface{}) Multikey

GetChildFactory() proto.Message

FindDifference(MultiKey) (Multikey, []string, error)
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered reusing existing code to deal with this? I am thinking about Client.List to get all keys under a prefix, Client.WatchPrefix to watch for updates under given prefix, and Desc.Merge (in ring) for merging multiple keys into final ring.

That way the ring itself would decide to use single key or multiple keys, and would handle merging them together.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a similar approach to what you mentioned. I changed the ring to support multiples keys. My concern was how we migrate online application. We would need to create a similar solution as multi client from kv store on the ring level. I was thinking that the ring would use single or multi keys operations depending on configuration. I think it goes back to my answer to Friedrich suggesting that this would be a first step as it does not change any existent code and we can change the ring as a long term approach.

@alvinlin123 alvinlin123 merged commit b611bf3 into cortexproject:master Sep 8, 2022
decode the data stored in the kv store.

Example of CAS being used with multikey design:
![Sequence diagram](/images/proposals/ring-multikey-sequence.png)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ingesters generate hash tokens locally, how do we resolve the token conflicts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damnever that is a good point that i should have touched more in the proposal. The idea is to have a similar approach to memberlist design.
The memberlist code resolves conflict is in the merge implementation of mergeable interface. The idea is to use a very similar code (maybe the same) of resolveConflict in the WatchKey for a new KV.

We still have the 'observe_period' on ring to verify any conflicts.

f.DurationVar(&cfg.ObservePeriod, prefix+"observe-period", 0*time.Second, "Observe tokens after generating to resolve collisions. Useful when using gossiping ring.")

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

Successfully merging this pull request may close these issues.

6 participants