-
Notifications
You must be signed in to change notification settings - Fork 14.4k
KAFKA-1826 [1/N]: Introducing GroupStore #17981
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
base: trunk
Are you sure you want to change the base?
Conversation
Hi @aliehsaeedii. Thanks for the PR. A few high-level comments for now:
cc @dajac |
import static org.apache.kafka.coordinator.group.Group.GroupType.CONSUMER; | ||
import static org.apache.kafka.coordinator.group.Group.GroupType.SHARE; | ||
|
||
public class GroupStore { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GroupStore
could be renamed to GroupMetadataStore
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I like the proposal.
Thanks @aliehsaeedii! I will definitely review it next week. Would it be possible to describe the high level design that you're aiming for? I would like to ensure that we are on the same page. It will also ease the reviews. |
Thanks, @dajac. I updated the PR description with a brief description of the high level design. This closed PR, contains all the changes (without utests), but we decided to create a separate PR for each phase. |
Thanks, @lucasbru. To remove the current |
Okay, I see. The point of replacing the functionality immediately would be that it is easier to track that all unit tests are being ported from the old to the new structure, since the unit tests are the only thing that stop us from breaking things here. But if you think it's too complicated, from my side it's okay to do it this way. Please take extra care retainingthe test coverage. I will give this a more detailed look tomorrow, but on a high level the approach looks good to me. |
Thanks, @lucasbru. I see your point. I can remove the unit tests that are covered by the newly introduced classes from the |
@@ -0,0 +1,307 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aliehsaeedii Thanks for working on this! I have a few high level comments regarding the GroupStore
. I want us to agree on what we put and don't put in the store.
- In my mind, the store should hold the state of all the groups. I think that we all agree on this.
- As it holds the state of all groups, I am also tempted by moving all the replay methods to the store as they are the ones updating the state. Is it something that you have considered?
- I think that the store should only have methods to query the state (e.g. get a group, list all groups, etc.). All the other methods (e.g.
validateDeleteGroup
,maybeDeleteGroup
,createGroupTombstoneRecords
, etc should not be here in my opinion. - The API specific methods should resides outside of the store. e.g.
listGroups
is directly linked to the implementation of the admin API, hence it may be better to have it in one of the other managers or in a manager responsible for the admin APIs. - The store does not need a reference to a MetadataImage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @dajac, for the conceptual review.
I am also tempted by moving all the replay methods to the store
Agree! That makes sense and makes the utests cleaner.
other methods (e.g. validateDeleteGroup, maybeDeleteGroup, createGroupTombstoneRecords, etc should not be here in my opinion.
Your opinion is valid David. Since other manager classes have a reference to GroupStore
, I assumed such methods could be inside this class to be accessible by all other manager classes. But I think, later we can have a helper class and these methods could be defined there.
The API specific methods should resides outside of the store. e.g. listGroups
listGroups
: REMOVED
The store does not need a reference to a MetadataImage.
I removed the MetadataImage
and the associated methods from this class. Do you mean each manager class should have its own MetadataImage
instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments on the production code.
For the unit tests, I'm not sure, I like that we copy a lot of replay methods in the test code that are unrelated to the production code of the class. I think we have two options for solving this
- We essentially make the group store completely independent of the group types. That would mean, in the unit tests we create a mock group type to test the functionality of the class independently of the group types.
- We make the
replay
methods parts of the production code ofGroupStore
.
/** | ||
* The snapshot registry. | ||
*/ | ||
private SnapshotRegistry snapshotRegistry; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be final
import static org.apache.kafka.coordinator.group.Group.GroupType.CONSUMER; | ||
import static org.apache.kafka.coordinator.group.Group.GroupType.SHARE; | ||
|
||
public class GroupStore { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I like the proposal.
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/GroupStore.java
Outdated
Show resolved
Hide resolved
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/GroupStore.java
Outdated
Show resolved
Hide resolved
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/GroupStore.java
Outdated
Show resolved
Hide resolved
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/GroupStore.java
Outdated
Show resolved
Hide resolved
This PR is being marked as stale since it has not had any activity in 90 days. If you If you are having difficulty finding a reviewer, please reach out on the [mailing list](https://kafka.apache.org/contact). If this PR is no longer valid or desired, please feel free to close it. If no activity occurs in the next 30 days, it will be automatically closed. |
This PR has been closed since it has not had any activity in 120 days. If you feel like this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the PR. left some comments
import static org.apache.kafka.coordinator.group.classic.ClassicGroupState.EMPTY; | ||
import static org.apache.kafka.coordinator.group.classic.ClassicGroupState.STABLE; | ||
|
||
public class GroupMetadataStore { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be great to add the high level idea of the group metadata store here
*/ | ||
private final TimelineHashMap<String, TimelineHashSet<String>> groupsByTopics; | ||
|
||
public GroupMetadataStore(SnapshotRegistry snapshotRegistry, GroupCoordinatorMetricsShard metrics, Time time) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GMM uses a builder pattern. should we use it here as well?
} | ||
|
||
/** | ||
* Returns the snapshot registry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this is redundant
* | ||
* @return The snapshot registry. | ||
*/ | ||
public SnapshotRegistry snapshotRegistry() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what will be the use case for this method?
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(booleans = {true, false}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps we pass in the rebalance times here instead?
throw new GroupIdNotFoundException(String.format("Group %s is not a consumer group", groupId)); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: newline
This PR and the future following ones aim to refactor the big
GroupMetadataManager
class and split it into multiple classes. This PR specifically introduces theGroupStore
class, which contains the metadata for all groups.The high level design: mainly introducing the following classes, each containing specific properties and methods:
GroupStore
: metadata for all groups.ShareGroupMetadataManager
: has a reference toGroupStore
+ properties and methods related to ShareGroup metadata management.ConsumerGroupMetadataManager
: has a reference toGroupStore
+ properties and methods related to ConsumerGroup metadata management.ClassicGroupMetadataManager
: has a reference toGroupStore
+ properties and methods related to ClassicGroup metadata management.StreamsGroupMetadataManager
: has a reference toGroupStore
+ properties and methods related to StreamsGroup metadata management.Since
ConsumerGroupMetadataManager
andClassicGroupMetadataManager
share many methods, a helper class may be defined to avoid method duplication.