V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ligiggy
V2EX  ›  C++

请教如何打 log,性能最好

  •  
  •   ligiggy · 2022-07-11 16:58:37 +08:00 · 5159 次点击
    这是一个创建于 890 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果每打一句 log ,就阻塞住,通过 filestream 往文件中写入一句 log ,写入很多次(比如 10000 次),多少会影响程序性能。

    想请教各位大佬,性能最好的 log 方案是什么样的?

    31 条回复    2022-09-21 13:39:39 +08:00
    MoYi123
        1
    MoYi123  
       2022-07-11 17:04:21 +08:00
    一般会弄个队列异步写文件, 性能最好的应该是 log4j2 里用的 disruptor 吧.
    这东西还是找找成熟的第三方库吧, 没必要自己写.
    ligiggy
        2
    ligiggy  
    OP
       2022-07-11 17:08:14 +08:00
    @MoYi123 c++好像不是 log4j2 ,异步写的话,要缓存,然后开线程吧,会不会还不如直接写到文件里。
    xhldtc
        3
    xhldtc  
       2022-07-11 17:13:09 +08:00
    log4j = log for java, C++应该没这玩意吧
    lonewolfakela
        4
    lonewolfakela  
       2022-07-11 17:13:30 +08:00
    c++先上 https://github.com/gabime/spdlog ,不够用再研究别的
    MoYi123
        5
    MoYi123  
       2022-07-11 17:14:11 +08:00
    @ligiggy 缓存比直接写估计快 50-60 倍左右吧. 不过具体还是要看 benchmark.
    MoYi123
        6
    MoYi123  
       2022-07-11 17:16:28 +08:00
    @ligiggy 我指的是 log4j2 里用的数据结构 disruptor 是我知道的最快的处理日志的方案.
    ligiggy
        7
    ligiggy  
    OP
       2022-07-11 17:25:14 +08:00
    @lonewolfakela 大概浏览了下 spdlog 的异步写 log ,看到了 std::vector<std::thread>,感觉不会很快。主要是我没有实现方案,有的话,可以自己实现一个功能简单一点的。
    ceflib
        8
    ceflib  
       2022-07-11 17:27:57 +08:00
    log4cpp? 可以看看 glog
    ligiggy
        9
    ligiggy  
    OP
       2022-07-11 17:28:00 +08:00
    @MoYi123 好像开源库都是基于 std::thread 实现的,看来没法避免线程了,我去研究下吧
    novolunt
        10
    novolunt  
       2022-07-11 17:28:43 +08:00
    log ==> null
    ligiggy
        11
    ligiggy  
    OP
       2022-07-11 17:31:35 +08:00
    @novolunt 什么意思。。。。
    chengengshen
        12
    chengengshen  
       2022-07-11 17:33:21 +08:00 via Android
    google 的 log 库
    4771314
        13
    4771314  
       2022-07-11 17:33:42 +08:00
    @novolunt respect
    s127
        14
    s127  
       2022-07-11 18:21:32 +08:00
    zjwugiv2
        15
    zjwugiv2  
       2022-07-11 18:54:41 +08:00
    异步缓存,,
    yulon
        16
    yulon  
       2022-07-11 19:16:11 +08:00
    发到别的线程是内存操作,写到磁盘是 I/O 操作,内存操作肯定比 I/O 操作要快,你可能觉得整体的时间增加了,但对于产生 log 的那个线程,就不用负担 I/O 的时间了。
    bsg1992
        17
    bsg1992  
       2022-07-11 19:55:14 +08:00
    同步调用,异步落盘
    cloverstd
        18
    cloverstd  
       2022-07-11 20:30:31 +08:00
    往标准输出和磁盘写,都要异步非阻塞,不然会因为这两个 IO 会影响到你的程序的
    cxytz01
        19
    cxytz01  
       2022-07-11 20:55:21 +08:00   ❤️ 2
    对性能要求奇高,可以写入 mmap 里面,然后 log 进程搜集。腾讯是这么做的。
    BeautifulSoap
        20
    BeautifulSoap  
       2022-07-11 21:03:08 +08:00 via Android
    歪一下,大部分服务都跑云服务了,所以直接往标准输入输出里输出就行。云服务会自己收集输出的日志
    jones2000
        21
    jones2000  
       2022-07-11 22:23:18 +08:00
    开个线程单独写呗。
    foxtalk
        22
    foxtalk  
       2022-07-11 23:04:33 +08:00
    zlog 还不错,接口比较简单,效率不错
    SoarSoga
        23
    SoarSoga  
       2022-07-11 23:16:03 +08:00
    log 到控制台,在关键的地方才 log ,其他的直接 minidump 了
    Caturra
        24
    Caturra  
       2022-07-11 23:31:55 +08:00
    简单点做个多生产者-单消费者模型就可以了,写到缓冲的线程为当前正在操作的线程,缓冲写到文件的线程为单独的后台线程。按这种思路,一万次操作跟玩一样,自己写过测过总共也就 2ms 耗时
    不想写的话用 spdlog 之类的吧
    bthulu
        25
    bthulu  
       2022-07-12 08:37:01 +08:00
    直接写文件就行了, SSD 自身就有缓存, 不需要你来考虑缓存问题
    djoiwhud
        26
    djoiwhud  
       2022-07-12 09:28:34 +08:00 via Android
    纠正一下,文件写的执行是系统中断。也就是中断进程调度。并非写 10000 次,就有一万次中断执行。可能,我说的是可能,你写 10000 次,中断只执行了 100 次。

    这个问题在 mysql 上面是重点问题。实际上 mysql 默认的文件写操作,是非实时的。有一点延迟,碰到宕机,可能会出现 sql 执行成功但是文件没保存的情况。强如 mysql 这类,都只能做取舍。

    如果性能要求极高,可以考虑 mmap ,mysql 也有用 mmap 做文件写操作。但是实现方案真的繁杂。做稳定很难,而且极消耗内存。

    不过我觉得是不是应该想想为什么要单节点追求无敌的文件写的性能?是全球领先的需求场景么?方案调整一下说不定根本没有这个问题。
    djoiwhud
        27
    djoiwhud  
       2022-07-12 09:35:21 +08:00 via Android
    日志 io 问题,只在机械硬盘上面比较显著,现在的 ssd 都可以做到 gb 级别读写,比机械硬盘提升了几十倍。

    另外,ssd 是随机不敏感的存储,对数据库的优化特别重要。因为日志文件写是连续 io ,不是随机 io ,不像数据库那样特别需要 ssd 的随机不敏感特性。


    如果不考虑数据丢失的问题,写到内存再批量写文件,肯定是可以优化问题的。

    最后,我感觉你的忧虑应该是不存在的。
    ligiggy
        28
    ligiggy  
    OP
       2022-07-12 09:44:51 +08:00
    @djoiwhud 我的行业偏向嵌入式,没有 SSD ,硬盘性能很差。不过还是可以试试 缓存到内存里面,再开线程写入到文件的操作。
    Mogamigawa
        29
    Mogamigawa  
       2022-07-12 13:12:19 +08:00 via iPhone
    我才不管这些,日志狂魔就是我
    byaiu
        30
    byaiu  
       2022-07-12 14:10:59 +08:00
    fmtlog 延时还可以,要吞吐的话,可以用 nanolog 。但是 nanolog 查看的时候就不太方便了。
    JohnBull
        31
    JohnBull  
       2022-09-21 13:39:39 +08:00
    发 UDP 包,让别的机器去做性能最好,不接受反驳
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5419 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 08:04 · PVG 16:04 · LAX 00:04 · JFK 03:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.