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

sno*_*kin 2 perl datetime time-series

我想存储时间序列数据,例如超过6个月的CPU使用率(将每2分钟轮询CPU使用率,所以稍后我可以得到几个分辨率,例如 - 1周,1个月,甚至更高的分辨率,5分钟,等等).

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

  1. 6个月= 186天= 4,464小时= 267,840分钟.
  2. 将其分为2分钟:267,840/2 = 133,920.
  3. 133,920是环形缓冲区大小.
  4. ring-buffer中的每个元素都是一个hashref,其中key作为epoch(很容易转换为使用的日期时间localtime),值是该给定时间的CPU使用率.
  5. 我将序列化此环缓冲区(使用Storable我猜)

还有其他建议吗?谢谢,

Ilm*_*nen 10

我怀疑你是在思考这个问题.为什么不在每个时间间隔使用一行(例如)TAB分隔文件,每行包含一个时间戳和CPU使用情况?这样,您可以在收集文件时将新条目附加到文件中.

如果要自动丢弃超过6个月的数据,可以通过为每天(或周或月或其他)使用单独的文件并删除旧文件来执行此操作.这比每次读取和重写整个文件更有效.


在Perl中编写和解析这些文件是微不足道的.这是一些示例代码,我的头顶:

写作:

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";
Run Code Online (Sandbox Code Playgroud)

读:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

(注:我无法测试这两种示例程序的权利,所以他们可能包含错误或错别字使用您自己的风险!)