我在数据库系统中制作类似于commit log
的东西。该系统能够处理约20,000个事件/秒。每个事件占用约16个字节。粗略地说,系统将以~312.5 kB / sec的速度写入commit log
。每个commit log
文件最多包含500,000个事件。
我有一个问题:我应该为每个事件致电fopen - fwrite - fclose
,还是应该在创建新文件时调用fopen
一次,然后是一系列fwrite
,最后是{{ 1}}?
答案 0 :(得分:3)
在这种情况下,恢复打开/写入/关闭并完全摆脱C缓冲输出可能更好。日志文件通常由大量几乎相同(大小)写入组成,并且从C缓冲中获得的收益并不高。低级,无缓冲的I / O也可以减轻您调用fflush()的负担,并且可以保证将每个日志条目写为原子实体。
考虑到你提到的音量,你应该仍然不关闭,并在写入之间重新打开文件。
答案 1 :(得分:1)
fopen / fwrite / fclose 每秒20k次看起来相当昂贵。 考虑将 fflush 作为替代方案。
如果您希望使用它来记录数据库事务以进行可能的恢复,则可能需要重新考虑它。 f系列函数使用缓冲,因此在发生崩溃时,最终缓冲区可能已经或可能没有实际进入磁盘。
答案 2 :(得分:0)
您没有义务,不......实际上按照EvilTeach's answer的建议拨打fflush
会更好。
然而,更好的是,如果你可以避免调用fflush
这是理想的,因为C标准库可能(可能会)实现特定于系统的缓存,将较小的物理写入统一为更大的物理写入,使你的20k每秒写入更优化。
按照您的建议调用fopen
/ fwrite
/ fclose
,或者fflush
作为EvilTeach的建议会避免缓存,这可能会降低性能。