Chronicle队列+log4j2异步记录器[英] Chronicle queue + log4j2 async logger

本文是小编为大家收集整理的关于Chronicle队列+log4j2异步记录器的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我使用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和日志都写入同一DIR.

在日志中,它爆炸了,直到我看到

    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所显示的

 profiler

谢谢!

推荐答案

开始使用内存映射文件后,您就会离开Java领域并输入操作系统(和硬件)的世界.

所以,问题1:您正在使用什么操作系统(以及什么版本)?

问题2:您的机器上有多少物理记忆?

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

在2017年,超过200 MB/sec的消费级旋转磁盘非常快.相比之下,

顺便说一句,您无法配置

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

log4j2将尝试将其解析为一个数字,它将失败,并且会倒退以使用默认的缓冲区大小.您需要在字节中指定所需的环缓冲区大小.

本文地址:https://www.itbaoku.cn/post/1575193.html

问题描述

I use log4j2 2.10.0 and have the following code:

   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);
    }

Both the cq4 and the log is writing to the same dir.

And in the log, it was blasting out fine until I can see

    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 

There's some sort of IO operation that made it delayed 6 seconds.

I don't know enough about disk, mount, etc. This would disappear if I comment out the writeText but I don't know if it's a chronicle problem or log4j2.

My log4j2 parameter is

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

Here's what the profiler is showing

Profiler

Thanks!!

推荐答案

Once you start to work with memory-mapped files, you leave the realm of Java and enter the world of operating systems (and hardware).

So, question 1: what operating system (and what version) are you using?

Question 2: how much physical memory do you have on your machine?

Question 3: what hard disk are you using? SSD or spinning disk?

In 2017, consumer grade spinning disks exceeding 200 MB/sec write speed are pretty fast. By comparison, the fastest SSD in this 2017 comparison writes 1900 MB/sec.

You did just try to write about 2GB to a memory mapped file. That needs to be sync-ed with the physical disk at some point. That syncing could easily take 6 seconds...

The “joy” with memory mapped files is that you have little control over when this syncing happens. People end up splitting into smaller files to ensure these pauses don't grow too large. There is some aspect of black magic in tuning the performance of this kind of applications. There is a lot to learn in this field. Fun times ahead! Enjoy!

By the way, you cannot configure

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

Log4j2 will try to parse 65536*65536 as a number, which will fail, and it will fall back to use the default buffer size instead. You need to specify the desired ring buffer size in bytes.