如何为 Hadoop YARN ResourceManager 和 ApplicationTimeline 启用 GC 日志记录,同时防止日志文件覆盖和限制磁盘 space 使用

How to enable GC logging for Hadoop YARN ResourceManager and ApplicationTimeline, while preventing log file overwrites and capping disk space usage

我们最近决定在多个集群(具体版本不同)上为 Hadoop YARN ResourceManager 和 ApplicationTimeline 服务器启用 GC 日志记录,以帮助调查与 YARN 相关的内存和垃圾收集问题。这样做时,我们想避免两个我们知道可能会发生的问题:

当 Java GC 日志记录开始时,它似乎会替换任何同名文件的内容。这意味着除非您小心,否则您将丢失 GC 日志记录,也许在您更有可能需要它的时候。

如果您将集群 运行 保持足够长的时间,除非进行管理,否则日志文件将填满磁盘。即使 GC 日志记录目前不是很多,我们也希望管理出现导致日志记录率飙升的异常情况的风险。

在启动 YARN 服务器时,您需要设置一些 JVM 参数,这意味着您需要对 yarn-env.sh 进行一些更改。您可以在 YARN_OPTS 中设置参数,但这会产生比仅 ResourceManager 和 ApplicationTimeline 服务器更广泛的影响,因此您可能希望在 YARN_RESOURCEMANAGER_OPTSYARN_TIMELINESERVER_OPTS 中都进行设置。

现在让我们讨论要包含在其中的 JVM 参数。

要启用 GC 日志记录到文件,您需要添加 -verbose:gc -Xloggc:<log-file-location>

您需要特别考虑日志文件名,以防止在服务器重新启动时被覆盖。似乎每次调用都需要一个唯一的名称,因此附加时间戳似乎是最佳选择。您可以包含诸如“date +'%Y%m%d%H%M'”之类的内容来添加时间戳。在这个例子中,它是 YYYYMMDDHHMM 的形式。在某些版本的 Java 中,您可以将“%t”放在您的日志文件位置,它将被格式为 YYYY-MM-DD_HH-MM-SS.

的服务器启动时间戳替换。

现在开始管理磁盘的使用 space。如果有比我现有的更简单的方法,我会很高兴。

首先,利用 Java 的内置 GC 日志文件轮换。 -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M 是启用此循环的示例,JVM 有多达 10 个 GC 日志文件,每个文件的大小不超过大约 10MB。 10 x 10MB 是 100MB 最大使用量。

随着 GC 日志文件轮换最多 10 个文件,“.0”、“.1”...“.9”将添加到您在 [=17= 中提供的文件名中]. .0 将是第一个,在达到 .9 后它将替换 .0 并以循环方式继续。在某些版本中 Java '.current' 将被附加在当前正在写入的日志文件名称的末尾。

由于独特的文件命名,我们显然必须避免覆盖,您可以有 100MB 每个 RM 或 AT 服务器进程调用,所以这不是一个完整的解决方案管理 YARN GC 日志使用的磁盘 space。您最终会在每次服务器调用时得到一组最多 10 个 GC 日志文件——这会随着时间的推移而增加。最好的解决方案(在 *nix 下)似乎是使用 logrotate 实用程序(或其他一些实用程序)定期清理最近 N 天未修改的 GC 日志。

一定要算一下,确保你有足够的磁盘 space。请注意,您可能 运行 同一主服务器上的 ResourceManager 和 ApplicationTimeline。

人们经常希望在他们的 GC 日志中看到比默认情况下更多的详细信息和上下文,因此请考虑添加 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps。 把这些放在一起,你可能会在 yarn-env 中添加一些东西:

# this function takes the name of a YARN component as input and returns the JVM options
# to enable GC logging for the component.  The option string is set in the variable named
# as the second arg
function yarn_gc_log_opts_for_component()
{
    # get function args
    local component_name=
    local  __resultvar=

    # calculate GC log name
    local timestamp_str=`date +'%Y%m%d%H%M'`
    local gc_log_name="{{yarn_log_dir_prefix}}/$USER/yarn-${component_name}-gc.log-${timestamp_str}"

    # calculate GC logging options for enablement, rotation, and format
    local gc_log_enable_opts="-verbose:gc -Xloggc:$gc_log_name"
    local gc_log_rotation_opts="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
    local gc_log_format_opts="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"

    # combing these options and return the result
    local gc_log_opts="$gc_log_enable_opts $gc_log_rotation_opts $gc_log_format_opts"
    eval $__resultvar="'$gc_log_opts'"
}

# 获取 YARN ResourceManager 服务器的 GC 日志选项并投入使用 yarn_gc_log_opts_for_component "resourcemanager" YARN_RESOURCEMANAGER_GC_LOG_OPTS

export YARN_RESOURCEMANAGER_OPTS="$YARN_RESOURCEMANAGER_OPTS $YARN_RESOURCEMANAGER_GC_LOG_OPTS"

# 获取 YARN AT 服务器的 GC 日志选项并投入使用 yarn_gc_log_opts_for_component "timelineserver" YARN_TIMELINESERVER_GC_LOG_OPTS

export YARN_RESOURCEMANAGER_OPTS="$YARN_RESOURCEMANAGER_OPTS $YARN_RESOURCEMANAGER_GC_LOG_OPTS"

在上面,您可以将 {{yarn_log_dir_prefix}}/$USER 更改为您希望 GC 日志去往的任何地方(您可能希望它去与 YARN RM 和 AT 服务器日志相同的地方)。您也可以更改日志文件命名。

如果您使用 Apache Ambari 管理 Hadoop 集群,那么这些更改将位于 YARN 服务 > 配置 > 高级 > 高级 yarn-env > yarn-env 模板中。使用 Ambari,{{yarn_log_dir_prefix}} 将自动替换为定义在字段上方几行的 YARN 日志目录前缀。

GC 日志记录将在服务器重启时开始。