套接字写入性能与磁盘写入性能的比较

5

我的Java应用程序将大量信息记录到磁盘上的日志文件中。其中一些记录的信息比其他信息更重要;但是在极少数情况下,需要使用不太重要的信息向最终用户解释为什么生产代码做出了某个决定。

我想知道将不太重要的信息记录到套接字而不是磁盘上的文件是否是一个好主意。套接字写入是否比磁盘写入快得多?

更新:基本上,我想记录到同一子网甚至同一台机器上的套接字,假设这比写入磁盘要快。然后,另一个进程(不是我的应用程序的一部分)会在方便时从该套接字读取。我想到的是Logstash从套接字中拉取。使用另一个线程异步记录到磁盘是另一种选择,但如果套接字选项是一种易于实现且性能损失最小的解决方案,我想首先考虑套接字选项。


1
这个套接字会被打开到哪里?套接字是输入/输出,磁盘也是输入/输出。我猜两者都可能非常慢。也许最好将日志记录放入低优先级线程中,以防止如果日志记录引起性能问题时干扰运行时间。 - Michael Dorgan
1
如果磁盘写入是完全基于RAM缓存的Optane SSD,并且套接字通过四个卫星反弹到南极前哨站,那么磁盘写入速度会更快。如果磁盘写入是同步挂载的软盘,并且套接字通过回送设备进行连接,其消费者只需进行零拷贝传输到RAM,那么套接字速度会更快。 - that other guy
最重要的问题是,你是否注意到了性能下降? - VGR
磁盘通常要更快一些:https://serverfault.com/questions/238417/are-networks-now-faster-than-disks 现代日志框架在性质上是异步的,因此日志语句的成本非常低。升级你的日志记录:https://logging.apache.org/log4j/2.x/manual/async.html - diginoise
如果您担心性能问题,首先要检查的是是否缓冲写入磁盘(例如使用BufferedOutputStreamBufferedWriter)。 - Mark Rotteveel
我也有同样的需求,我更倾向于使用异步SocketAppender将数据发送到本地日志收集器应用程序。然后Logstash会从收集器中获取数据。 - Siddappa Walake
2个回答

4
您有几种选择:

如果您正在某个快速写入的位置,并且从那里以较慢的方式转发(logstash通过网络记录到某个Elastic实例),缓冲区在哪里?如果长时间以高速率记录日志,则此设置将生成不断增长的待发送消息积压。


在上述情况下,缓冲区将会出现(分别是):

  • 直接同步写入磁盘:最终日志文件在磁盘上作为缓冲区
  • 异步记录框架:缓冲区可能占用您的堆或进程内存(当在堆外或某些内核区域时,因此在RAM中)
  • Unix域套接字:缓存在内核空间中,因此又是RAM

在最后2个选项中,在不断高容量场景下,情况将变得越来越糟糕。

测试和分析... 或者只需记录到本地磁盘并轮换文件,删除旧文件。


diginoise。感谢您的见解。在您上面提到的第三个链接中,不清楚套接字I/O通常比磁盘I/O更快 - 即在同一台机器上。我将运行基准测试来比较异步写入选项与套接字写入在同一台机器上的性能。 - Don
@Don 引用第三个链接中的第一个答案时说:“除了使用内核模块之外,UNIX 域套接字通常是最快的选项。” 我将这些称为 POSIX/BSD IPC sockets - 将其重命名为 Unix Domain Sockets - diginoise

2

Socket不是目的地,而是一种传输方式。因此,你的问题“将数据发送到socket”应该重新表述为“将数据发送到网络”、“将数据发送到磁盘”或“将数据发送到另一个进程”。

在所有这些情况下,socket本身不太可能成为瓶颈。瓶颈将是网络、磁盘或应用程序CPU使用率,这取决于您实际从socket发送数据的位置。在操作系统级别上,套接字通常被实现为零拷贝机制,这意味着数据只是作为指针传递到另一侧,因此高效。


感谢您的回答。请查看我对问题的更新。 - Don
嗯,即使更新了,我仍然不清楚您遇到的问题究竟是什么。看起来您关心的是日志性能,但“socket”这个术语实际上只是一个特殊的文件名。它与问题或解决方案没有任何关系。如果您询问性能,那就涉及到您的软件如何工作以及您拥有的硬件的具体情况。 - jurez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接