-
Notifications
You must be signed in to change notification settings - Fork 93
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
IGNITE-23054 Improve cluster status REST endpoint #4614
base: main
Are you sure you want to change the base?
Conversation
assertOutput("cluster", 2, "Metastore majority lost", cmgNodes(), metastoreNodes()); | ||
|
||
CLUSTER.startNode(0); | ||
Thread.sleep(10000); |
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.
Let's change this to await().untilAsserted()
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.
Removed
@@ -33,6 +33,8 @@ class ItSqlCommandTest extends CliSqlCommandTestBase { | |||
void nonExistingFile() { | |||
execute("sql", "--file", "nonexisting", "--jdbc-url", JDBC_URL); | |||
|
|||
CLUSTER.stopNode(0); |
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.
Why this is needed?
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.
Removed
|
||
/** | ||
* Call to get cluster status. | ||
*/ | ||
@Singleton | ||
public class ClusterStatusCall implements Call<UrlCallInput, ClusterStatus> { | ||
public class ClusterStatusCall implements Call<UrlCallInput, ClusterState> { | ||
private static final int READ_TIMEOUT = 50_000; |
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.
Why this needs to be 50 seconds? As I understand this depends on the timeout settings in the cluster state retrieval, can we at least point to the place where this is configured in the CMGManager?
@@ -64,24 +73,28 @@ public class ClusterState { | |||
@JsonCreator | |||
public ClusterState( | |||
@JsonProperty("cmgNodes") Collection<String> cmgNodes, | |||
@JsonProperty("msNodes") Collection<String> msNodes, | |||
@JsonProperty("msNodes") Collection<String> msNodes, |
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.
@JsonProperty("msNodes") Collection<String> msNodes, | |
@JsonProperty("msNodes") Collection<String> msNodes, |
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.
Done
); | ||
} | ||
|
||
private ClusterStatus mapClusterStatus(org.apache.ignite.internal.cluster.management.ClusterState clusterState) { | ||
Set<String> metaStorageNodes = clusterState.metaStorageNodes(); | ||
long presentedMetaStorageNodes = topologyService.allMembers().stream() |
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.
long presentedMetaStorageNodes = topologyService.allMembers().stream() | |
long presentMetaStorageNodes = topologyService.allMembers().stream() |
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.
Done
.filter(metaStorageNodes::contains) | ||
.count(); | ||
|
||
if (presentedMetaStorageNodes <= metaStorageNodes.size() / 2) { |
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.
if (presentedMetaStorageNodes <= metaStorageNodes.size() / 2) { | |
if (presentMetaStorageNodes <= metaStorageNodes.size() / 2) { |
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.
Done
public class ClusterStatusCall implements Call<UrlCallInput, ClusterState> { | ||
/** | ||
* We need to overlap timeout from raft client. | ||
* We can't determine timeout value because it's configurable for each node |
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.
Maybe we can read the node configuration here and just add a couple of seconds to the configured timeout?
|
||
/** | ||
* Class that represents the cluster status. | ||
*/ | ||
public class ClusterStatus { | ||
public class ClusterState { |
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.
We already have an entity called 'cluster state' in the CMG domain. This one is a different entity and yet it's called identically. Could a distinct name be devised? Something like ClusterRuntimeState, maybe.
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.
This is CLI output DTO object. So, I have added postfix
this.cmgNodes = cmgNodes; | ||
this.metadataStorageNodes = metadataStorageNodes; |
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.
How about making defensive copies? Better safe than sorry, and this class should not have a huge amount of instances
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.
We use builder approach in CLI module
case MS_MAJORITY_LOST: | ||
return fg(Color.RED).mark("Metastore majority lost"); | ||
case HEALTHY: | ||
return fg(Color.GREEN).mark("active"); | ||
case CMG_MAJORITY_LOST: | ||
return fg(Color.RED).mark("CMG majority lost"); |
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.
The ordering is a bit strange: why is HEALTHY
in the middle?
private final ClusterTag clusterTag; | ||
|
||
@Schema(description = "IDs the cluster had before.") | ||
@IgniteToStringInclude | ||
private final @Nullable List<UUID> formerClusterIds; | ||
|
||
@Schema(description = "Cluster status.", | ||
requiredMode = RequiredMode.REQUIRED) | ||
private final ClusterStatus clusterStatus; |
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 seems that entities from different domains are mixed here. This ClusterState
class represents the CMG cluster state that is the state stored in the CMG related to the cluster itself. But ClusterStatus
is some volatile thing, it might change during runtime however it wants, even if the CMG cluster state does not change.
I believe we should not mix them together. Could a distinct API endpoint (and CLI command) be added to access this volatile information?
|
||
/** | ||
* The metastore group has lost its majority. Almost all of the cluster functions are inoperative. | ||
* To restore their operation, it is necessary to return the majority to the metastore group. |
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.
* To restore their operation, it is necessary to return the majority to the metastore group. | |
* To restore their operation, it is necessary to restore the majority to the metastore group. |
MS_MAJORITY_LOST, | ||
|
||
/** | ||
* The cluster management group has lost its majority. The cluster is completely inoperative until the majority is returned. |
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.
* The cluster management group has lost its majority. The cluster is completely inoperative until the majority is returned. | |
* The cluster management group has lost its majority. The cluster is completely inoperative until the majority is restored. |
.count(); | ||
|
||
if (presentMetaStorageNodes <= metaStorageNodes.size() / 2) { | ||
return ClusterStatus.MS_MAJORITY_LOST; |
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.
The fact that we have enough nodes in the physical topology does not necessarily imply we have an MG majority. For instance, something on levels higher than the network might prevent a leader to be elected. The most accurate way would be to try executing a read command against the MS group (like reading its current revision) and handle a timeout.
# Conflicts: # modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/impl/MetaStorageManagerImpl.java # modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/impl/MetaStorageService.java
https://issues.apache.org/jira/browse/IGNITE-23054
Cluster status REST and CLI methods are improved: