如何为 Apache Storm 进程启用 GC 日志记录,同时防止日志文件覆盖和限制磁盘 space 使用

How to enable GC logging for Apache Storm processes, while preventing log file overwrites and capping disk space usage

我们最近决定为多个 Apache Storm 进程启用 GC 日志记录:Nimbus、UI、DRPC 服务器、主管和日志查看器。 (另一个问题涵盖了 Storm worker:。)我们正在许多集群(具体版本各不相同)上执行此操作,以帮助调查与 Storm 相关的内存和垃圾收集问题。这样做时,我们想避免两个我们知道可能会发生的问题:

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

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

我有解决这些问题的方法,只是防覆盖功能不适用于 Java 的所有版本。欢迎提出建议。

您需要在启动服务器时设置一些 JVM 参数。您可以通过以下 storm.yaml 属性为 Storm 进程设置 JVM 选项(如果您通过 Apache Ambari 管理 Storm,请查看 Storm 服务 > 配置 > 高级风暴站点 > worker.childopts):

  • nimbus.childopts:雨云
  • supervisor.childopts:主管
  • ui.childopts:风暴UI
  • drpc.childopts: DRPC 服务器
  • logviewer.childopts: 日志查看器
  • worker.childopts:Storm 工作人员(超出此问题的范围)

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

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

您需要特别考虑日志文件名以防止覆盖。显然,您会希望为不同类型的 Storm 进程使用不同的 GC 日志文件名。似乎您还需要为每次调用设置一个唯一的名称,添加时间戳似乎是最好的解决方案。在某些版本的 Java 中,您可以在 Xloggc 值中放置一个“%t”,它将被进程启动时的时间戳替换,格式为 <YYYY>-<MM>-<DD>_<HH>-<MM>-<SS>。但是,在 Java 的其他版本中,“%t”将按字面意思包含在文件名中。

到目前为止,JVM 选项是(以 Nimbus 为例)-verbose:gc -Xloggc:/var/log/storm/storm-nimbus-gc.log-%t(路径应该与您的 Storm 日志目录相匹配,如果您愿意,可以不同地命名日志文件,以及“-%t " 应在 Java 不支持的地方省略)。

现在开始管理磁盘的使用 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 由 Storm GC 日志使用。您最终会在每次服务器调用时得到一组最多 10 个 GC 日志文件——这会随着时间的推移而增加。最好的解决方案(在 *nix 下)似乎是使用 logrotate 实用程序(或其他一些实用程序)定期清理最近 N 天未修改的 GC 日志。

一定要算一下,确保你有足够的磁盘 space。请注意,您的机器可能会有多个进程同时写入 GC 日志。

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

总而言之,您将向属性中添加如下内容:

  • nimbus.childopts: -verbose:gc -Xloggc:/var/log/storm/storm-nimbus-gc.log-%t -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.
  • supervisor.childopts: -verbose:gc -Xloggc:/var/log/storm/storm-supervisor-gc.log-%t -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.
  • ui.childopts: -verbose:gc -Xloggc:/var/log/storm/storm-ui-gc.log-%t -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.
  • drpc.childopts: -verbose:gc -Xloggc:/var/log/storm/storm-drpc-gc.log-%t -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.
  • logviewer.childopts: -verbose:gc -Xloggc:/var/log/storm/storm-logviewer-gc.log-%t -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.

执行此操作时,请检查其中一些 JVM 参数是否已存在。还要记得用 logrotate 或其他东西清除旧的 GC 日志。

GC 日志将在进程重启时生效。