Perl 存储时间序列数据,无需数据库

Perl 存储时间序列数据,无需数据库,perl,datetime,time-series,Perl,Datetime,Time Series,我想存储时间序列数据,例如6个月以上的CPU使用率(将每2分钟轮询一次CPU使用率,以便以后我可以获得多个分辨率,例如-1周、1个月或更高分辨率、5分钟等) 我正在使用Perl,我不想使用RRDtool或关系数据库,我正在考虑使用某种具有以下属性的循环缓冲区(环形缓冲区)来实现我自己的功能: 6个月=186天=4464小时=267840分钟 将其分为2分钟部分:267840/2=133920 133920是环缓冲区大小 环形缓冲区中的每个元素都是一个hashref,其键作为历元(使用localt

我想存储时间序列数据,例如6个月以上的CPU使用率(将每2分钟轮询一次CPU使用率,以便以后我可以获得多个分辨率,例如-1周、1个月或更高分辨率、5分钟等)

我正在使用Perl,我不想使用RRDtool或关系数据库,我正在考虑使用某种具有以下属性的循环缓冲区(环形缓冲区)来实现我自己的功能:

  • 6个月=186天=4464小时=267840分钟
  • 将其分为2分钟部分:267840/2=133920
  • 133920是环缓冲区大小
  • 环形缓冲区中的每个元素都是一个hashref,其键作为历元(使用
    localtime
    可以轻松转换为日期时间),该值是给定时间的CPU使用量
  • 我将序列化这个环形缓冲区(我想使用
    Storable
  • 还有其他建议吗?
    谢谢,

    我怀疑你想得太多了。为什么不直接使用一个平面(例如)制表符分隔的文件,每个时间间隔一行,每行包含一个时间戳和CPU使用情况?这样,您就可以在收集新条目时将其附加到文件中

    如果要自动丢弃超过6个月的数据,可以每天(或每周、每月或其他任何时间)使用单独的文件并删除旧文件。这比每次读取和重写整个文件更有效


    在Perl中编写和解析这样的文件非常简单。下面是我脑海中的一些示例代码:

    写作: 阅读:
    使用严格;
    使用警告;
    使用POSIXQW'strftime';
    my$dir='/path/to/log/directory';
    foreach my$filename(排序glob“$dir/cpu\u usage.*.log”){
    
    按照@Borodin的建议打开FH,,按照建议使用SQLite或
    DBM::Deep

    如果您想坚持使用Perl本身,请使用:

    一个独特的平面文件数据库模块,用纯perl编写……可以处理数百万个键和无限级别,而不会显著降低速度。它是用纯perl从头开始编写的——这不是基于C的DBM的包装器。与Unix、Mac OS X和Windows的开箱即用兼容性。 您提到了您对存储的需求,这可以通过@llmari提倡的简单文本文件来满足。(当然,使用CSV格式可以使文件在电子表格中轻松操作。)


    但是,如果您计划收集大量数据,并且希望最终能够以良好的性能查询数据,那么请使用为此目的设计的工具。

    我强烈建议您使用数据库。SQLite不需要服务器
    use strict;
    use warnings;
    use POSIX qw'strftime';
    
    my $dir = '/path/to/log/directory';
    
    my $now = time;
    my $date = strftime '%Y-%m-%d', gmtime $now;  # ISO 8601 datetime format
    my $time = strftime '%H:%M:%S', gmtime $now;
    
    my $data = get_cpu_usage_somehow();
    
    my $filename = "$dir/cpu_usage_$date.log";
    
    open FH, '>>', $filename
        or die "Failed to open $filename for append: $!\n";
    
    print FH "${date}T${time}\t$data\n";
    
    close FH or die "Error writing to $filename: $!\n";
    
    use strict;
    use warnings;
    use POSIX qw'strftime';
    
    my $dir = '/path/to/log/directory';
    
    foreach my $filename (sort glob "$dir/cpu_usage_*.log") {
        open FH, '<', $filename
            or die "Failed to open $filename for reading: $!\n";
        while (my $line = <FH>) {
            chomp $line;
            my ($timestamp, $data) = split /\t/, $line, 2;
            # do something with timestamp and data (or save for later processing)
        }
    }