0

我们最近决定在多个集群(具体版本不同)上启用 Hadoop NameNode 的 GC 日志记录,以帮助查看与 NameNode 相关的内存和垃圾收集问题。我们希望集群中的所有 NameNode(活动和备用或主要和辅助)都使用此功能。我们还想避免我们知道可能会发生的两个问题:

  • 当 NameNode 因任何原因重新启动时覆盖日志文件
  • 日志使用太多磁盘空间,导致磁盘被填满

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

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

4

1 回答 1

1

可以在 hadoop-env.sh 中设置环境变量有几个选择,以便在 NameNode 启动时传递 JVM 参数:

  • HADOOP_OPTS(适用于所有以“hadoop”开头的客户端和服务器调用,甚至是“hadoop dfs”)
  • HADOOP_NAMENODE_OPTS(使用 NameNode HA 这会影响活动和备用 NameNode,而没有 NameNode HA 会影响主 NameNode)
  • HADOOP_SECONDARYNAMENODE_OPTS(影响辅助NameNode,如果没有NameNode HA)

问题是专门针对 NameNode 的,因此我们希望将 JVM 参数添加到HADOOP_NAMENODE_OPTSHADOOP_SECONDARYNAMENODE_OPTS(如果相关)。现在让我们讨论要包含在其中的 JVM 参数。

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

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

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

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

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

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

请务必进行数学计算并确保您有足够的磁盘空间。

人们经常希望他们的 GC 日志中的详细信息和上下文比默认的更多,因此请考虑添加-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.

把这些放在一起,你可能会在 hadoop-env 中添加一些东西:

TIMESTAMP=`date +'%Y%m%d%H%M'`
# location/name prior to .n addition by log rotation
NAMENODE_GC_LOG_NAME="{{hdfs_log_dir_prefix}}/$USER/hdfs-namenode-gc.log-$TIMESTAMP"

NAMENODE_GC_LOG_ENABLE_OPTS="-verbose:gc -Xloggc:$NAMENODE_GC_LOG_NAME"
NAMENODE_GC_LOG_ROTATION_OPTS="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
NAMENODE_GC_LOG_FORMAT_OPTS="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"

NAMENODE_GC_LOG_OPTS="$NAMENODE_GC_LOG_ENABLE_OPTS $NAMENODE_GC_LOG_ROTATION_OPTS $NAMENODE_GC_LOG_FORMAT_OPTS" 

应该将其插入到设置位置上方的某个HADOOP_NAMENODE_OPTS位置HADOOP_SECONDARYNAMENODE_OPTS。然后添加$HADOOP_NAMENODE_OPTSHADOOP_NAMENODE_OPTSHADOOP_SECONDARYNAMENODE_OPTS(如果存在)代替任何现有的 GC 记录相关参数。

在上面,您可以更改{{hdfs_log_dir_prefix}}/$USER到您希望 GC 日志去的任何地方(您可能希望它去与 NameNode 日志相同的地方)。您也可以更改日志文件命名。

如果您使用 Apache Ambari 管理 Hadoop 集群,那么这些更改将位于 HDFS 服务 > 配置 > 高级 > 高级 hadoop-env > hadoop-env 模板中。使用 Ambari,{{hdfs_log_dir_prefix}}会自动替换为定义在 Hadoop Log Dir Prefix 上方几行的字段。

GC 日志记录将在 NameNode 重新启动时开始发生。如果您有 NameNode HA 并且两个 NameNode 都在线,那么您可以一次重新启动一个,而不会造成任何停机。

于 2016-10-04T18:27:27.010 回答