【问题标题】:How does web UI calculate Storage Memory (in Executors tab)?Web UI 如何计算存储内存(在 Executors 选项卡中)?
【发布时间】:2017-10-03 16:57:04
【问题描述】:

我试图了解 Spark 2.1.0 如何在节点上分配内存。

假设我正在启动一个本地 PySpark REPL,并为其分配 2GB 内存:

$ pyspark --conf spark.driver.memory=2g

Spark UI 告诉我们有 956.6 MB 分配给存储内存:

我不明白如何得到那个数字,这是我的思考过程:

  1. 驱动程序堆大小设置为2048 MB
  2. 根据docs(2048 MB - 300 MB) * 0.6 = 1048.8 MB 用于执行和存储区域(统一),
  3. 另外统一区域内的1048.8 MB * 0.5 = 524.4 MB应保留为免疫存储区域

那么,Spark 中 956.6 MB 的值实际上是如何计算的?

【问题讨论】:

    标签: apache-spark pyspark


    【解决方案1】:

    您似乎正在使用local 模式(一个驱动程序也作为唯一的执行程序),但它也应该适用于其他集群模式。

    启用BlockManagerMasterEndpoint 的INFO 日志记录级别,以了解Spark 看到您在命令行中设置的属性(如spark.driver.memory)有多少内存。

    log4j.logger.org.apache.spark.storage.BlockManagerMasterEndpoint=INFO
    

    当您启动spark-shell --conf spark.driver.memory=2g 时,您将看到以下内容:

    $ ./bin/spark-shell --conf spark.driver.memory=2g
    ...
    17/05/07 15:20:50 INFO BlockManagerMasterEndpoint: Registering block manager 192.168.1.8:57177 with 912.3 MB RAM, BlockManagerId(driver, 192.168.1.8, 57177, None)
    

    如您所见,可用内存为 912.3,计算如下(参见 UnifiedMemoryManager.getMaxMemory):

    // local mode with --conf spark.driver.memory=2g
    scala> sc.getConf.getSizeAsBytes("spark.driver.memory")
    res0: Long = 2147483648
    
    scala> val systemMemory = Runtime.getRuntime.maxMemory
    
    // fixed amount of memory for non-storage, non-execution purposes
    val reservedMemory = 300 * 1024 * 1024
    
    // minimum system memory required
    val minSystemMemory = (reservedMemory * 1.5).ceil.toLong
    
    val usableMemory = systemMemory - reservedMemory
    
    val memoryFraction = sc.getConf.getDouble("spark.memory.fraction", 0.6)
    scala> val maxMemory = (usableMemory * memoryFraction).toLong
    maxMemory: Long = 956615884
    
    import org.apache.spark.network.util.JavaUtils
    scala> JavaUtils.byteStringAsMb(maxMemory + "b")
    res1: Long = 912
    

    让我们回顾一下 Web UI 是如何计算内存的(这与上面的不同,应该只是显示值!)。这是令人惊讶的部分。

    Web UI 中存储内存的显示方式由 utils.js 中的自定义 JavaScript 函数 formatBytes 控制,该函数(映射到 Scala)如下所示:

    def formatBytes(bytes: Double) = {
      val k = 1000
      val i = math.floor(math.log(bytes) / math.log(k))
      val maxMemoryWebUI = bytes / math.pow(k, i)
      f"$maxMemoryWebUI%1.1f"
    }
    scala> println(formatBytes(maxMemory))
    956.6
    

    956.6!这正是 Web UI 显示的内容,并且与 Spark 的 UnifiedMemoryManager 认为可用内存完全不同。 相当令人惊讶,不是吗?


    我认为这是一个错误并填写为SPARK-20691

    【讨论】:

    • 感谢您提供非常详细和详尽的回答。引起误解的片段是 reservedMemory * 1.5,应该记录在某处(文档声明保留了 300 MB,而实际上它是 450 MB)。
    • 感谢您的回答。只是对您的评论:reservedMemory 是 300MB,但它是 Spark 应用程序所需的最小内存,不是吗?
    • @JacekLaskowski 所以如果我想减少 storagememory 我应该把什么确切的参数放在配置中?
    • @jk1 我想应该是--executor-memory,因为那里有一个 StorageManager。你能否问一个单独的问题,这样它就不会落空?谢谢。
    • @roamer 这一切都可以使用。
    猜你喜欢
    • 1970-01-01
    • 2011-02-07
    • 2021-09-25
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 2017-11-11
    • 2012-04-16
    • 1970-01-01
    相关资源
    最近更新 更多