Chronicle queue + log4j2 async logger

时间:2017-12-25 18:59:25

标签: log4j2 chronicle-queue

我使用log4j2 2.10.0并具有以下代码:

   SingleChronicleQueue q = SingleChronicleQueueBuilder.binary(args[0]).blockSize(536870912).build();
    ExcerptAppender a = q.acquireAppender();

    char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
    StringBuilder sb = new StringBuilder();
    Random random = new Random();
    for (int i = 0; i < 1000; i++) {
        char c = chars[random.nextInt(chars.length)];
        sb.append(c);
    }
    String t = sb.toString();

    for (int i = 0; i < 1000000; i ++ ) {
        m_logger.info(i + " " + t);
        a.writeText(t);
    }

cq4和日志都写入同一个目录。

在日志中,直到我能看到

,它才会爆炸
    12:40:00.853 - [main] INFO c.c.c.a.r.SandboxApp 601049 
    12:40:00.853 - [main] INFO c.c.c.a.r.SandboxApp 601050 
    12:40:00.853 - [main] INFO c.c.c.a.r.SandboxApp 601051 
    12:40:06.156 - [main] INFO c.c.c.a.r.SandboxApp 601052 

有某种IO操作使其延迟6秒。

我对磁盘,挂载等知之甚少。如果我注释掉writeText,这会消失,但我不知道它是编年史问题还是log4j2。

我的log4j2参数是

-DLog4jContextSelector = org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -DAsyncLogger.RingBufferSize = 65536 * 65536 -DAsyncLogger.WaitStrategy = Sleep -Dlog4j2.AsyncQueueFullPolicy = Discard -Dlog4j2.DiscardThreshold = INFO

这是分析器显示的内容

Profiler

谢谢!

1 个答案:

答案 0 :(得分:0)

开始使用内存映射文件后,您将离开Java领域并进入操作系统(和硬件)世界。

那么,问题1:您使用的操作系统(以及版本)是什么?

问题2:您的机器上有多少物理内存?

问题3:您使用的硬盘是什么? SSD还是旋转磁盘?

2017年,超过200 MB /秒写入速度的消费级旋转磁盘非常快。相比之下,this 2017 comparison中最快的SSD写入1900 MB /秒。

您刚刚尝试将大约2GB写入内存映射文件。这需要在某些时候与物理磁盘同步。同步可能需要6秒......

内存映射文件的“快乐”是您无法控制何时发生此同步。人们最终会分成较小的文件,以确保这些暂停不会变得太大。调整这种应用程序的性能有一些黑魔法方面。在这个领域有很多东西需要学习。欢乐时光!享受!

顺便说一下,你无法配置

-DAsyncLogger.RingBufferSize=65536*65536 # not a number

Log4j2将尝试将65536*65536解析为一个数字,这将失败,它将回退使用默认的缓冲区大小。您需要以字节指定所需的环形缓冲区大小