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

标签 hadoop logging garbage-collection hadoop-yarn diskspace

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

  • 当 YARN RM 或 AT 服务器因任何原因重启时覆盖日志文件
  • 日志使用过多的磁盘空间,导致磁盘被填满

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

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

最佳答案

启动 YARN 服务器时,您需要设置一些 JVM 参数,这意味着您需要对 yarn-env.sh 进行一些更改。您可以在 YARN_OPTS 中设置参数,但这会产生比 ResourceManager 和 ApplicationTimeline 服务器更广泛的影响,因此您可能希望同时在 YARN_RESOURCEMANAGER_OPTS 中进行设置和 YARN_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 的服务器启动时间戳替换。

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

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

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

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

请务必进行计算并确保您有足够的磁盘空间。请注意,您可能在同一台主服务器上运行 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=$1
    local  __resultvar=$2

    # 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 “资源管理器” 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 日志记录将在服务器重启时开始。

关于hadoop - 如何为 Hadoop YARN ResourceManager 和 ApplicationTimeline 启用 GC 日志记录,同时防止日志文件覆盖和限制磁盘空间使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39883995/

相关文章:

mysql - Hadoop(+HBase/HDFS)与 Mysql(或 Postgres)——要处理和查询的独立结构化数据负载

hadoop - 使用elephant-bird配合hive读取protobuf数据

logging - Logrus 时间戳格式

java - Java 中的死存储到局部变量

r - 通过 sparklyr 连接到 s3 bucket 时出现签名错误

hadoop - 包含分号的sqoop密码

json - Datadog Grok 解析 - 从嵌套的 JSON 中提取字段

arrays - 不要在日志中打印 secret

java - java 垃圾收集日志条目 "Full GC (System)"是否意味着某个名为 System.gc() 的类?

c# - 可以强制对象在第 1 代或第 2 代而不是第 0 代中被垃圾回收吗?