Skip to content

Conversation

@xBis7
Copy link
Contributor

@xBis7 xBis7 commented Jan 3, 2023

What changes were proposed in this pull request?

Ratis roles are created as part of the OMMXBean class which makes them available only for /jmx. This information should be available for both /jmx and /prom endpoints of the OM.

In order to make the info available for the /prom endpoint, this patch adds a new metrics class that holds info about the component registering it, showing to the user if the current OM is a leader or a follower. The info is presented with a gauge(1 for leader, 0 for follower) so that it can be charted.

There will be a follow up PR, with a similar approach for the SCM.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-7721

How was this patch tested?

A new test was added under hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManagerHAWithData.java.

This patch was also tested manually in docker clusters for both HA and non-HA like so

  • in /hadoop-ozone/dist/target/ozone-1.4.0-SNAPSHOT/compose/ozone

    ❯ docker-compose up --scale datanode=3 -d
      
    0.0.0.0:9874/jmx
    {
      "name" : "Hadoop:service=OzoneManager,name=OMHAMetrics",
      "modelerType" : "OMHAMetrics",
      "tag.NodeId" : "om1",
      "tag.Hostname" : "7eb57edf7920",
      "OzoneManagerHALeaderState" : 1
    },
      
    0.0.0.0:9874/prom
    # TYPE omha_metrics_ozone_manager_ha_leader_state gauge
    omha_metrics_ozone_manager_ha_leader_state{nodeid="om1",hostname="7eb57edf7920"} 1
    
  • in /hadoop-ozone/dist/target/ozone-1.4.0-SNAPSHOT/compose/ozone-ha

    ❯ docker-compose up --scale datanode=3 -d
    
    0.0.0.0:9874/jmx
    {
      "name" : "Hadoop:service=OzoneManager,name=OMHAMetrics",
      "modelerType" : "OMHAMetrics",
      "tag.NodeId" : "om1",
      "tag.Hostname" : "om1",
      "OzoneManagerHALeaderState" : 0
    },
    
    0.0.0.0:9874/prom
    # TYPE omha_metrics_ozone_manager_ha_leader_state gauge
    omha_metrics_ozone_manager_ha_leader_state{nodeid="om1",hostname="om1"} 0
    

@xBis7 xBis7 changed the title Make OM Ratis roles available in /prom endpoint HDDS-7721. Make OM Ratis roles available in /prom endpoint Jan 3, 2023
@kerneltime
Copy link
Contributor

Do you want to include docker-compose.yaml and docker-config changes? I think being able to read the metrics would be useful in general.

@xBis7
Copy link
Contributor Author

xBis7 commented Jan 3, 2023

@kerneltime Thanks for the suggestion, I included the config for OM and SCM.

@kerneltime
Copy link
Contributor

Question: Why the need to format the metric as

{ HostName: om1 | Node-Id: om1 | Ratis-Port : 9872 | Role: FOLLOWER}  { HostName: om2 | Node-Id: om2 | Ratis-Port : 9872 | Role: LEADER}  { HostName: om3 | Node-Id: om3 | Ratis-Port : 9872 | Role: FOLLOWER} 

Would it make sense to break it up into individual values so it can be charted? It could be
leader: true
follower: false
ratis-port:
and so on...
I think Prometheus metrics have a specific scheme to it.

@xBis7
Copy link
Contributor Author

xBis7 commented Jan 3, 2023

@kerneltime Thanks for looking into this.

Why the need to format the metric as

I wanted to avoid duplicating code, so I got the same string we are using in OMMXBean.getRatisRoles() from OzoneManager.getRatisRoles().

We can either split it up in new tags or have a Map and then use that for the tag.

Would it make sense to break it up into individual values so it can be charted?

We want to track the leader and if we are presenting info only for the current node, then we would have to go over all of them just to find the leader. If we want to simplify it, we could have a tag with only the info for the leader and skip all the followers.

Do you have any suggestions about the format? This fix is based on this discussion and #3791.

@xBis7
Copy link
Contributor Author

xBis7 commented Jan 13, 2023

@kerneltime I updated the patch with the changes you requested. Now OMHAMetrics hold info only for the component registering them. All the info is added as tags instead of a concatenated string and also there is a gauge(1 for leader, 0 for follower) so that the metrics can be charted like you suggested. Can you take another look?

@xBis7
Copy link
Contributor Author

xBis7 commented Jan 20, 2023

@neils-dev Thanks for the review! I have addressed your comments.

@neils-dev
Copy link
Contributor

Thanks @xBis7. I took a look at the prom omha_metrics_ozone_manager_ha_leader_state metric when it is tracked and charted on om leadership transition. I rendered the prometheus endpoint with the prometheus web app and performed failover with 2 om nodes. On failover currently with the extra tag for "state" we get extra traces, in this case 4, one for each state change and gauge change, see - https://github.com/neils-dev/play/blob/main/images/failover_extra_traces.png.

It would be much cleaner to keep the tags to a min and just use the gauge to reflect the leader and changes to the leader. This can be seen when failover is rendered on prometheus with simplified tags, two traces this time, see - https://github.com/neils-dev/play/blob/main/images/failovers_just_gauge.png. Failover is the criss-cross when rendered.

@xBis7
Copy link
Contributor Author

xBis7 commented Jan 26, 2023

@neils-dev I've tested it locally and I can see what you are referring to. I will remove state tag from OMHAMetrics. Thanks!

@DaveTeng0
Copy link
Contributor

Hey @xBis7 ! Seemed like some test was failing, please help take a look! Thanks~

@xBis7
Copy link
Contributor Author

xBis7 commented Jan 30, 2023

Hey @DaveTeng0, the failure seems unrelated. Check here, I had a green build on the workflow of my fork. A lot of tests are flaky but I don't have write privileges to rerun the failed ones on the PR workflow.

Copy link
Contributor

@adoroszlai adoroszlai left a comment

Choose a reason for hiding this comment

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

Thanks @xBis7 for working on this.

@xBis7
Copy link
Contributor Author

xBis7 commented Feb 1, 2023

@adoroszlai I've updated the patch, with the changes you requested. Can you please take another look?

Copy link
Contributor

@adoroszlai adoroszlai left a comment

Choose a reason for hiding this comment

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

Thanks @xBis7 for updating the patch, LGTM.

If I understand correctly, @neils-dev's comment was also addressed previously in e836659.

@xBis7
Copy link
Contributor Author

xBis7 commented Feb 1, 2023

If I understand correctly, @neils-dev's comment was also addressed previously in e836659.

@adoroszlai Yes, it has been addressed.

@neils-dev
Copy link
Contributor

Thanks @xBis7 , @adoroszlai, I'm going to take another look.

@xBis7
Copy link
Contributor Author

xBis7 commented Feb 2, 2023

@neils-dev I've addressed your comments. Can you please take another look?

@DaveTeng0
Copy link
Contributor

Once @neils-dev takes a final look, this PR would be ready to be merged!

@xBis7
Copy link
Contributor Author

xBis7 commented Feb 16, 2023

@neils-dev Double checking the leaderId seems unecessary. If for some reason there is no leader or there is an error and leaderId is empty, then the state is set to 0 pointing that the current node is a follower, which will be true.

I hadn't thought about the case where ratis is disabled but I looked into it and tested it. Since, in that scenario there are no leaders or followers, updatePeerList() never gets called and therefore OMHAMetrics are not registered. Checking if ratis is enabled is redundant because if it isn't and the method gets called we will get a NPE at the very first line when calling omRatisServer. I'll remove the check.

@xBis7
Copy link
Contributor Author

xBis7 commented Feb 16, 2023

@neils-dev I've added some unit tests, so that we can check the case where we provide an empty leaderId.

@adoroszlai adoroszlai requested a review from neils-dev February 17, 2023 20:48
Copy link
Contributor

@neils-dev neils-dev left a comment

Choose a reason for hiding this comment

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

Left a few comments. Thanks. Should remove the unintended addition file TestOzoneFsSnapshot.java that came in your latest commit.

@neils-dev
Copy link
Contributor

Checking if ratis is enabled is redundant because if it isn't and the method gets called we will get a NPE at the very first line when calling omRatisServer. I'll remove the check.

Thanks for updating that.

@xBis7
Copy link
Contributor Author

xBis7 commented Feb 21, 2023

@neils-dev Thanks for the reviews, I've updated the patch. Let me know how it looks.

@xBis7
Copy link
Contributor Author

xBis7 commented Feb 21, 2023

@neils-dev I've updated the patch to address the latest comment.

Copy link
Contributor

@neils-dev neils-dev left a comment

Choose a reason for hiding this comment

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

Thanks @xBis7 . Looks good. Look to merge pending a green CI.

@adoroszlai adoroszlai merged commit 06e7b1b into apache:master Feb 22, 2023
@adoroszlai
Copy link
Contributor

Thanks @xBis7 for the patch, @kerneltime, @neils-dev for the review.

Comment on lines +1900 to +1913
RaftPeer leader = null;
try {
leader = omRatisServer.getLeader();
} catch (IOException ex) {
LOG.error("IOException while getting the " +
"Ratis server leader.", ex);
}
if (Objects.nonNull(leader)) {
String leaderId = leader.getId().toString();

// If leaderId is empty, then leader is undefined
// and current OM is neither leader nor follower.
// OMHAMetrics shouldn't be registered in that case.
if (!Strings.isNullOrEmpty(leaderId)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@neils-dev @xBis7

I had to update this part of the code after merging the PR due to a conflicting change that had been just merged (HDDS-6743, getLeader() no longer throws IOException).

Upon closer inspection, I think these if-else blocks have a problem. Please correct me if I'm wrong, but if leader is undefined then leader will be null, so the unregistration will not happen. (This seems to have been the case even before HDDS-6743.) If we have any leader information, its id cannot be null.

I think it should be:

if (Objects.nonNull(leader)) {
  // init
} else {
  // unregister
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@adoroszlai You are right. This was missed because the code was

String leaderId = "";
try{
  leader = 
} catch() {

}

if (Objects.nonNull(leader)) {

}

// leaderId could be deliberately left empty down here due to failure to get the leader
// after refactoring `String leaderId = "";` was removed.

If we have any leader information, its id cannot be null.

I didn't know that.

How can we handle this now since the code has been merged?

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @xBis7 for checking.

If we have any leader information, its id cannot be null.

I didn't know that.

https://github.com/apache/ratis/blob/27f5a59cc697ce51f1c5ab6d7b6c63eb58390b79/ratis-common/src/main/java/org/apache/ratis/protocol/RaftPeer.java#L175

How can we handle this now since the code has been merged?

HDDS-8009

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@adoroszlai Thanks! I'll create a patch shortly for HDDS-8009.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @adoroszlai for merging and uncovering this change. With getLeader() no longer throwing an exception, we can cleanup the null check and handling of that condition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants