Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何让线程停止相互阻止写入磁盘上的日志文件?_Java_Multithreading_Logging_File Io_Blocking - Fatal编程技术网

Java 如何让线程停止相互阻止写入磁盘上的日志文件?

Java 如何让线程停止相互阻止写入磁盘上的日志文件?,java,multithreading,logging,file-io,blocking,Java,Multithreading,Logging,File Io,Blocking,我的线程已经落后于计划,一个线程转储显示它们都被阻止IO将日志输出写入硬盘。我的快速修复方法只是减少日志记录,这对于我的QA需求来说是很容易做到的。当然,这不是垂直可伸缩的,这很快就会成为一个问题 我想增加线程数,但我猜瓶颈在于文件争用,如果这样做是错误的,这可能会非常糟糕 我有很多想法,但真的不知道哪些是富有成效的 我想增加线程数,但我猜他们是瓶颈,所以这不会做任何事情。这是正确的吗?如何确定?减少线程数有帮助吗 如何分析要写入磁盘的正确线程?这是写请求数、每秒写入的字节数、每次写入操作的字节

我的线程已经落后于计划,一个线程转储显示它们都被阻止IO将日志输出写入硬盘。我的快速修复方法只是减少日志记录,这对于我的QA需求来说是很容易做到的。当然,这不是垂直可伸缩的,这很快就会成为一个问题

我想增加线程数,但我猜瓶颈在于文件争用,如果这样做是错误的,这可能会非常糟糕

我有很多想法,但真的不知道哪些是富有成效的

  • 我想增加线程数,但我猜他们是瓶颈,所以这不会做任何事情。这是正确的吗?如何确定?减少线程数有帮助吗
  • 如何分析要写入磁盘的正确线程?这是写请求数、每秒写入的字节数、每次写入操作的字节数的函数吗
  • 我是否可以切换较低级别的设置(文件系统、操作系统等)以减少对文件的锁定,以换取可能出现的无序行?是在我的Java应用程序中还是在较低级别
  • 我可以分析我的系统或硬盘以确保它不会因某种原因工作过度吗?(模糊不清,但我不在这里)
  • 所以我的问题是:如何配置文件以确定可以安全写入公共文件的线程的正确数量?哪些变量决定了这一点-写入操作数、每秒写入的字节数、每个写入请求的字节数、任何操作系统或硬盘信息

    还有什么方法可以使日志文件更自由地写入?我们给每件事都加上时间戳,所以如果减少阻塞的话,我可以处理一些无序的行

    我的线程已经落后于计划,一个线程转储显示它们都被阻止IO将日志输出写入硬盘

    通常在这些情况下,我会安排一个线程用于日志记录。大多数日志类(如
    PrintStream
    )都是同步的,并写入/刷新每一行输出。通过移动到中心日志线程并使用某种类型的
    BlockingQueue
    将要写入的日志消息排队,您可以使用
    BufferedWriter
    或类似的工具来限制单个IO请求。默认缓冲区大小为8k,但应增加该大小。您需要确保在应用程序关闭时正确关闭流

    使用缓冲写入程序,您还可以通过
    GZIPOutputStream
    进行额外写入,如果日志消息重复很多,这将显著降低IO要求

    也就是说,如果您输出的调试信息太多,您可能会感到不安,需要减少日志记录带宽或提高磁盘IO速度。优化应用程序后,接下来的步骤包括移动到日志服务器上的SSD以处理负载。您还可以尝试将日志消息分发到多个要持久化的服务器,但本地SSD很可能会更快

    为了模拟SSD的好处,本地RAM磁盘应该能让您对增加IO带宽有一个很好的了解

    我想增加线程数,但我猜他们是瓶颈,所以这不会做任何事情。这是正确的吗

    如果所有线程都在IO中被阻塞,那么是的,增加线程数将没有帮助

    如何分析要写入磁盘的正确线程

    这个问题很难回答。您将不得不进行一些测试运行。查看应用程序的吞吐量,包括10个线程、20个线程等。。您正试图在一段时间内最大化处理的总体事务。确保测试运行执行几分钟以获得最佳结果。但是,重要的是要认识到,如果磁盘或网络IO流输出过多,单个线程很容易淹没它

    我是否可以切换较低级别的设置(文件系统、操作系统等)以减少对文件的锁定,以换取可能出现的无序行?是在我的Java应用程序中还是在较低级别

    否。请参阅上面的缓冲线程编写器。这并不是关于文件锁定的问题,我想这是不会发生的。这是关于每秒IO请求的数量

    我可以分析我的系统或硬盘以确保它不会因某种原因工作过度吗?(模糊不清,但我不在这里)


    如果你被IO束缚,那么IO会使你减速,因此它是“过度工作的”。移动到SSD或RAM磁盘是一个很容易的测试,看看您的应用程序是否运行得更快。

    为了补充这个极好的答案,值得注意的是,现在几乎所有的HDD都支持NCQ,即本机命令队列。这意味着HDD将自动重新排序磁盘读/写,以优化吞吐量。因此,如果你的应用程序,不管是否有线程和/或缓冲,到处写入各种各样的文件,硬盘驱动器将合理地将混乱转化为从磁盘吞吐量的角度来看有意义的东西。因此,如果现在速度太慢,改进的空间可能有限。GZipOutputStream是个好主意;操作系统压缩文件系统怎么样?然后买一个SSD…是的-带阻塞队列的单个记录器线程应该会解决这个问题。SSD-这就更好了,尽管即使是微调器也应该可以,因为有一个队列和记录器线程来占用磁盘延迟。