【问题标题】:Performance of Socket write vs disk write套接字写入与磁盘写入的性能
【发布时间】:2019-01-06 23:59:05
【问题描述】:

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

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

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

【问题讨论】:

  • 这个套接字将被打开到哪里?套接字是 I/O,磁盘是 I/O。我猜两者可能都非常慢。或许最好将您的日志记录放到一个低优先级线程中,这样如果日志记录导致性能问题就不会影响您的运行时间?
  • 如果磁盘写入是完全 RAM 缓存的 Optane SSD,并且套接字是通过四颗卫星反弹到南极前哨的拨号连接,则磁盘写入速度会更快。如果磁盘写入到同步安装的软盘,并且套接字是通过环回设备并且其消费者只是对 RAM 进行零拷贝传输,那么套接字会更快。
  • 最重要的问题是,您是否注意到性能下降?
  • 磁盘通常更快:serverfault.com/questions/238417/… 现代日志框架本质上是异步的,因此日志语句的成本非常低。升级您的日志记录:logging.apache.org/log4j/2.x/manual/async.html
  • 如果您担心性能问题,您首先要检查的是您是否正在缓冲写入磁盘(例如使用BufferedOutputStreamBufferedWriter)。

标签: java performance sockets logging


【解决方案1】:

你有几个选择:

如果您正在快速写入某个地方,并且从那里以较慢的方式转发(logstash 通过网络登录到某个 Elastic 实例),缓冲发生在哪里?如果日志记录在很长一段时间内以高速率发生,这种设置将产生越来越多的尚未发送的消息积压。


在上述情况下,缓冲将(分别)发生:
  • 直接同步写入磁盘:最终日志磁盘上的文件是缓冲区
  • 异步日志框架:缓冲区可能会占用您的堆或进程内存(在堆外或某些内核区域时,因此在 RAM 中)
  • unix 域套接字:在内核空间中缓冲,所以再次RAM

在最后 2 个选项中,在持续高容量的情况下,事情会变得越来越不稳定。

测试和配置文件... 或者只是登录到本地磁盘并旋转文件,删除旧文件。

【讨论】:

  • 数字化。感谢您的见解。在您上面提到的第三个链接中,尚不清楚套接字 i/o 通常比磁盘 i/o 快 - 比如在同一台机器上。我将运行一个基准测试来比较异步写入选项与同一台机器上的套接字写入的性能。
  • @Don 引用第三个链接的第一个答案:“UNIX 域套接字通常是使用模块进入内核空间之外的最快选择”。我将这些 POSIX/BSD IPC 套接字 命名为 - 将重命名为 Unix 域套接字
【解决方案2】:

套接字不是目的地。是交通工具。因此,您的问题“向套接字发送数据”应改写为“向网络发送数据”、“向磁盘发送数据”或“向另一个进程发送数据”。

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

【讨论】:

  • 感谢您的回答。请查看我对我的问题的更新。
  • 嗯,即使更新后,我仍然不清楚您遇到的问题到底是什么。您似乎关心日志记录性能,但术语“套接字”实际上只是一个特殊的文件名。它与问题或解决方案没有任何关系。如果您问的是性能,那么问题是您的软件如何工作以及您拥有什么硬件。
猜你喜欢
  • 2018-05-31
  • 2016-01-31
  • 2011-02-20
  • 2013-01-02
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多