原文链接:https://blog.csdn.net/Tencent_Bugly/article/details/53157830
旧日志方案
传统的日志方案每有一句日志就加密写进文件。这样在使用过程中不仅存在大量的 GC,更致命的是因为有大量的 IO 需要写入,影响程序性能很容易导致程序卡顿。replase版本需要关闭,无法定位线上问题。
当写文件的时候,并不是把数据直接写入了磁盘,牵涉到两次数据拷贝:一次是用户空间内存拷贝到内核空间的缓存dirty page
中,一次是回写时内核空间的缓存到硬盘的拷贝。当发生回写时,也涉及到了内核空间和用户空间频繁切换。
系统一般会在下面几种情况把 dirty page 写入到磁盘:
- 定时回写,相关变量在/proc/sys/vm/dirty_writeback_centisecs和/proc/sys/vm/dirty_expire_centisecs中定义。
- 调用 write 的时候,发现 dirty page 占用内存超过系统内存一定比例,相关变量在/proc/sys/vm/dirty_background_ratio( 后台运行不阻塞 write)和/proc/sys/vm/dirty_ratio(阻塞 write)中定义。
- 内存不足。
需要的日志方案
- 流畅性:流畅性不仅包括了系统没有卡顿,还要尽量保证没有 CPU 峰值
- 完整性:任何时刻都有日志可查。不能因为程序被操作系统杀掉或者发生了未捕捉到的 Crash 就丢了部分日志
- 容错性:当日志文件中的部分日志数据损坏时应该尽量最小化对整个日志文件的影响
- 安全性:日志内容需要进行加密
xlog-V2.0 方案
使用流式压缩方式对单行日志进行压缩,压缩加密后写进作为 log 中间 buffer的 mmap 中,当 mmap 中的数据到达一定大小后再写进磁盘文件中
mmap
mmap 是使用逻辑内存对磁盘文件进行映射,中间只是进行映射没有任何拷贝操作,避免了写文件的数据拷贝。 操作内存就相当于在操作文件,避免了内核空间和用户空间的频繁切换。mmap几乎和直接写内存一样的性能。
mmap的回写时机:
- 内存不足
- 进程退出
- 调用 msync 或者 munmap
- 不设置 MAP_NOSYNC 情况下 30s-60s(仅限FreeBSD)
压缩
流式压缩是把时间分散在整个生命周期内,CPU 的曲线更平滑,相当于把压缩过程中使用的资源均分在整个 app 生命周期内。