如何为 Hadoop MapReduce2 历史服务器启用 GC 日志记录,同时防止日志文件覆盖和限制磁盘 space 使用
How to enable GC logging for Hadoop MapReduce2 History Server, while preventing log file overwrites and capping disk space usage
我们最近决定在多个集群(具体版本各不相同)上为 Hadoop MapReduce2 历史服务器启用 GC 日志记录,以帮助调查与历史服务器相关的内存和垃圾收集问题。这样做时,我们想避免两个我们知道可能会发生的问题:
- 当 MR2 历史服务器因任何原因重新启动时覆盖日志文件
- 日志使用过多磁盘 space,导致磁盘被填满
当 Java GC 日志记录开始时,它似乎会替换任何同名文件的内容。这意味着除非您小心,否则您将丢失 GC 日志记录,也许在您更有可能需要它的时候。
如果您将集群 运行 保持足够长的时间,除非进行管理,否则日志文件将填满磁盘。即使 GC 日志记录目前不是很多,我们也希望管理出现导致日志记录率突然飙升的异常情况的风险。
启动MapReduce2 History Server时需要设置一些JVM参数,也就是说需要对mapred-env.sh做一些改动。您可以在 HADOOP_OPTS 中设置参数,但这会产生比历史服务器更广泛的影响,因此您可能希望在 HADOOP_JOB_HISTORYSERVER_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”将添加到您在 [=14= 中提供的文件名中]. .0 将是第一个,在达到 .9 后它将替换 .0 并以循环方式继续。在某些版本中 Java '.current' 将被附加在当前正在写入的日志文件名称的末尾。
由于独特的文件命名,我们显然必须避免覆盖,您可以有 100MB 每次历史服务器调用,所以这不是管理磁盘的完整解决方案space 由服务器的 GC 日志使用。您最终会在每次服务器调用时得到一组最多 10 个 GC 日志文件——这会随着时间的推移而增加。最好的解决方案(在 *nix 下)似乎是使用 logrotate 实用程序(或其他一些实用程序)定期清理最近 N 天未修改的 GC 日志。
一定要算一下,确保你有足够的磁盘 space。
人们经常希望在他们的 GC 日志中看到比默认情况下更多的详细信息和上下文,因此请考虑添加 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
。
将这些放在一起,您可以将以下内容添加到 mapred-env:
## enable GC logging for MR2 History Server:
TIMESTAMP=`date +'%Y%m%d%H%M'`
# GC log location/name prior to .n addition by log rotation
JOB_HISTORYSERVER_GC_LOG_NAME="{{mapred_log_dir_prefix}}/$USER/mapred-jobhistory-gc.log-$TIMESTAMP"
JOB_HISTORYSERVER_GC_LOG_ENABLE_OPTS="-verbose:gc -Xloggc:$JOB_HISTORYSERVER_GC_LOG_NAME"
JOB_HISTORYSERVER_GC_LOG_ROTATION_OPTS="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
JOB_HISTORYSERVER_GC_LOG_FORMAT_OPTS="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
JOB_HISTORYSERVER_GC_LOG_OPTS="$JOB_HISTORYSERVER_GC_LOG_ENABLE_OPTS $JOB_HISTORYSERVER_GC_LOG_ROTATION_OPTS $JOB_HISTORYSERVER_GC_LOG_FORMAT_OPTS"
export HADOOP_JOB_HISTORYSERVER_OPTS="$HADOOP_JOB_HISTORYSERVER_OPTS $JOB_HISTORYSERVER_GC_LOG_OPTS"
您可能会发现您已经有对 HADOOP_JOB_HISTORYSERVER_OPTS
的引用,因此您应该替换或添加它。
在上面,您可以将 {{mapred_log_dir_prefix}}/$USER
更改为您希望 GC 日志去往的任何地方(您可能希望它去与 MapReduce 历史服务器日志相同的地方)。您也可以更改日志文件命名。
如果您使用 Apache Ambari 管理 Hadoop 集群,那么这些更改将位于 MapReduce2 服务 > 配置 > 高级 > 高级 mapred-env > mapred-env 模板中。使用 Ambari,{{mapred_log_dir_prefix}}
将自动替换为定义在该字段上方几行的 Mapreduce 日志目录前缀。
GC 日志记录将在服务器重新启动时开始,因此您可能需要短暂中断才能启用此功能。
我们最近决定在多个集群(具体版本各不相同)上为 Hadoop MapReduce2 历史服务器启用 GC 日志记录,以帮助调查与历史服务器相关的内存和垃圾收集问题。这样做时,我们想避免两个我们知道可能会发生的问题:
- 当 MR2 历史服务器因任何原因重新启动时覆盖日志文件
- 日志使用过多磁盘 space,导致磁盘被填满
当 Java GC 日志记录开始时,它似乎会替换任何同名文件的内容。这意味着除非您小心,否则您将丢失 GC 日志记录,也许在您更有可能需要它的时候。
如果您将集群 运行 保持足够长的时间,除非进行管理,否则日志文件将填满磁盘。即使 GC 日志记录目前不是很多,我们也希望管理出现导致日志记录率突然飙升的异常情况的风险。
启动MapReduce2 History Server时需要设置一些JVM参数,也就是说需要对mapred-env.sh做一些改动。您可以在 HADOOP_OPTS 中设置参数,但这会产生比历史服务器更广泛的影响,因此您可能希望在 HADOOP_JOB_HISTORYSERVER_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”将添加到您在 [=14= 中提供的文件名中]. .0 将是第一个,在达到 .9 后它将替换 .0 并以循环方式继续。在某些版本中 Java '.current' 将被附加在当前正在写入的日志文件名称的末尾。
由于独特的文件命名,我们显然必须避免覆盖,您可以有 100MB 每次历史服务器调用,所以这不是管理磁盘的完整解决方案space 由服务器的 GC 日志使用。您最终会在每次服务器调用时得到一组最多 10 个 GC 日志文件——这会随着时间的推移而增加。最好的解决方案(在 *nix 下)似乎是使用 logrotate 实用程序(或其他一些实用程序)定期清理最近 N 天未修改的 GC 日志。
一定要算一下,确保你有足够的磁盘 space。
人们经常希望在他们的 GC 日志中看到比默认情况下更多的详细信息和上下文,因此请考虑添加 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
。
将这些放在一起,您可以将以下内容添加到 mapred-env:
## enable GC logging for MR2 History Server:
TIMESTAMP=`date +'%Y%m%d%H%M'`
# GC log location/name prior to .n addition by log rotation
JOB_HISTORYSERVER_GC_LOG_NAME="{{mapred_log_dir_prefix}}/$USER/mapred-jobhistory-gc.log-$TIMESTAMP"
JOB_HISTORYSERVER_GC_LOG_ENABLE_OPTS="-verbose:gc -Xloggc:$JOB_HISTORYSERVER_GC_LOG_NAME"
JOB_HISTORYSERVER_GC_LOG_ROTATION_OPTS="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
JOB_HISTORYSERVER_GC_LOG_FORMAT_OPTS="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
JOB_HISTORYSERVER_GC_LOG_OPTS="$JOB_HISTORYSERVER_GC_LOG_ENABLE_OPTS $JOB_HISTORYSERVER_GC_LOG_ROTATION_OPTS $JOB_HISTORYSERVER_GC_LOG_FORMAT_OPTS"
export HADOOP_JOB_HISTORYSERVER_OPTS="$HADOOP_JOB_HISTORYSERVER_OPTS $JOB_HISTORYSERVER_GC_LOG_OPTS"
您可能会发现您已经有对 HADOOP_JOB_HISTORYSERVER_OPTS
的引用,因此您应该替换或添加它。
在上面,您可以将 {{mapred_log_dir_prefix}}/$USER
更改为您希望 GC 日志去往的任何地方(您可能希望它去与 MapReduce 历史服务器日志相同的地方)。您也可以更改日志文件命名。
如果您使用 Apache Ambari 管理 Hadoop 集群,那么这些更改将位于 MapReduce2 服务 > 配置 > 高级 > 高级 mapred-env > mapred-env 模板中。使用 Ambari,{{mapred_log_dir_prefix}}
将自动替换为定义在该字段上方几行的 Mapreduce 日志目录前缀。
GC 日志记录将在服务器重新启动时开始,因此您可能需要短暂中断才能启用此功能。