我正在寻找在红帽服务器上以日志文件(每天大约5G)生成大量数据的应用程序。 这个过程在一周中运行了24个小时,所以当天没有修改文件的时间没有意义,虽然午夜时间添加的信息并不是特别重要,所以如果丢失的话可以让我们说一个那段时间的数据只有几秒钟。
为了每天制作日志文件的“安全”档案,我创build了一个脚本,在清晨的某个时间点执行以下操作:
如果有明显的问题,这里是脚本本身:
DF=$(date +"%Y%m%d_%H%M%S") TARGET="fixdata-logs-$DF" cp -r ./fixdata/logs $TARGET #Truncate the original log file find ./fixdata/logs -name '*.log' -exec sh -c 'cat /dev/null >| {}' \; #Zip the log files tar -zcvf $TARGET.tar.gz $TARGET #Delete the labelled copy rm -rf $TARGET #Archive files older tha 3 days find . -type f -mtime +3 -name \*.gz -exec mv {} $ARCHIVE_DIR \;
(据我所知,有些数据可能会丢失,但是这个脚本运行的时间是几秒钟的数据丢失并不重要。)
问题是,在此期间,应用程序经常报告与系统资源相关的错误。 例如,其队列的心跳监视器通常不能产生定期的心跳。 很显然,copy-> tar.gz->移动过程对服务器IO造成的影响足以影响应用程序的行为。
我怎样才能减less这个脚本的影响? 时间到终点并不重要 – 如果一个解决scheme需要更长的时间,但不会导致应用程序错误,那么这是比较快的。 我应该考虑其他方法吗?
为了完整起见,我考虑了以下内容但有疑问:
您可以通过不执行copy + truncate来显着减lessI / O负载。 相反,重命名文件,然后,如果进程持有日志文件描述符打开,做任何需要使其回收其日志描述符(通常发送HUP
是这样做的规范方式)。 如果程序还没有这个function,那么就修补它。
通过这样做,您不会在同一个介质(同时读取+写入)上拥有副本的I / O开销,然后截断(根据您的文件系统,截断可能是也可能不是重要负载) , 然后读取到tar / compress和写入负载来做归档。
一旦你重新命名了日志文件,你可以在任何闲暇时都进行tar / compress /。 为了进一步减lessI / O负载,考虑将tar / compress的写入端直接写入存档存储 – 而您的存档存储可能不是一个典型的随机访问设备,它仍然需要直接stream正在被压缩的数据(甚至S3可以通过正确的CLI工具来实现)。
与上述正交的另一个要考虑的是使用ionice
。 通过以ionice -c 3 <command>
运行程序,可以将进程的I / O优先级降低到“仅空闲”状态 – 也就是说,如果系统上还有其他需要执行I / O的任务,你的程序会被碰撞。 这是一个很好的想法,但是如果你有一个沉重的I / O系统(你的程序可能需要完成一些工作,因为它很less获得I / O时间),它可能会在后面咬你。 如果你已经做了这么多的不必要的I / O,那么使它成为“空闲”优先级就会使问题变得更糟。
我也非常怀疑闲置时间安排并不完全符合锡上的说法。 当“空闲”程序正在运行时,与“空闲”程序没有运行时相比,我在其他(“尽力而为”计划)程序上的性能略有下降。 我怀疑这是因为当程序要求input/输出而“空闲”进程正在进行I / O操作时,直到I / O在“尽力而为”之前完成,过程“可以启动I / O操作。 也就是说,比起“尽力而为”的stream程以“尽力而为”的优先级运行,还是要好很多,但这并不是一个乍看之下的奇迹。
看看rhel中提供的logrotate linux实用程序,它具有压缩,复制截断和其他各种选项,并且还处理应用程序正在使用的日志文件。 你也可以尝试使用一个SSD磁盘,并将数据复制到应该是最快的,尽pipe它仍然会使用CPU的CPU速度慢的磁盘将被淘汰,只要你不使用USB。