Skip to content
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

[SPARK-28414][WEBUI] UI updates to show resource info in Standalone #25409

Closed
wants to merge 14 commits into from

Conversation

Ngone51
Copy link
Member

@Ngone51 Ngone51 commented Aug 11, 2019

What changes were proposed in this pull request?

Since SPARK-27371 has supported GPU-aware resource scheduling in Standalone, this PR adds resources info in Standalone UI.

How was this patch tested?

Updated JsonProtocolSuite and tested manually.

Master page:

masterpage

Worker page

workerpage

Application page

applicationpage

.map { case (rName, rInfoArr) =>
rName -> rInfoArr.map(_._2).reduce(_ + _)
}
if (totalInfo.isEmpty) "None" else formatResourcesUsed(totalInfo, usedInfo)
Copy link
Member

@dongjoon-hyun dongjoon-hyun Aug 11, 2019

Choose a reason for hiding this comment

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

Could you use "" instead of "None"?

Copy link
Member Author

Choose a reason for hiding this comment

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

updated, thanks.

@SparkQA
Copy link

SparkQA commented Aug 11, 2019

Test build #108932 has finished for PR 25409 at commit d039676.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Aug 12, 2019

Test build #108944 has finished for PR 25409 at commit cdc171a.

  • This patch fails to build.
  • This patch merges cleanly.
  • This patch adds no public classes.

@@ -242,6 +243,22 @@ private[deploy] class Worker(
System.exit(1)
}
}
resources.foreach { case (rName, _) =>
Copy link
Member

Choose a reason for hiding this comment

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

nit:

resources.keys.foreach { rName =>
  resourcesUsed(rName) = new ResourceInformation(rName, Array.empty[String])
}

Copy link
Member Author

Choose a reason for hiding this comment

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

updated, thanks.

@SparkQA
Copy link

SparkQA commented Aug 12, 2019

Test build #108945 has finished for PR 25409 at commit fbb4382.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@Ngone51
Copy link
Member Author

Ngone51 commented Aug 12, 2019

also cc @tgravescs @jiangxb1987 @mengxr

@@ -39,6 +39,18 @@ class ResourceInformation(
val name: String,
val addresses: Array[String]) extends Serializable {

def + (other: ResourceInformation): ResourceInformation = {
Copy link
Member Author

Choose a reason for hiding this comment

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

Note this may generates much more intermediate ResourceInformation objects. I do this because ResourceInformation yet is immutable. It may be better if we could make it be mutable in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

like I mention above we don't want to make this mutable since end user facing and I think you should use different class to track it there to be more efficient

@gatorsmile
Copy link
Member

Also cc @gengliangwang

@SparkQA
Copy link

SparkQA commented Aug 12, 2019

Test build #108979 has finished for PR 25409 at commit e0fc69a.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@tgravescs
Copy link
Contributor

Just looking at the screen shots, It would be nice for the worker detailed page to have the free and used resources like the top level page.


// used for UI
def formatResourceRequirements(requirements: Seq[ResourceRequirement]): String = {
requirements.map { req => s"${req.amount} ${req.resourceName}"}.mkString(", ")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit just use () and cleanup spacing.

Copy link
Member Author

Choose a reason for hiding this comment

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

like (5gpu, 10fpga) ?

Copy link
Contributor

Choose a reason for hiding this comment

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

sorry I wasn't clear I meant replace {} in the map with ().
requirements.map(req => ..) since it all fits on one line

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I see.

@@ -185,6 +185,7 @@ private[deploy] class Worker(

var coresUsed = 0
var memoryUsed = 0
val resourcesUsed = new HashMap[String, ResourceInformation]()
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah I don't think you should use REsourceInformation here to track used since like you said its immutable. We don't want to change that to be mutable because its user facing API. Something more like WorkerResourceInfo would make sense

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, thank you @tgravescs for reminding this. I'll update it as you suggested.

@@ -39,6 +39,18 @@ class ResourceInformation(
val name: String,
val addresses: Array[String]) extends Serializable {

def + (other: ResourceInformation): ResourceInformation = {
Copy link
Contributor

Choose a reason for hiding this comment

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

like I mention above we don't want to make this mutable since end user facing and I think you should use different class to track it there to be more efficient

@Ngone51
Copy link
Member Author

Ngone51 commented Aug 17, 2019

It would be nice for the worker detailed page to have the free and used resources like the top level page.

Sure, will add it.

@SparkQA
Copy link

SparkQA commented Aug 21, 2019

Test build #109486 has finished for PR 25409 at commit ce89784.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

}
}

private def updateResourcesUsed(deltaInfo: Map[String, ResourceInformation], add: Boolean)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd say just create 2 functions for this, when looking at how this gets called its not nearly as clear as just saying addResourcesUsed, removeResourceUsed, user has to figure out what other parameter is.
also shrinks the code as you simply need 2 lines:
deltaInfo.foreach { case (rName, rInfo) =>
resourcesUsed(rName) += resourcesUsed(rName) + rInfo
}

Copy link
Member Author

Choose a reason for hiding this comment

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

good point!

val clazz = ct.runtimeClass
val rf = {
clazz match {
case _ if clazz.equals(classOf[MutableResourceInfo]) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

I get why you are doing this, but this just seems more complex that what should be needed. Usually when you see different return types they have some same base class or trait so you don't actually have to look at the class, although in this case you don't have any input to determine type by either. It ends up being a runtime check instead of compile time check. So I think you should just make 2 functions - 1 to get immutable, 1 to get mutable.
alternatively just get it immutable all the time and change the one place its used as mutable to deal with it

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, and I chosen the alternative one, which seems more simply in WorkerInfo. While, the other one actually needs 4 functions(combinations of [immutable, mutable] * [total, used]), which seems noisy in WorkerInfo from my view.

: Map[String, MutableResourceInfo] = {
immutableResources.map { case (rName, rInfo) =>
val mutableAddress = new mutable.HashSet[String]()
rInfo.addresses.foreach(mutableAddress.add)
Copy link
Contributor

Choose a reason for hiding this comment

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

this can just be: mutableAddress ++= rInfo.addresses

@SparkQA
Copy link

SparkQA commented Aug 26, 2019

Test build #109740 has finished for PR 25409 at commit 1e64a33.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Aug 26, 2019

Test build #109746 has finished for PR 25409 at commit 77cd726.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@tgravescs
Copy link
Contributor

test this please

@SparkQA
Copy link

SparkQA commented Aug 26, 2019

Test build #109752 has finished for PR 25409 at commit 77cd726.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

Copy link
Contributor

@tgravescs tgravescs left a comment

Choose a reason for hiding this comment

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

+1. Thanks @Ngone51

@asfgit asfgit closed this in 70f4bbc Aug 27, 2019
@Ngone51
Copy link
Member Author

Ngone51 commented Aug 27, 2019

Thank you all :)

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