10

我有一个问题,需要我从远程机器上解析几个日志文件。有一些复杂性:1)文件可能正在使用 2)文件可能非常大(100mb+) 3)每个条目可能是多行的

要解决使用中的问题,我需要先复制它。我目前正在将它直接从远程机器复制到本地机器,并在那里解析它。这导致了问题 2。由于文件很大,因此在本地复制它可能需要很长时间。

为了增加解析时间,我想让解析器多线程,但这使得处理多行条目有点棘手。

两个主要问题是:1)我如何加快文件传输(压缩?,是否需要在本地传输?,我可以通过其他方式读取正在使用的文件吗?) 2)我如何处理多行条目在线程之间拆分行时?

更新:我没有对服务器进行明显解析的原因是我希望对 CPU 的影响尽可能小。我不想影响系统即时测试的性能。

4

9 回答 9

2

如果您正在读取一个顺序文件,您希望通过网络逐行读取它。您需要一种能够流式传输的传输方法。您需要查看您的 IO 流技术来解决这个问题。

像这样的大型 IO 操作不会从多线程中获得太多好处,因为您可以尽可能快地处理这些项目,因为您可以通过网络读取它们。

您的另一个不错的选择是将日志解析器放在服务器上,然后下载结果。

于 2008-09-26T00:23:12.523 回答
2

从性能的角度来看,更好的选择是在远程服务器上执行解析。除了特殊情况外,网络速度始终是瓶颈,因此限制通过网络发送的数据量将大大提高性能。

这是许多数据库使用在服务器端运行的存储过程的原因之一。

通过使用多线程来提高解析速度(如果有的话)将被网络传输的相对速度所淹没。

如果您致力于在解析文件之前传输文件,您可以考虑的一个选项是在进行文件传输时使用动态压缩。例如,有可用的 sftp 服务器可以即时执行压缩。在本地端,您可以使用libcurl之类的东西来执行传输的客户端,它还支持动态解压缩。

于 2008-09-26T01:44:24.920 回答
1

考虑到您已经在复制文件,最简单的方法是在复制之前对其进行压缩,并在复制完成后解压缩。压缩文本文件将获得巨大的收益,因为 zip 算法通常在它们上工作得很好。此外,您现有的解析逻辑可以保持不变,而不必将其连接到远程网络文本阅读器。

这种方法的缺点是您将无法非常有效地逐行更新,这对于日志解析器来说是一件好事。

于 2008-09-26T00:26:52.767 回答
1

我想这取决于它有多“远程”。100Mb LAN 上的 100MB 大约需要 8 秒……达到千兆位,大约 1 秒就可以了。卡 50 * 2 美元,交换机 100 美元将是您可以进行的非常便宜的升级。

但是,假设它比这更远,您应该能够以只读模式打开它(当您复制它时正在阅读它)。SMB/CIFS 支持文件块读取,因此您应该在此时流式传输文件(当然,您实际上并没有说明您是如何访问文件的 - 我只是假设 SMB)。

多线程无济于事,因为无论如何您都会受到磁盘或网络的限制。

于 2008-09-26T01:04:41.363 回答
1

使用压缩传输。

如果你的解析真的让你慢下来,并且你有多个处理器,你可以打破解析工作,你只需要以一种聪明的方式来做——有一个确定性的算法,工作人员负责处理不完整的记录。假设您可以确定一行是记录中间的一部分,例如,您可以将文件分成 N/M 段,每个段负责 M 行;当其中一项作业确定其记录未完成时,它只需要继续阅读,直到到达记录的末尾。当其中一个作业确定它正在读取它没有开始的记录时,它应该跳过该记录。

于 2008-09-26T01:21:10.420 回答
1

如果您可以复制文件,则可以阅读它。所以一开始就没有必要复制它。

编辑:使用FileStream 类可以更好地控制访问和共享模式。

new FileStream("logfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

应该做的伎俩。

于 2008-09-26T07:36:13.700 回答
0

我使用SharpZipLib在通过 Internet 传输大文件之前对其进行压缩。所以这是一种选择。

1) 的另一个想法是创建一个在远程机器上运行并在那里进行解析的程序集。您可以使用 .NET 远程处理从本地计算机访问程序集。远程程序集需要是 Windows 服务或托管在 IIS 中。这将允许您将日志文件的副本保存在同一台机器上,理论上处理它们需要更少的时间。

于 2008-09-26T00:28:09.517 回答
0

我认为使用压缩(deflate/gzip)会有所帮助

于 2008-09-26T00:29:15.520 回答
0

给定的答案不让我满意,也许我的答案会帮助其他人不要认为它是超级复杂的,或者多线程在这种情况下不会受益。也许它不会使传输更快,但根据解析的复杂性,它可能会使解析数据的解析/或分析更快。

这实际上取决于您的解析细节。您需要从日志文件中获取哪些信息?这些信息是像统计信息还是依赖于多个日志消息?你有几个选择:

  • 我想同时解析多个文件是最简单的,您将文件作为上下文,并且可以为每个文件创建一个线程
  • 前面提到的另一个选项是对网络通信使用压缩
  • 您还可以使用帮助程序将日志文件拆分为作为第一步属于一起的行,然后使用多个线程处理这些行块;这个依赖行的解析应该非常容易和快速。

在这种情况下,非常重要的是衡量您的实际瓶颈是什么。如果您的瓶颈是网络,您将不会从优化解析器中受益。如果您的解析器创建了许多相同类型的对象,您可以使用 ObjectPool 模式并创建具有多个线程的对象。尝试在不分配太多新字符串的情况下处理输入。解析器通常是通过使用大量的 string.Split 等来编写的,这并不像它可能的那么快。您可以通过检查即将出现的值来导航 Stream,而无需读取完整的字符串并再次拆分它,而是在解析完成后直接填充您需要的对象。

优化几乎总是可能的,问题是你有多少输入和你的场景有多重要。

于 2019-02-16T12:20:21.683 回答