我们最近决定在多个集群上为apachestorm workers启用gc日志记录(具体版本各不相同),以帮助研究与拓扑相关的内存和垃圾收集问题。我们希望为工人这样做,但我们也希望避免可能发生的两个问题:
在工作进程因任何原因重新启动时覆盖日志文件
日志占用了太多的磁盘空间,导致磁盘被填满(如果您让集群运行足够长的时间,日志文件将填满磁盘,除非管理)
当一个进程的javagc日志记录开始时,它似乎会替换任何同名文件的内容。这意味着除非您小心,否则您将丢失gc日志记录,可能是在您最需要它的时候。
我们最近决定在多个集群上为apachestorm workers启用gc日志记录(具体版本各不相同),以帮助研究与拓扑相关的内存和垃圾收集问题。我们希望为工人这样做,但我们也希望避免可能发生的两个问题:
在工作进程因任何原因重新启动时覆盖日志文件
日志占用了太多的磁盘空间,导致磁盘被填满(如果您让集群运行足够长的时间,日志文件将填满磁盘,除非管理)
当一个进程的javagc日志记录开始时,它似乎会替换任何同名文件的内容。这意味着除非您小心,否则您将丢失gc日志记录,可能是在您最需要它的时候。
1条答案
按热度按时间hfsqlsce1#
您可以通过storm.yaml中的worker.childopts属性为storm workers设置jvm选项(如果您通过apache ambari管理storm,请查看storm服务>配置>高级storm站点>worker.childopts)。您将向其中添加额外的jvm属性。
要启用文件的gc日志记录,您需要添加
-verbose:gc -Xloggc:<log-file-location>
.您需要特别考虑日志文件名以防止重写。似乎每次调用都需要一个唯一的名称。要实现这一点,请利用storm代码文档中提到的一些特殊“%”字符串替换。为了独特性,
%WORKER-ID%
对于每个工作进程,它(很可能)是唯一的。您可能还希望能够轻松地判断gc日志用于什么拓扑。在这种情况下,加载项%TOPOLOGY-ID%
(你可能需要说%ID%
一些旧版本的风暴);它可能很长,但将提供拓扑的名称。到目前为止,jvm选项是
-verbose:gc -Xloggc:/var/log/storm/storm-worker-%TOPOLOGY-ID%-%WORKER-ID%-gc.log
(the)-%TOPOLOGY-ID%
是可选的,路径应与storm日志目录匹配,如果愿意,可以使用不同的名称命名日志文件)。现在开始管理磁盘空间的使用。如果有更简单的方法,我会很高兴的。
首先,利用java内置的gc日志文件循环。
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M
是启用此循环的一个示例,jvm中最多有10个gc日志文件,每个文件的大小不超过10mb。10x10MB是100mb的最大使用量。请注意,这是每个worker示例。随着gc日志文件轮换到位,最多有10个文件,“.0”、“.1”、“…”。9'将添加到您在xloggc中提供的文件名中。0将是第一个,在它到达.9之后,它将替换.0并以循环方式继续。在java的某些版本中,“.current”将另外放在当前正在写入的日志文件名称的末尾。
由于我们显然必须添加唯一的文件命名以避免重写,这意味着每个工作进程调用可以有100mb,因此这不是管理storm worker子gc日志使用的磁盘空间的总体解决方案。最后,每个进程最多有10个gc日志文件——这可以加起来。最好的解决方案(在*nix下)似乎是使用logrotate工具定期清理在过去n天内没有修改过的worker gc日志。
一定要计算一下,确保你有足够的磁盘空间。
人们通常希望在gc日志中包含比默认日志更多的细节和上下文,因此考虑添加
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
.总之,您将向worker.childopts添加以下内容:
-verbose:gc -Xloggc:/var/log/storm/storm-worker-%TOPOLOGY-ID%-%WORKER-ID%-gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
再加上配置logrotate。最后,我应该提到另外两个命名日志文件的选项,尽管我不认为这有什么好处,至少在我的用例中是这样的:
在某些java版本中,您可以将%t放在gc日志文件命名中,java将用格式化为的当前时间戳替换它
<YYYY>-<MM>-<DD>_<HH>-<MM>-<SS>
. 您还可以输出%p以获取当前进程id。有人告诉我,在某些情况下,您可以在storm和java的某些组合中使用倒勾表达式,例如“date+'%y%m%d%h%m',,至少如果您使用ambari的话。他报告说,这在Storm0.10.0和Java1.7.0\u95中起作用,但我无法在Storm0.9.3.2.2.0.0-2041和Java1.7.0\u75中获得这种行为。