【问题标题】:log module with pre-allocated memory具有预分配内存的日志模块
【发布时间】:2017-02-10 21:59:12
【问题描述】:

我正在编写一个日志记录机制,其余代码将使用该机制将字母数字数据记录到文件中。系统中的每个其他模块都将发送字母数字句子(最多几个单词)以连续写入文件。问题是,我只获得了少量的预分配内存,用于我的数据结构和这些日志消息的内存存储。如果流入量大于可写入磁盘的量,则日志消息将被丢弃。

我想在我的日志模块中在客户端和内存存储之间放置一个压缩机制,这样我就可以保存尽可能多的消息。

我目前的设计:

CLIENT ------> LOG MODULE ----> 压缩并存储在内存缓冲区1中

作家线程: 写入时,将缓冲区 1 与缓冲区 2 切换并将缓冲区 1 写入文件。在此期间,客户端将写入缓冲区 2。

外部脚本: 解压并显示日志信息

问题: 我可以使用什么好的字母数字压缩算法或可以用来捕获尽可能多的数据的好的数据结构(在上面的压缩阶段)?

如果可能的话,我想要一个不将压缩代码存储在中间数据结构中的算法 - 即,如果系统崩溃,我希望能够解压缩到目前为止已写入文件的任何内容。

目前的尝试: 为我们将使用的每个字符分配一个代码。似乎没有那么灵活。

大部分日志信息都是简单的文本句子

【问题讨论】:

    标签: logging data-structures compression buffer-overflow text-compression


    【解决方案1】:

    问题:我可以使用什么好的字母数字压缩算法或可以用来捕获尽可能多的数据的好的数据结构(在上面的压缩阶段)?

    一般来说,算法越慢,越占用内存,压缩率就越好。不同的编解码器做出不同的权衡,即使在某些编解码器中,您也可以调整不同的参数以产生不同的权衡。

    编解码器在处理不同数据时也往往表现得非常不同。有几个基准浮动,但这只会让您对性能有一个大致的了解;要真正选择最好的,您需要使用您的数据进行尝试并进行自己的测量。

    至于在进程崩溃时避免数据丢失,根据您当前的设计,您想要的是支持刷新的流编解码器。每次完成记录消息时,您都需要告诉编解码器刷新。用于此的 API 将取决于编解码器,但通常您最终会得到类似

    foo_compress(stream, output, input);
    foo_flush(stream);
    fwrite(stream->output, 1, stream->output_size, file);
    fflush(stream);
    

    一些库提供了用于读取/写入磁盘的 API(允许您跳过 fwrite/fflush)。我想到了 Squash、gzip 和 lzham,但可能还有其他的。不过,在大多数情况下,库只是压缩到缓冲区,而您负责将缓冲区写入文件。

    您的主要障碍是很多算法不支持刷新。在我的脑海中,gzip、lzham、brotli、bzip2、lzma、zstd,我认为 lz4f 支持冲洗。如果您进行大量刷新,bzip2 可能不会表现得很好,如果这是一个新系统,则可能没有太多理由使用 gzip 或 lzma(zstd 优于 gzip,并且 brotli 和 lzham 在几乎所有方面都优于 lzma方式)。

    也就是说,如果您只是想避免因您的代码崩溃而导致数据丢失(即,您希望在程序崩溃时保留数据,但您不太担心操作系统崩溃),您可能需要考虑将压缩和 I/O 代码拆分到单独的进程中。那时,您最终会得到类似于 syslog 的东西,或者更新的结构化日志 API,例如 journald、ASL,或者令人惊讶的令人不快的 Windows Event Log API。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      • 2015-01-13
      • 1970-01-01
      相关资源
      最近更新 更多