行业网站渠道选择和内容运营,网站续费问题,河南省建设厅网站师林峰,山东电力建设第一工程有限公司网站注册高性能日志
1 数据肯定是批量写入的 如果数据单笔写入会造成 磁盘寻址、频繁用户态/内核态的切换 #xff08;耗时#xff09; 2 fwrite/write 的区别
fwrite() 是C标准库中的函数#xff0c;而 write() 是系统调用接口。fwrite底层也是通过write来实现的。 二者均都有缓冲…高性能日志
1 数据肯定是批量写入的 如果数据单笔写入会造成 磁盘寻址、频繁用户态/内核态的切换 耗时 2 fwrite/write 的区别
fwrite() 是C标准库中的函数而 write() 是系统调用接口。fwrite底层也是通过write来实现的。 二者均都有缓冲区系统调用write的效率取决于你buf的大小和你要写入的总数量如果buf太小你进入内核空间的次数增大效率就低下。而fwrite会替你做缓存减少了实际出现的系统调用所以效率比较高。 假如write按照调用者要求写入十个字节的数据在内核缓冲区这中间会涉及到用户态与内核态之间的切换。由于使用了系统调用 而fwrite不一样fwrite每次都会先把数据写入一个应用进程缓冲区等到该缓冲区满了系统会调用write一次性把相应数据写进内核缓冲区中。同样减少了系统调用(即write调用)。 因此当 buf_size 设置的比较大的时候write 的性能比较优当 buf_size 设置的比较小的时候缓冲区会容易写满频繁使用系统调用OS会进行变态增加耗时 3 log4cpp
3.1 设计理念 输出格式 c风格 warn_log.warnStream() xxx 100;箭头运算符重载 C语言风格 warn_log.info(xxx %d, 100); 输出位置 打印到本地文件 log4cpp::FileAppender 输出到控制台 log4cpp::OstreamAppender
3.2 日志性能的问题
支持回滚的日志RollignFileAppender) 换了一个文件后会在程序里面记录每次写入的数据大小总计超过比如1M 再重写另外一个文件 此处log4cpp 错误的做法是每次写日志都会去调用 lseek 函数去获取文件大小耗时多这也是影响效率的关键
FileAppender 每次日志都调用write 异步日志的高性能支持批量写入日志达到一定量的时候才会调用write去写入文件
4 异步设计
4.1 多线程写入
多个线程将日志写入到缓存队列里需要加锁
4.2 日志什么时候写入磁盘
引入双缓存机制两个缓存队列。
日志写满一个缓存队列的话才去notify 日志读取线程将日志从缓存队列中取出然后写入然后下一条日志写到另外一个缓存队列中去。
而不是一个日志写到缓存队列中就通知线程进行日志读取。 实际做法原理使用多个大数组缓冲区作为日志缓冲区多个大数组缓冲区以双循环链表方式连接并使用两个指针p1和p2指向链表两个节点分别用以生成数据、与消费数据 生产者可以是多线程共同持有p1来生产数据消费者是一个后台线程持有p2去消费数据 4.3 如果缓存队列快满了还未满导致日志长时间未写入
日志写线程notify 唤醒 超时唤醒
4.4 程序崩溃了日志没有及时写入
使用gdb打开-g可以产生coredump通过coredump方式